Rate Limits
Two limits apply to every request: an account-level limit that covers nearly every endpoint, and, on a few endpoints, a stricter per-endpoint limit. Whichever is lower is the one you will hit.Account-level limit
Counted per account in a fixed one-minute window. All API keys belonging to one account share a single budget — creating more keys does not raise your limit.
Unauthenticated budgets are counted separately for each group of endpoints — prices, invoice status,
address lookups, authentication, and everything else — so polling prices never eats into your budget
for anything else.
These are defaults. If your integration needs a higher ceiling, we raise it for your account: ask us
on Telegram.
The window is fixed, not sliding: the counter resets at the start of each minute. Do not build a
burst around that boundary. Two separate mechanisms make it a bad bet. An edge limit of about 50
requests per second per IP address sits in front of the API and answers
503 with an HTML body, not
a JSON error. And an account that stays over its limit for three minutes in a row has its limit
halved for the next ten minutes; three more such minutes block it entirely for thirty, with
Retry-After: 1800. Accounts on the 1000/minute tier are exempt from that escalation.Endpoints with a stricter limit of their own
Note that
POST /api/v1/invoices is counted per IP address, not per account: if several of your
clients send requests from the same egress IP, they share one budget of 10 per minute.
The purchase endpoints — POST /api/v1/energy/buy, POST /api/v1/energy/activate,
POST /api/v1/bandwidth/buy and POST /api/v1/bandwidth/rentals — carry an older budget of 1000
requests per minute counted per IP address (the two bandwidth endpoints share one budget). For a
single account it is never the binding limit, but clients behind one egress IP share it with each
other.
The webhook management endpoints (/api/v1/webhooks/...) are not covered by the account-level limit.
Every other documented endpoint has no limit of its own — the account-level limit is the only one that
applies to it.
What a 429 looks like
The body depends on which limit you hit. Three shapes exist, so parse defensively rather than assuming one of them. Account-level limit. The response carries aRetry-After header with the number of seconds to wait:
POST /api/v1/invoices. There is no Retry-After header; the
window is one minute:
POST /api/v1/account/withdrawal. A plain-text detail with the seconds remaining, and no error code:
A 429 that retrying will not fix
POST /api/v1/invoices also answers 429 when you are already holding too many unpaid invoices — at
most 3 per IP address and at most 5 per account. The per-IP cap applies to signed-in requests
too, so it is usually the one you reach first:
429 — for example
{"detail":"Energy price unavailable"}. Read the message before deciding how to react.
Retrying
- If the response carries a
Retry-Afterheader, wait exactly that many seconds. - Otherwise back off exponentially, starting at one second.
- Never retry immediately.
- Read the body before retrying:
Too many pending invoicesneeds a different action, not a longer wait.