HeavenDocs

Getting started

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

409
{
  "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"
  }
}
kind string
What went wrong, from the list below. Your code should check this.
message string
A sentence to show people, with the specific problem and the next step. Its wording can change, so don't parse it.
request_id string
The change's Idempotency-Key, when it had one.
operation_id string
The operation to read, when there is one.
retry_after integer
For rate_limited, the seconds to wait. It's also sent as the Retry-After header.
url string
A Stripe page where you can pay, for some payment_required errors.
action object
Present when the message suggests a command. command is its name (pool start), and line is the full command from the message (pool start web), so an app can show its own button for it.

Kinds

KindHTTPMeansDo
invalid400A missing or malformed field, value or size.Fix the request.
denied401, 403The credential is missing, expired or not allowed this command.Check the key and its commands.
not_found404Nothing 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.
conflict409It 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_capacity409A 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_full409A 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_required402Payment 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_limited429You sent commands faster than your rate limit. Nothing changed.Wait retry_after seconds.
busy429Too many of your requests at once, or the server is at capacity. Nothing changed.Retry shortly.
unknown503A 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.
unavailable503Refused 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.

WhatRateBurst
All commands20 a second300
Changes (create, start, snapshots, domains, ports, pools, billing…)1 a second60
Revoking a key or sign-in (api-key remove, ssh-key remove, sign-in end-all), counted for each key and sign-in separately1 a second60
Requests in progress at once16. 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

WhatLimit
A POST body512 KiB of JSON; 2 MiB for exec
exec output, not streamed1 MiB, within 30 seconds
exec streamedAn hour, with no limit on output or input
stdin in JSON1 MiB. Send more as the request body.
Setup script10 KiB
Feedback text16 KiB