Getting started
Errors and limits
Every error has a kind for your code to check and a message to show people. The message says what to do next.
The error object
{
"version": 1,
"error": {
"kind": "conflict",
"message": "This request ID was already used for a different request. Use a new --request-id.",
"request_id": "create-my-site",
"operation_id": "8540e6f2-9f39-4d39-89b5-eeac80d0ac97"
}
}kindstring- What went wrong, from the list below. Your code should check this.
messagestring- A sentence to show people, with the specific problem and the next step. Its wording can change, so don't parse it.
request_idstring- The change's
Idempotency-Key, when it had one. operation_idstring- The operation to read, when there is one.
retry_afterinteger- For
rate_limited, the seconds to wait. It's also sent as theRetry-Afterheader. urlstring- A Stripe page where you can pay, for some
payment_requirederrors. actionobject- Present when the message suggests a command.
commandis its name (pool start), andlineis the full command from the message (pool start web), so an app can show its own button for it.
Kinds
| Kind | HTTP | Means | Do |
|---|---|---|---|
invalid | 400 | A missing or malformed field, value or size. | Fix the request. |
denied | 401, 403 | The credential is missing, expired or not allowed this command. | Check the key and its commands. |
not_found | 404 | Nothing by that name or ID that you can reach. | Check the name. Another account's resources are not_found too. A one-time link that was already used or has expired returns not_found with HTTP 410. |
conflict | 409 | It clashes with the current state, such as a taken name, a stopped Computer or a reused Idempotency-Key. | Read the message, then change the state or the request. |
over_capacity | 409 | A limit was reached, such as not enough capacity on the server, too many Computers in the pool, or too many keys. | Buy capacity, or stop or shrink a pool. |
access_list_full | 409 | A share or key would grow a server's access list past what it can hold. | Share with a team or the organization instead of person by person. |
payment_required | 402 | Payment is needed first. The balance can't cover the first hour of capacity, a pool's capacity has lapsed or its storage is unpaid, or a card was declined. | Add money, or open the returned url. |
rate_limited | 429 | You sent commands faster than your rate limit. Nothing changed. | Wait retry_after seconds. |
busy | 429 | Too many of your requests at once, or the server is at capacity. Nothing changed. | Retry shortly. |
unknown | 503 | A change's outcome couldn't be confirmed, so it may have happened. Or a read failed, and its message says nothing changed. | For a change, find out what happened: read the operation, or send it again with the same Idempotency-Key. Retry a read. |
unavailable | 503 | Refused before anything changed, for a reason that may pass. For example, the server isn't accepting changes, the pool is moving between servers, a Computer's console or mail couldn't be reached, or a provider isn't set up. | Retry later. The message says what to wait for. |
Rate limits
Limits are per person and shared by the API, the dashboard and SSH, so one runaway script doesn't slow the rest of your team.
| What | Rate | Burst |
|---|---|---|
| All commands | 20 a second | 300 |
| Changes (create, start, snapshots, domains, ports, pools, billing…) | 1 a second | 60 |
Revoking a key or sign-in (api-key remove, ssh-key remove, sign-in end-all), counted for each key and sign-in separately | 1 a second | 60 |
| Requests in progress at once | 16. Another request waits up to two seconds for one to finish, then returns busy. | |
Revoking counts only against its own limit, so a leaked key that uses up your other limits can't stop you removing it. Someone clicking in the dashboard never comes close, and fifty creates at once fit in the burst.
A change that names several Computers, or several static addresses, counts once for each. Heaven accepts such a request whenever it would accept a single command, whatever the request's size. If it names more than you have left, your next commands wait until the limit has refilled by that many.
Waiting on an operation? Use wait=true or a stream instead of polling quickly. A wait in progress doesn't count against the 16.
Size limits
| What | Limit |
|---|---|
A POST body | 512 KiB of JSON; 2 MiB for exec |
exec output, not streamed | 1 MiB, within 30 seconds |
exec streamed | An hour, with no limit on output or input |
stdin in JSON | 1 MiB. Send more as the request body. |
| Setup script | 10 KiB |
| Feedback text | 16 KiB |