Errors and recovery
Retain operation identity across failures.
Response envelopes
Success: {"data":{...},"meta":{"request_id":"req_...","api_version":"2026-10-01"}}. Errors: {"error":{"code":"validation_error","message":"Check the request fields.","request_id":"req_...","details":[{"field":"budget_cents","message":"..."}]}}. X-Request-Id is included in responses. Persistent/API responses are private and no-store.
JSON bodies have a 16384-byte limit and reject unsupported fields. Send Content-Type: application/json. All money is integer cents and currency is USD.
Decide what to do next
| Status / code | Action |
|---|---|
| 400 invalid_json or idempotency_key_required | Correct the request, then retry. |
| 401 unauthorized | Ask the owner for a valid, unrevoked agent key. |
| 403 owner_approval_required, owner_required, insufficient_scope | Request the appropriate owner action or scope. Never borrow owner credentials. |
| 404 not_found | Check the resource ID and workspace. |
| 409 idempotency_conflict | Read the existing request; use a new key only for an intentionally new operation. |
| 409 advertiser_setup_required / advertiser_consent_required | Owner/operator setup is incomplete. |
| 409 live_launch_disabled / billing_disabled | The deployment gate is closed; do not retry to bypass it. |
| 409 insufficient_funding / insufficient_allocation | Owner payment or operator allowance is required. |
| 409 pixel_not_ready / conversion_not_verified | Install and validate tracking before seeking launch. |
| 409 provider_operation_in_progress | Poll status and retry with backoff. |
| 409 provider_idempotency_expired | Stop automatic retries and ask the operator to reconcile the original operation. |
| 413 payload_too_large | Reduce JSON size; use direct file upload for images. |
| 422 validation_error / invalid_creative | Correct the indicated field. |
| 429 or provider_rate_limited | Respect Retry-After if present; otherwise back off. |
| 502 provider_outcome_unknown | A write may have happened. Keep the operation identity and reconcile. |
| 503 database_unavailable / provider_setup_required | Retry reads later; preserve write keys and request IDs. |
Bounded retries
Use exponential backoff with jitter, for example 2, 4, 8, 16, then 30 seconds. Bound the total attempts and escalate with request_id and campaign ID. Never loop approval or create requests with fresh keys after timeouts. An HTTP failure cannot prove that an upstream write did not occur.