Docs menu
Guides
API reference
Errors and HTTP status codes
Every error the API returns, by endpoint and HTTP status, listed from the OpenAPI file. Errors are JSON, { "error": "CODE", "message": "…" }: branch on error, never on message.
Last updated
Format
- The HTTP status says what kind of problem it is;
errorsays which one.messageis for people and can change. - A body that is not valid JSON gets
400 BAD_REQUEST; a body over 1 MB gets413 PAYLOAD_TOO_LARGE. 402 QUOTA_EXCEEDEDalso carriesused,limitandresetsAt.429carriesRetry-Afterin seconds. See Rate limits and quotas.
Errors by endpoint
| Endpoint | HTTP status | error | When |
|---|---|---|---|
POST /api/v1/verify | 400 | BAD_REQUEST, INVALID_IP | email missing, empty or not a string; an ip that is not an IP address; or a body that is not valid JSON. |
POST /api/v1/verify | 401 | UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUND | No X-Api-Key header, or an unknown, revoked or expired key. |
POST /api/v1/verify | 402 | QUOTA_EXCEEDED | The monthly quota is used up. Test requests of an account over its quota get this too (they are still not counted). |
POST /api/v1/verify | 403 | TENANT_SUSPENDED | Either a BLOCKED screening with X-Response-Mode: http-status (the body is the screening result), or TENANT_SUSPENDED. |
POST /api/v1/verify | 429 | RATE_LIMIT_EXCEEDED, TEST_LIMIT | RATE_LIMIT_EXCEEDED: the per-minute limit (your plan's; 300 for test keys). TEST_LIMIT: 10,000 test requests per account per UTC day; Retry-After is the time to the next UTC midnight. |
POST /api/v1/verify | 500 | VERIFICATION_ERROR, PERSISTENCE_FAILURE, AUTH_ERROR | The screening failed or could not be stored. Your integration decides whether to fail open or closed. |
POST /api/v1/verify | 503 | DATABASE_ERROR | The key could not be checked right now. Try again. |
POST /api/v1/check | 400 | BAD_REQUEST | No email, or a body that is not valid JSON. |
POST /api/v1/check | 401 | INVALID_SITE_KEY | No site key, or an unknown or revoked one. |
POST /api/v1/check | 402 | QUOTA_EXCEEDED | The monthly quota is used up (no token is issued). |
POST /api/v1/check | 403 | ORIGIN_NOT_ALLOWED | The Origin is missing or not one of the site key's domains. |
POST /api/v1/check | 429 | RATE_LIMIT_EXCEEDED, TEST_LIMIT | A per-minute limit, or (test site key) the daily test limit. |
POST /api/v1/check | 500 | VERIFICATION_ERROR, PERSISTENCE_FAILURE | The check failed. inlineshield.js then lets the form submit (fail open). |
POST /api/v1/siteverify | 400 | BAD_REQUEST | No email, or (without the rate-limit headers) a body that is not valid JSON. |
POST /api/v1/siteverify | 401 | UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUND | No X-Api-Key header, or an unknown, revoked or expired key. |
POST /api/v1/siteverify | 403 | TENANT_SUSPENDED | The account is suspended. |
POST /api/v1/siteverify | 429 | RATE_LIMIT_EXCEEDED | The per-minute limit of this key. |
POST /api/v1/siteverify | 500 | VERIFICATION_ERROR, AUTH_ERROR | Internal error. |
POST /api/v1/siteverify | 503 | DATABASE_ERROR | The key could not be checked right now. Try again. |
GET /api/v1/reviews/{reviewId} | 401 | UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUND | No X-Api-Key header, or an unknown, revoked or expired key. |
GET /api/v1/reviews/{reviewId} | 403 | TENANT_SUSPENDED | The account is suspended. |
GET /api/v1/reviews/{reviewId} | 404 | NOT_FOUND | No such review in this account. |
GET /api/v1/reviews/{reviewId} | 429 | RATE_LIMIT_EXCEEDED | More than 60 requests per minute with this key. |
GET /api/v1/reviews/{reviewId} | 500 | REVIEW_ERROR, AUTH_ERROR | Internal error. |
GET /api/v1/reviews/{reviewId} | 503 | DATABASE_ERROR | The key could not be checked right now. Try again. |
POST /api/v1/feedback | 400 | BAD_REQUEST | Not exactly one of requestId or token, a bad outcome, category or note, or (without the rate-limit headers) a body that is not valid JSON. |
POST /api/v1/feedback | 401 | UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY, ORGANIZATION_NOT_FOUND | No X-Api-Key header, or an unknown, revoked or expired key. |
POST /api/v1/feedback | 403 | TENANT_SUSPENDED | The account is suspended. |
POST /api/v1/feedback | 404 | NOT_FOUND | No such screening in this account. |
POST /api/v1/feedback | 422 | SCREENING_TOO_OLD | The screening is more than 180 days old. |
POST /api/v1/feedback | 429 | RATE_LIMIT_EXCEEDED | The per-minute limit of this key. |
POST /api/v1/feedback | 500 | FEEDBACK_ERROR, AUTH_ERROR | Internal error. |
POST /api/v1/feedback | 503 | DATABASE_ERROR | The key could not be checked right now. Try again. |
GET /api/v1/health | 503 | – | Degraded. |
siteverify: success false
/siteverify answers token problems with HTTP 200 and { "success": false, "error": "…" }, not with an error status:
NO_TOKEN: no token was sent.INVALID_TOKEN: not a token of this account.EXPIRED_TOKEN: older than 10 minutes.TOKEN_ALREADY_USED: redeemed before.EMAIL_MISMATCH: issued for another email.QUOTA_EXCEEDED: no token was sent and the account is over its quota.
What to do
| Status | Typical cause | Your code |
|---|---|---|
| 400 | A missing or malformed field. | Fix the request; do not retry it unchanged. |
| 401 | No key, or an unknown, revoked or expired key. | Fix the configuration. Treat the sign-up as unchecked. |
| 402 | The account is over its monthly quota. | Treat as unavailable until the next UTC month or an upgrade. |
| 403 | A suspended account, an Origin not on the site key, or a BLOCKED screening in http-status mode. | Read error. |
| 404, 422 | An unknown id, or a screening too old for feedback. | Do not retry. |
| 429 | A per-minute limit, or the daily test-mode cap. | Wait for Retry-After. |
| 500, 503 | A temporary failure. | Treat as unavailable; retry later if you queue checks. |