Errors share one shape. retry.strategy tells an agent what to do next without parsing the message.
{
"requestId": "req_…",
"error": {
"code": "OFFER_NOT_FOUND",
"message": "Offer not found.",
"details": [],
"retryable": false,
"retry": { "strategy": "none" }
}
}| Strategy | Meaning | Example codes |
|---|---|---|
revise-request | Change the inputs and try again. | INVALID_COMMITMENT, QTY_BELOW_MIN, OUT_OF_POLICY, IDEMPOTENCY_REQUIRED, PAYMENT_MANDATE_REQUIRED, SELLER_ID_REQUIRED |
poll-approval | A person must approve; poll the quote. | QUOTE_APPROVAL_REQUIRED |
backoff | Wait (honor Retry-After) and retry. | VELOCITY_LIMIT, QUERY_QUOTA_EXCEEDED, SETTLEMENT_NOT_CONFIGURED |
none | Do not retry this request. | AUTH_REQUIRED, INVALID_CREDENTIAL, INSUFFICIENT_SCOPE, TENANT_DENIED, OFFER_NOT_FOUND, QUOTE_ALREADY_EXECUTED |
Where each error comes from
A keyed quote request runs these checks in order and stops at the first one that fails. A request that passes all eight gets 201: indicative within policy, or approval-required when a person must approve first. The buyer sends that quote to the seller with POST /v1/quote-requests/{id}/submit; executing it before a person approves returns QUOTE_APPROVAL_REQUIRED, strategy poll-approval. Submit returns 409 QUOTE_NOT_SUBMITTABLE for a quote that needs no approval or is finished, and QUOTE_EXPIRED or QUOTE_STALE when it must be requested again.
| Step | Check | If it fails | retry.strategy |
|---|---|---|---|
| 1 | A bearer key is sent | 401 AUTH_REQUIRED | none |
| 2 | The key is valid and not revoked | 401 INVALID_CREDENTIAL | none |
| 3 | The key has not expired | 401 CREDENTIAL_EXPIRED | none |
| 4 | The seller has not paused agent access | 503 AGENT_ACCESS_PAUSED | none |
| 5 | The key has the scope for the call (quote:request or quote:execute) | 403 INSUFFICIENT_SCOPE | none |
| 6 | The key belongs to this seller | 403 TENANT_DENIED | none |
| 7 | The seller’s policy accepts the priced quote | 422 POLICY_DENIED | revise-request |
| 8 | The key is inside its limits, including its daily quoted value | 429 VELOCITY_LIMIT | backoff |
- Rate limits: requests are rate limited per caller; a
429carriesRetry-AfterandX-RateLimit-Limit. A seller’s own keys get higher limits than anonymous traffic. - Paused sellers: a seller can pause all agent traffic; calls then return
503 AGENT_ACCESS_PAUSED. - Turned-off protocols: a seller can turn off UCP, ACP, A2A or UAP. Those endpoints return
403 PROTOCOL_DISABLEDwith an MCP link indetails; MCP and REST always stay on. - Signed requests (optional): sign quote and access requests with Web Bot Auth: HTTP Message Signatures with tag
web-bot-auth, covering@authorityand aSignature-Agentthat points at your key directory. Atlas records whether the signature verified and shows the seller who signed. A missing or bad signature never blocks a call. - Wrong seller: a key used against another seller’s keyed tools returns
403 TENANT_DENIED; on public tools it is treated as anonymous.