Documentation Index
Fetch the complete documentation index at: https://docs.boltroute.ai/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Webhooks notify your system when an email verification job completes or when an entire task finishes. Configure a webhook_url when creating a batch task or uploading a file. Webhook URLs must be HTTPS.
You can receive two webhook types:
- Per-email webhook: sent for each email as it completes (or is skipped).
- Task completion webhook: sent once when the entire task finishes.
You can distinguish types by the data shape: per-email payloads include data.job, while task completion payloads include data.stats and data.jobs.
Delivery
Your endpoint receives an HTTP POST with JSON. Respond with a 2xx to acknowledge receipt. We retry on timeouts, connection errors, and 429/502/503/504 responses.
Each webhook includes:
Content-Type: application/json
User-Agent: EmailVerification/1.0
X-Webhook-ID: unique UUID per delivery
X-Webhook-Timestamp: Unix seconds when the request is sent
X-Webhook-Signature: HMAC-SHA256 of the raw request body (only when WEBHOOK_SECRET_KEY is configured). Format: sha256=<hex>
Signature verification
Compute the HMAC-SHA256 over the raw request body using your shared secret and compare to X-Webhook-Signature.
expected = "sha256=" + hex(hmac_sha256(secret, raw_body))
Payload format (HTTP request body)
All webhooks use the same outer envelope:
{
"event_type": "email_verification_completed",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"completed_at": "2025-01-01T12:05:00Z",
"data": {}
}
Field notes:
event_type is currently always email_verification_completed.
upload_id is optional and omitted in most current webhook payloads.
completed_at is when the webhook is sent (UTC).
data depends on webhook type (see below).
Per-email webhook payload
Sent once per email address. data contains the task context and a job object for the email.
{
"event_type": "email_verification_completed",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"completed_at": "2025-01-01T12:01:12Z",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "550e8400-e29b-41d4-a716-446655440999",
"source": "frontend",
"created_at": "2025-01-01T12:00:00Z",
"updated_at": "2025-01-01T12:01:12Z",
"job": {
"email_address": "user@example.com",
"status": "completed",
"created_at": "2025-01-01T12:00:10Z",
"updated_at": "2025-01-01T12:01:12Z",
"email": {
"id": "550e8400-e29b-41d4-a716-446655440222",
"status": "valid",
"address": "user@example.com",
"local": "user",
"domain": "example.com",
"verification_steps": [
{ "step": "syntax", "status": "completed" },
{ "step": "domain", "status": "completed" },
{ "step": "smtp", "status": "completed" }
]
}
}
}
}
Notes:
source and user_id are present when available; they may be omitted in some per-email sends.
job.email can be null or omitted if email details are unavailable.
job.skipped is included when an email is skipped.
verification_steps may be empty or omitted if no steps are recorded.
Task completion webhook payload
Sent once when all jobs for a task finish. data contains aggregated stats and the list of jobs.
{
"event_type": "email_verification_completed",
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"completed_at": "2025-01-01T12:05:00Z",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "550e8400-e29b-41d4-a716-446655440999",
"source": "frontend",
"created_at": "2025-01-01T12:00:00Z",
"updated_at": "2025-01-01T12:05:00Z",
"stats": {
"total": 2,
"pending": 0,
"processing": 0,
"completed": 2,
"failed": 0
},
"jobs": [
{
"email_address": "user@example.com",
"status": "completed",
"created_at": "2025-01-01T12:00:10Z",
"updated_at": "2025-01-01T12:01:12Z",
"email": {
"id": "550e8400-e29b-41d4-a716-446655440222",
"status": "valid",
"address": "user@example.com",
"local": "user",
"domain": "example.com",
"verification_steps": [
{ "step": "syntax", "status": "completed" },
{ "step": "domain", "status": "completed" },
{ "step": "smtp", "status": "completed" }
]
}
},
{
"email_address": "ops@example.com",
"status": "completed",
"created_at": "2025-01-01T12:00:10Z",
"updated_at": "2025-01-01T12:01:30Z",
"email": {
"id": "550e8400-e29b-41d4-a716-446655440223",
"status": "valid",
"address": "ops@example.com",
"local": "ops",
"domain": "example.com",
"verification_steps": [
{ "step": "syntax", "status": "completed" },
{ "step": "domain", "status": "completed" },
{ "step": "smtp", "status": "completed" }
]
}
}
]
}
}
Notes:
jobs can be large for big tasks; consider streaming/async processing on your side.
verification_steps may be empty or omitted if no steps are recorded.