Endpoints Reference

The complete parameter and error reference for every endpoint.

POST /v1/email/check

Checks a single address and returns a result synchronously.

ParameterTypeDefaultNotes
emailstringrequiredMax 320 characters
mode"fast" | "standard" | "full""standard"See Choosing a Mode for tradeoffs
context"generic" | "signup" | "b2b_lead" | "crm" | "marketplace" | "payment""generic"Changes signal weighting — see Email Risk Scoring Explained

Returns 200 with the full result object on success — see Getting Started for the complete response shape.

POST /v1/email/bulk

Submits a batch of addresses for asynchronous processing. Returns immediately with a job reference.

ParameterTypeDefaultNotes
emailsstring[]requiredNon-empty array
mode"fast" | "standard" | "full""standard"Applies to every address in the batch
contextsame enum as above"generic"Applies to every address in the batch
response.json (202 Accepted)
{ "job_id": "job_9f3a2e", "status": "queued", "total": 3 }

GET /v1/email/bulk

Lists your bulk jobs, most recent first - the same view the dashboard's Bulk check page uses to show past and in-progress jobs without needing a job ID up front.

ParameterTypeDefaultNotes
pageinteger120 jobs per page
response.json
{
  "page": 1,
  "page_size": 20,
  "total": 3,
  "data": [
    { "job_id": "job_9f3a2e", "status": "completed", "total": 3, "processed": 3, "allow": 2, "review": 1, "block": 0, "errors": 0, "mode": "standard", "context": "generic", "created_at": "2026-08-18T09:00:00.000Z", "completed_at": "2026-08-18T09:00:12.000Z" }
  ]
}

GET /v1/email/bulk/:jobId

response.json
{
  "job_id": "job_9f3a2e",
  "status": "queued" | "processing" | "completed" | "failed",
  "total": 3,
  "processed": 3,
  "allow": 2,
  "review": 1,
  "block": 0,
  "errors": 0,
  "mode": "standard",
  "context": "generic",
  "created_at": "2026-08-18T09:00:00.000Z",
  "completed_at": "2026-08-18T09:00:12.000Z"
}

GET /v1/email/bulk/:jobId/results?page=1

response.json
{
  "job_id": "job_9f3a2e",
  "page": 1,
  "page_size": 50,
  "total": 3,
  "data": [
    { "row": 1, "email": "a@example.com", "status": "completed", "decision": "allow", "risk_score": 5, "risk_level": "low", "error": null }
  ]
}

Webhook delivery

Register a webhook endpoint from the dashboard (see Authentication — webhook management is session-authenticated, not API-key-authenticated). Once registered, a bulk job firing bulk.completed or bulk.failed will POST to your endpoint:

webhook-payload.json
{ "event": "bulk.completed", "job_id": "job_9f3a2e", "total": 3, "allow": 2, "review": 1, "block": 0 }

Every delivery includes an X-Webhook-Event header (the event name) and an X-Webhook-Signature header — an HMAC-SHA256 hex digest of the raw request body, signed with the secret shown once when you created the endpoint. See the webhook security section of Error Handling & Webhooks for how to verify it.

Error codes

Every error follows the same shape: { "error": { "code", "message", "request_id" } }.

CodeHTTP statusMeaning
INVALID_REQUEST400Malformed body — missing/invalid email, empty emails array, etc.
INVALID_EMAIL400The email field failed validation
AUTHENTICATION_REQUIRED401Missing or malformed Authorization header
INVALID_API_KEY401Key not recognized
API_KEY_REVOKED401Key was valid but has since been revoked
TEST_KEY_EMAIL_RESTRICTED403A test-mode key was used to check an address other than the account's own signup email
FORBIDDEN403Authenticated, but not permitted to perform this action
NOT_FOUND404Resource (e.g. a bulk job) doesn't exist or doesn't belong to you
CONFLICT409State conflict on the requested resource
RATE_LIMIT_EXCEEDED429Too many requests per second for your plan — back off and retry
QUOTA_EXCEEDED402Monthly check quota exhausted
BULK_LIMIT_EXCEEDED400Batch exceeds your plan's bulk allowance, or bulk isn't enabled on your plan
SERVICE_UNAVAILABLE503A required dependency isn't available
INTERNAL_ERROR500Unexpected server error — safe to retry with backoff

We use Google Analytics to understand site traffic, and only load it if you accept — nothing runs before you choose. Signing in still stores a strictly necessary session token regardless. See the Privacy Policy for details.