Skip to content

Handling errors

Errors are RFC 9457 problem documents, served as application/problem+json:

json
{
  "type": "https://api.zefi.ai/problems/validation-failed",
  "title": "Validation failed",
  "status": 400,
  "code": "VALIDATION_FAILED",
  "detail": "One or more fields are invalid.",
  "traceId": "Cw7-AggGliAEJiQ="
}

Branch on code. Show detail to a human. Quote traceId if you contact us — it is how we find your request.

Two responses are not problem documents

Authentication is rejected at the gateway, before the service runs, so these two are plain JSON with no code:

ResponseBodyMeans
401{"message":"Unauthorized"}No Authorization header
403{"message":"Forbidden"}Key is malformed, unknown, revoked or expired

Treat any 403 whose body is not a problem document as an invalid credential. A 403 that is one is a permission problem — see below.

Codes

StatuscodeWhat to do
400VALIDATION_FAILEDFix the request. errors[] names the field.
403INSUFFICIENT_SCOPEThe key lacks survey_links:read or :write.
403WORKSPACE_MISMATCHThe key belongs to a different workspace than the path.
404CAMPAIGN_NOT_FOUNDWrong campaign id, or it belongs to another workspace.
404SURVEY_LINK_NOT_FOUNDAlready consumed, expired, revoked, or never existed.
413BATCH_TOO_LARGEMore than 50 entries. Chunk and retry.
429RATE_LIMIT_EXCEEDEDBack off — see below.

Rate limits

Rate limiting has its own page — see Rate limits for the budgets, the headers every response carries, and how to back off.

What to retry

Retry?
429Yes, after Retry-After.
5xxYes, with backoff.
400, 403, 404, 413No. Fix the request.
401No. The credential is missing or wrong.

Creating links is not idempotent: a retry that reaches us twice mints two sets of links. Prefer honouring Retry-After over aggressive retrying, and reconcile with reference if you are unsure whether a call landed.

Zefi API v1