Skip to main content

Rate limits

Every /v1 response carries: X-RateLimit-Limit and X-RateLimit-Remaining are sent as aliases. Over the limit, the API returns 429 with a Retry-After header (seconds). Wait that long before retrying. Limits apply at two levels, each over a 60-second window:
  • Per key: each API key has its own bucket.
  • Per account: all keys of one account share one budget. Minting more keys does not raise it. Over it, the 429 body says too many requests for this account.
The server’s configured default is 300 requests per window. Read RateLimit-Limit rather than hard-coding a number; the deployed value is what the header says. Quotes sent over the maker feed spend from the same budget as REST calls with that key. Key minting (POST /v1/keys) has its own limit: 20 requests per hour per client IP.

Idempotency

Send an Idempotency-Key header on any POST (and DELETE) to make retries safe.
Keys are scoped to your account, the HTTP method and the path. Any other status is stored and replayed, including a 400 and a 500: fix the request and use a new key. The settlement builders (POST /v1/swaps/{id}/legs/{leg}/fund, /claim, /refund) are the exception: they change nothing on the server, so they run on every call and none of their answers is stored, whatever the key. 409 is a state to wait out or act on (a leg already funded, a step that must come first, an address still missing), 429 a rate limit and 503 “unavailable right now” — none of them is stored, so the retry they invite can succeed.

Why 504 is special

504 means “we do not know what happened”:
  • On the settlement builders and POST /v1/swaps/{id}/address: a chain or explorer read of ours timed out. Nothing was changed. Retry.
  • On POST /v1/tx/broadcast: the node did not answer in time. The transaction may already be on chain. Look up the txid before sending it again. Resending the same signed bytes yields the same txid.
On the maker feed, the equivalent of the header is the idempotencyKey field of a quote frame.