The response envelope
Every response has the same outer shape, success or failure, so you never have to guess whether a200 actually worked.
success first, then read data. The error string is written for a person. Show it or log it, but don’t parse it, because we reword messages when a clearer one comes along. Branch on the HTTP status instead.
A few errors also carry a machine-readable code. For example, a closed account answers with "code": "ACCOUNT_BANNED".
Two endpoints don’t return JSON when they succeed: invoice PDFs and ticket attachment downloads send the file itself. Their errors still use the envelope.
Status codes
The
404 behaviour is worth remembering. If you ask about someone else’s service, you get “not found”, not “forbidden”. Otherwise the API would let anyone check which service IDs exist.
Rate limits
Most token endpoints have no per-request limit today. A handful do, and they answer429 once you go over:
429, wait out the rest of the minute and try again. Don’t hammer the endpoint.
No published limit doesn’t mean unlimited. If you’re planning something high-volume, like polling thousands of servers every few seconds, talk to us first rather than finding the edge by hitting it. List endpoints read from our database, not the hypervisor, so one paged GET /v1/cloud is far cheaper than a status call per machine.
Failed authentication and IP blocks
Repeated bad credentials from one IP get that IP blocked automatically. Ten failures inside 15 minutes trigger the first block, and each repeat lasts longer:
While blocked, every request from that IP gets a
403 with a Retry-After header, in seconds:
Handling errors well
A good client:- Checks
success, then branches on the status code. - Treats
401as “stop and fix the credential”, never “retry”. - Retries
429,502and503with backoff, and caps the number of attempts. - Doesn’t retry
409blindly. Re-read the resource’s state first, because something else has changed it. - Logs the
errorstring, since it’s the fastest way for us to help when you open a ticket.