Skip to main content

Errors

Any response outside the 2xx range carries a JSON body. Branch on code, never on message — messages are written for humans and can be reworded.

The envelope​

{
"detail": {
"code": "INSUFFICIENT_BALANCE",
"message": "Deploying needs about 1h of credit up front",
"balance_micro": 1500000,
"required_micro": 2305000
}
}
KeyTypeMeaning
detail.codestringStable, uppercase, safe to branch on
detail.messagestringOne-line human explanation
Extra keysvariesContext for that specific failure

Two failures use a different shape. Request validation errors from the framework put a list under detail, one entry per bad field:

{"detail": [{"type": "greater_than_equal", "loc": ["body", "disk_gb"], "msg": "Input should be greater than or equal to 10"}]}

And an unexpected server-side failure puts a plain string there, such as {"detail": "Internal Server Error"}. Handle all three forms if you are writing a client library.

HTTP statuses​

StatusMeaning
200The request succeeded
201Something was created — an instance, a template copy, an API key
204Succeeded with no body: revoking a key, deleting an SSH key
400The request is malformed, such as an X-Org-Id that is not an id
401The bearer token is missing, invalid, expired, revoked, or an API key on an account endpoint
402The organization's balance does not cover the action, or payments are frozen
403You are authenticated but not allowed: admin-only action, wrong organization, or an immutable object
404Not found, or not visible to your organization — the two are deliberately indistinguishable
409The state conflicts: the offer is taken, the instance is in the wrong status, the name is used
410Gone: an invite that was used, has expired, or was revoked
413The request body is larger than the endpoint accepts
422The values are wrong: a field out of range, a disk larger than the machine, an unknown enum value
429Too many requests: wait for Retry-After
503Temporarily unavailable: a start the host could not complete, or sign-in checks that cannot run right now. Retry shortly

What a renter actually hits​

ConditionStatusCodeWhat to do
Deploying or starting when the balance does not cover one hour of the organization's burn with that instance running (its GPU and disk, plus the GPU and disk of instances running, starting or being created and the disk of stopped ones) — a positive balance is not enough402INSUFFICIENT_BALANCEAn admin adds credits in the console. The body carries balance_micro and required_micro. API keys cannot top up.
The offer was rented between your list call and your deploy, or while your deploy was being reserved409OFFER_UNAVAILABLETake the next offer from your filtered list and retry. Do not retry the same offer_id. Nothing was created.
The machine is booked offline sooner than an instance can be started on it409MACHINE_IN_MAINTENANCEThe body carries next_maintenance. Deploy elsewhere, or wait for the window to pass. This is not a capacity problem — the machine has free GPUs — so retrying the same offer works once the window is over.
disk_gb outside 10–20000422validation listSend a value inside the range
disk_gb larger than the host's disk422DISK_TOO_LARGEThe body carries max_disk_gb. Retry at or below it, or pick a bigger machine.
Admin-only action, or any admin action attempted with an API key403ADMIN_REQUIREDUse a session token belonging to an admin. Checkout, invites and member management are never available to keys. See Roles and permissions.
Revoking a key that is unknown, already revoked, or in another organization404API_KEY_NOT_FOUNDRe-list GET /v1/api-keys and use a current id
Stopping, starting or destroying from a status that forbids it409INVALID_STATERead status first. The message names the current one, for example Cannot start an instance while it is running.
A vm template on a machine that is not VM-capable422OFFER_NOT_VM_CAPABLEFilter for offers whose vm_capable is true
An ssh_key_id the credential may not attach: not your own, or — with a team key — not a current member's404SSH_KEY_NOT_FOUNDList GET /v1/ssh-keys with a session token and use one of those ids
The organization already holds 25 instances that are not destroyed409INSTANCE_LIMIT_REACHEDThe body carries limit. Destroy one first — stopped and errored instances count, so stopping frees nothing.
A payment dispute is open on the organization402PAYMENTS_FROZENDeploys and starts are paused until the dispute closes.
A template that is not published yet, pins a CUDA older than the machine's, or needs non-x86_64 hardware422TEMPLATE_COMING_SOON, TEMPLATE_CUDA_TOO_NEW, TEMPLATE_ARCH_UNSUPPORTEDBefore deploying, check the template's coming_soon and its constraints.cuda_max and constraints.arch against the offer's cuda_version.
Another organization's template that pulls from a private registry, or an offer whose machine the control plane does not know422, 409TEMPLATE_REQUIRES_OWNER, OFFER_NOT_PINNABLENothing was created. Duplicate the template with your own registry credentials, or re-list offers.
Starting an instance whose host cannot take it409, 503HOST_UNREACHABLE, START_REFUSED, START_UNAVAILABLEThe instance is still stopped. Retry later — for START_UNAVAILABLE, shortly. A START_REFUSED whose message says the host no longer holds the workload will not succeed: destroy and redeploy.
Starting an instance whose GPUs were released (gpus_released), while another renter uses one of them409CAPACITY_UNAVAILABLEThe instance is still stopped, with its disk. Retry later; a start has to get the same GPUs back, so no other machine or offer will do.
Too many requests from one caller429RATE_LIMITEDWait the number of seconds in the Retry-After header (also in the body as retry_after_s), then retry.
A request body over the size limit413PAYLOAD_TOO_LARGEThe body carries limit_bytes. Send less: 1 MiB for most endpoints, 4 MiB for templates.
An instance, offer or template your organization cannot see404INSTANCE_NOT_FOUND, OFFER_NOT_FOUND, TEMPLATE_NOT_FOUNDCheck the X-Org-Id you sent, and that the object still exists

Authentication and organization failures — TOKEN_INVALID, TOKEN_EXPIRED, NOT_A_MEMBER, ORG_MISMATCH, INVALID_ORG_ID — are covered in Authentication. The complete list of codes is in Error codes.

Retrying​

ResponseRetry?
402No. Nothing changes until credits arrive — or, for PAYMENTS_FROZEN, until the dispute closes.
409 INSTANCE_LIMIT_REACHEDOnly after destroying an instance.
409 OFFER_UNAVAILABLEYes, with a different offer.
409 MACHINE_IN_MAINTENANCEYes, with a different machine — or with the same one after next_maintenance.
409 INVALID_STATEOnly after re-reading the instance and confirming the transition is now legal — allowed_actions says what is.
409 HOST_UNREACHABLE, START_REFUSED, CAPACITY_UNAVAILABLELater, with backoff. The instance stays stopped in the meantime.
429 RATE_LIMITEDYes, after Retry-After seconds.
503Yes, after a short wait.
422No. Fix the request first. For INVALID_CURSOR, start the listing again without a cursor.
401 TOKEN_EXPIREDYes, once, with a fresh session token. An shk_ key does not expire, so a 401 on a key means it was revoked.

POST /v1/instances takes no idempotency key, so a timeout leaves you unsure whether the rental happened. Resolve it by looking, not by retrying: GET /v1/instances and match on your label.

Retrying the same offer_id is not safe. An offer is a shape, not a single slot — a machine with GPUs left answers the same offer again and you get a second instance, billed separately, from one intended deploy. It only 409s once that machine's units are gone, which is exactly the case where you were not double-charged anyway.