General Liquidity
Reference

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.

A problem
{
  "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.pending needs a person; memory.pending is its memory equivalent.
400
Did not validate: intent.unparseable, intent.malformed, state.malformed.
401
principal.unauthorized for the agent credential, operator.unauthorized for the operator one.
403
Refused. intent.denied, or memory.denied and memory.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, or operator.refused.
429
rate_limited. Back off and retry with the same key.
500 · 503
internal, enforcement.mismatch, and rail.unavailable when a rail is down.