Skip to content

Error codes

A failed request answers { success: false, error: { code, message, request_id } } with one of the codes below, and never costs a credit. The request_id is also sent as the X-Request-Id header; quote it when writing to support.

code http when
UNAUTHENTICATED401The Authorization header is missing, malformed, or carries a key that does not exist or was revoked.
VALIDATION_FAILED422One or more fields are missing, malformed, or over a limit. error.errors lists each field with its messages.
RATE_LIMITED429The API allows 5 requests per second per key; each browser endpoint allows 20 lookups a minute per visitor, and the published sandbox key allows 30 a minute per address.
NOT_FOUND404The bulk job, monitor or suppression entry named in the path does not exist, or belongs to another account. Nothing is charged.
INSUFFICIENT_CREDITS402The account has no credits left, so the lookup did not run. Free credits renew at the start of each month; packs can be bought from the Billing page.
RESULTS_NOT_READY409Results were requested for a bulk job that is still queued or running.
JOB_ALREADY_FINISHED409A cancel was requested for a bulk job that already reached a terminal status: completed, cancelled, or failed.
JOB_CANCELLED409Results were requested for a job that was cancelled before any address was processed, so there is no results file.
JOB_FAILED409Results were requested for a job that failed before a single row was written, so there is no results file.
JOB_NOT_RESUMABLE409A resume was asked for a run that did not stop because the credit balance ran out, that has not settled yet, or that is already going again.
JOB_INPUT_EXPIRED409A resume was asked for a run whose uploaded list has passed out of the retention window, so there is nothing left to re-run.
IP_LIST_LIMIT_REACHED409A new allow or deny list was asked for when the account already holds the maximum number of lists.
JOB_NOT_FINISHED409A redelivery of the completion webhook was asked for a run that is still queued or running.
WEBHOOK_NOT_CONFIGURED409A redelivery of the completion webhook was asked for a run created without a `webhook_url`, so there is no address to post to and no secret to sign with.
INVALID_PUBLISHABLE_KEY401The pk_ key sent to the browser endpoint is unknown.
ORIGIN_NOT_ALLOWED403The Origin header of the browser request does not match any domain the publishable key allows, or the header is missing.
KEY_IP_NOT_ALLOWED403The secret key was created with an allowlist of source addresses or CIDR ranges, and this request came from elsewhere.
KEY_ACCOUNT_MISMATCH403A secret key belongs to the account it was created on. The person who holds this one is no longer a member of that account, so the key no longer authorises anything.
KEY_SCOPE_DENIED403The secret key was created with a limited set of scopes (email, ip, phone, address, entity, consistency, account), and the endpoint belongs to a family it does not cover.
KEY_SPEND_CAP_REACHED429The key, publishable or secret, was created with a daily credit cap and has reached it today. The counter resets each day.
SANDBOX_ENDPOINT_NOT_ALLOWED403The request carried the published sandbox key, which answers a handful of read-only lookups and nothing else.
SANDBOX_VALUE_NOT_ALLOWED403The endpoint is one the sandbox answers, but only for the sample values the documentation prints, and the request asked about something else.
SANDBOX_UNAVAILABLE503The request carried the published sandbox key on a deployment where the sandbox is turned off.
TURNSTILE_FAILED403The key was created with a Turnstile site key and secret, and the lookup carried no token or one Cloudflare did not confirm.
UNKNOWN_FEEDBACK_PROVIDER404The URL POST /api/v1/email/feedback/{provider}/{key} accepts postmark, ses, mailgun and sendgrid only.
INVALID_FEEDBACK_KEY401The fb_ key in a bounce webhook URL does not exist or was rotated.
EMAIL_NOT_VERIFIED403The key is valid, but its account has not opened the verification link yet, so the API and the MCP server refuse to spend for it.
IDEMPOTENCY_KEY_REUSED409POST /api/v1/email/bulk saw an Idempotency-Key it already knows, but the addresses or webhook URL differ from the request that first used it.
ADDRESS_LIST_UNAVAILABLE501GET /api/v1/address/postcode/{postcode} answers from a licensed address-list partner or from an open register's street listing, and neither covers the country asked about, or the installed listing cannot speak for that postcode. Nothing is charged.
ADDRESS_STREETS_NOT_FOUND404GET /api/v1/address/streets found nothing to report: no address register Spaw syncs carries a street listing for the country, the registers list no street at that postcode, or the listing does not cover it. Nothing is charged.
ASN_NOT_FOUND404GET /api/v1/ip/asn/{asn} found nothing to report: the ASN database assigns no prefix to that number. Nothing is charged.
ASN_INDEX_UNAVAILABLE501GET /api/v1/ip/asn/{asn} needs the index `lookup:index-asns` builds from the ASN database, and it is not installed. Nothing is charged.
PHONE_BLOCK_NOT_FOUND404GET /api/v1/phone/block/{country}/{prefix} found nothing to report: either no numbering plan Spaw syncs covers the country, or no block in it starts with the prefix. Nothing is charged.
METHOD_NOT_ALLOWED405The path exists but not for this verb — a GET where the endpoint takes POST, most often. The response carries an Allow header naming the methods it does take. Nothing is charged.
SERVER_ERROR500Something went wrong on this side. The failure is logged against the request_id in the response, which is the fastest way for support to find it.

Validation failures carry an extra error.errors object keyed by field. Rate-limit answers carry a Retry-After header. Each code has a Markdown twin at its URL with a .md suffix.