Skip to main content
Every failure returns the same envelope — never alongside data:
code and message are always present; details only appears on field-level failures.
Branch on error.code, never on error.message. Messages are written for humans and change without notice; codes are a contract.

Codes

Field codes

Inside details[].code on a VALIDATION_ERROR:

Partial success on bulk writes

Bulk endpoints are not all-or-nothing in the same way. create_brand_prompts writes the valid rows and reports the rest in the response body — a 201 can still contain failures:
Check prompts_failed and errors_and_warnings even on a success status. The one exception is usage limits: if the batch as a whole would exceed your subscription, the entire mutation is rolled back and you get a 422 USAGE_LIMIT_REACHED instead — no rows are written.

Handling errors

  • 401 — stop retrying. The key is bad, revoked, or expired; retrying won’t fix it.
  • 403 — you’re calling an endpoint outside the public surface, or a brand your org doesn’t own. Also not retryable.
  • 404 — treat as terminal. A soft-deleted brand starts returning it mid-integration, so handle it as “gone”, not as a transient failure.
  • 422 — a bug in your payload. Log details and fix the caller.
  • 429 — back off exponentially and retry. Don’t rotate keys to get around it; the per-IP backstop catches that too.
  • 500 — retry with backoff, cap the attempts, and alert if it sticks.