Errors and limits

What a refusal carries

Every refusal is a signed JSON problem:

{
  "type": "https://developers.anis.ly/errors/price-changed",
  "title": "Price changed",
  "status": 409,
  "code": "price_changed",
  "requestId": "01J9R2K8T4V6XQ0M3B7C5D9E1F"
}
  • Branch on code. Never on title or detail: they are written for people, follow the language you ask for (Accept-Language: ar or en) and can change wording.
  • type is the address of the code’s page — every code has one in Error codes, saying what it means, whether an order was bought and what to do.
  • requestId is what to quote when you ask Anis about a call. It is also in the X-Request-Id header of every answer.

Two things a refusal may carry

  • Retry-After — when Anis knows how long to wait, in seconds. Honour it.
  • Idempotency-Replayed: true — on an order: the recorded answer of an order that is already closed.

Refusals that hide which rule failed

Some refusals give the same answer for different causes, on purpose, so that a refusal never tells anyone which thing to work around:

Code Covers
invalid_credentials an unknown key, a key that is not active, a revoked key, a wrong signature, an expired signature, a body that does not match its digest
insufficient_scope a missing permission, or a call from outside your allowed networks
wallet_not_granted, resource_not_found something that does not exist, or that is not yours
validation_failed any broken rule — the field is never named

Limits

Anis staff can set limits on your application, for the whole application or per wallet. Each counts one kind of call in a time window:

Limit Counts
All requests every signed call
Orders placing an order (and resuming one)
Reveals both reveals

When a limit is reached the call is refused as rate_limited, with Retry-After when the reset time is known. Anis also protects itself with limits that give no reset time — back off exponentially then. A refused call records nothing: once the wait is over, send it again (an order keeps its operation id).

The Routes and permissions page shows which limits each call counts toward.

Spending limits are different

owner_limit_exceeded and daily_limit_exceeded are limits on what the Anis business account may spend, not on how often you call. Waiting does not reset them — do not retry in a loop.