Skip to content

Error Format

Every error response replaces the success envelope’s data field with a structured error object, designed to be actionable by both humans and automated/agent clients — not just an HTTP status code:

{
"success": false,
"error": {
"code": "survey_not_found",
"message": "No survey with id mlb8i9f2UZLhXwJA.",
"suggestion": "Call listSurveys to discover valid ids.",
"retryable": false,
"details": { "survey_id": "mlb8i9f2UZLhXwJA" }
},
"meta": { "timestamp": "2026-07-23T12:00:00Z", "requestId": "..." }
}
Field Meaning
code A stable, snake_case domain code. Branch your error handling on this, not on the HTTP status or the human-readable message.
message Human-readable description. Safe to log or display, not guaranteed to stay word-for-word identical across API versions.
suggestion An imperative hint at how to recover — often naming the exact endpoint to call next.
retryable Whether re-sending the same request might succeed without any change on your end (a transient condition), as opposed to a client error that will keep failing until you change the request.
details Structured, code-specific context (e.g. the offending field, or the resource ID that wasn’t found).
Code HTTP status Retryable
validation_failed 400 No
insufficient_scope 403 No
survey_not_found 404 No
survey_not_published 409 No
confirmation_required 409 No
dependency_not_ready 409 Yes — poll and retry, typically for async operations like exports
rate_limited 429 Yes — back off and retry (see Rate Limits)

This isn’t the full list — new domain codes are added as the API surface grows. Always check retryable rather than assuming based on the code name alone.

For any non-GET request that includes an Idempotency-Key header, retrying the exact same request (same key, same body) is always safe — the API returns the original result rather than re-applying the write. Without that header, only retry requests where error.retryable is true.

A small number of high-stakes, hard-to-reverse actions (for example, anonymizing a contact, or exporting a dataset containing full PII) require an extra confirmation step rather than executing immediately:

  1. Call the action normally. Instead of executing, the API responds with 409 confirmation_required and a one-time confirmation_token in error.details, describing the action’s impact.
  2. Re-send the identical request with an X-Confirmation-Token header carrying that token. The action now executes.

The token is single-use, expires after a few minutes, and is bound to the exact request payload — it can’t be reused for a different action or a modified body.