Errors
Problem documents, and the one distinction that matters: what to retry and what not to.
The shape
Failures come back as problem documents with application/problem+json. Alongside the standard members there are three you should actually branch on: code is the stable identifier, action tells you what to do, and retryable says whether doing it again could ever help.
action is one of retry-as-is, retry-after-renegotiation, escalate-to-human or never-retry. Branch on that rather than on the status code, and your handling stays correct as codes are added.
{
"type": "https://docs.generalliquidity.com/problems/intent.denied",
"title": "Refused by a limit you set",
"status": 403,
"detail": "Only $50 of this budget can go to payments that cannot be
reversed. It is already used.",
"code": "intent.denied",
"action": "escalate-to-human",
"retryable": false,
"reasons": ["irreversible outlay bound reached"]
}What to retry
- Retry
- Timeouts, 429s and 5xx. Back off, and reuse the instruction's own idempotency key so a retry cannot become a second payment. A Retry-After header is present whenever the action is retry-as-is.
- Do not retry
- A refusal. It is deterministic: the same instruction against the same limits gives the same answer, so a retry loop just burns tokens and fills your record with noise.
- Neither
- A payment waiting on a person. Nothing is wrong. Park the work and wait for the approval.
Authentication and shape
- 200
- Settled. The only status that carries a receipt.
- 202
- Accepted, not settled.
approval.pendingneeds a person;memory.pendingis its memory equivalent. - 400
- Did not validate:
intent.unparseable,intent.malformed,state.malformed. - 401
principal.unauthorizedfor the agent credential,operator.unauthorizedfor the operator one.- 403
- Refused.
intent.denied, ormemory.deniedandmemory.forbidden. - 404
- No such payment, or not one this credential can see.
- 405 · 413 · 415
- Wrong method, body too large, wrong content type.
- 409
state.stale, oroperator.refused.- 429
rate_limited. Back off and retry with the same key.- 500 · 503
internal,enforcement.mismatch, andrail.unavailablewhen a rail is down.