Skip to main content

Error handling

Every non-2xx response uses the same envelope. Key on code (stable); never parse message (human-readable, may change).

{
"error": "Bad Request",
"code": "validation_failed",
"message": "Request body failed validation",
"details": {
"formErrors": [],
"fieldErrors": { "user_email": ["Invalid email"] }
}
}

The fields: error is the HTTP-status label (e.g. "Bad Request") and is informational only; code is the stable machine-readable value to branch on; message is human-readable and may change. details appears only on validation_failed and contains a flattened list of field errors.

Codes by category

HTTPcodeWhen
401auth_missing, auth_invalid_format, auth_unknown_partner, auth_revoked, auth_bad_secretAuthentication (see Authentication).
403auth_partner_not_approvedYour account is still pending approval; no endpoint works yet.
400validation_failedBody failed schema validation (see details).
400invalid_jsonBody was not valid JSON.
400body_requiredNo JSON body (missing, or Content-Type not application/json).
400document_path_invalidA document_refs path is not under the entity+claim prefix.
400document_not_uploadedA referenced file does not exist in storage yet.
403entity_not_ownedYou have no connection to that entity.
403partner_disconnectedThe entity disconnected you (writes blocked; listing still works).
404entity_not_foundNo such entity.
409claim_conflictInternal claim-id collision (rare). Retry the identical request.
409connect_token_already_redeemed, entity_already_linkedConnect-flow conflicts (surfaced during user approval).
400connect_token_invalid, connect_token_expiredConnect-flow token problems (surfaced during user approval).
422onboarding_unavailableOnboarding cannot complete automatically. Use POST /connect-requests instead.
429rate_limitedRate limit exceeded (see Rate limits).
500internal_errorUnexpected server error.
503service_unavailableA dependency is briefly unavailable. Retry after Retry-After.
503document_verification_failedStorage check on an uploaded document failed transiently. Retry.

Retry guidance

  • Retry on 429 (after Retry-After), 500 (internal_error), 503 (service_unavailable / document_verification_failed, after Retry-After where given), and the internal-id 409 (claim_conflict). Use exponential backoff with jitter.
  • Always reuse the same partner_user_id / partner_claim_id on retries so the idempotency guarantees apply and you don't double-create.
  • Do not blindly retry 400 / 401 / 403 / 404 / 422. They are deterministic and need a corrected request or a different flow (e.g. onboarding_unavailablePOST /connect-requests).