string
required
The broad class. Six values; see below. Branch on this for retry policy.
string
required
Stable and machine-readable. Branch on this for specific handling.
string
required
Human-readable. Written for a developer reading a log — safe to show a user,
but not localised.
string
required
Deep link to this page, anchored at the code.
string
required
Quote it to support and we can find the exact request.
string
The offending parameter, when one is identifiable.
required_scope, retry_after_seconds, limit_cents,
committed_cents, resets_at. They are always inside the error object,
never beside it, so a parser that reads body.error gets everything.
Branch on type first
billing_error is the one worth special-casing. It looks transient — the request
was valid, nothing was malformed — but retrying it unchanged will fail forever.
A retry loop that treats 402 like 429 will hammer us until its own timeout and
still not start a machine.Every code
Authentication — 401
invalid_api_key
401 ·authentication_error
No usable API key was provided. Send it as Authorization: Bearer gpk_….
Check for the usual suspects: a missing Bearer prefix, a truncated paste, an
environment variable that did not survive into the container, or a trailing
newline from $(cat key.txt).
api_key_revoked
401 ·authentication_error
The key was revoked in the dashboard. Revocation is immediate and final —
create a new key.
If you did not revoke it, someone with dashboard access did. Check with your team
before minting a replacement.
api_key_expired
401 ·authentication_error
The key passed its expiry date. Create a new one.
Permission — 403
insufficient_scope
403 ·permission_error · carries required_scope
The key is valid but lacks the scope this endpoint needs. Scopes are fixed at
creation — mint a new key. See Scopes.
test_mode_not_supported
403 ·permission_error
A test key tried to create or stop a rental. Test keys authenticate like live
keys and read the same real catalog, but there is no sandbox behind this API —
a rental they created would be a real, billed machine. Use a live key.
account_suspended
403 ·permission_error · code banned
The account is suspended. Contact help@gpuoutlet.ai.
Request — 400, 404, 409
invalid_request
400 ·invalid_request_error · often carries param
One or more parameters are invalid. param names the first offender when we can
identify one.
invalid_cursor
400 ·invalid_request_error
The cursor does not match the current filters or sort order. Cursors are valid
only for the exact query that produced them — see Pagination.
pagination_limit_exceeded
400 ·invalid_request_error
The result set is too deep to page through. Narrow the filters rather than paging
further.
not_found
404 ·invalid_request_error
No such resource, or it is not visible to you. The two are reported identically
on purpose: distinguishing them would confirm that another account’s resource
exists.
offer_not_found
404 ·invalid_request_error
No such offer, or it is no longer visible. Offers are transient — a supplier can
withdraw one at any time. Re-read /offers and pick another.
offer_unavailable
409 ·invalid_request_error
The offer exists but cannot be rented right now: no free capacity at the size you
asked for, or the seller withdrew it. Specific to this offer — pick a
different one rather than retrying this one.
Contrast with capacity_unavailable (503), which is not offer-specific.
max_active_rentals_reached
409 ·invalid_request_error
The account is at its concurrent-rental ceiling. Stop one first — and remember
that a rental in stopping still occupies a slot until it reaches stopped.
See Concurrency.
invalid_template
400 ·invalid_request_error
No such template. Omit template_id to boot the default image.
Idempotency — 400, 409
idempotency_key_required
400 ·invalid_request_error
POST /rentals spends money, so Idempotency-Key is mandatory. Generate one per
intent — a UUID is fine. See Idempotency.
idempotency_key_in_flight
409 ·invalid_request_error · carries retry_after_seconds
A request with this key is still being processed. This is the correct answer to a
client that retried before the first attempt finished — it stops you creating two
machines. Wait retry_after_seconds and retry with the same key.
idempotency_key_reused
409 ·invalid_request_error
This key was already used with a different request body. We refuse rather than
silently serving the first rental or overwriting it, because both would be wrong.
Use a new key for a new rental.
Billing — 402
All three arebilling_error. None of them is retryable as-is.
insufficient_balance
402 ·billing_error
The balance does not cover the hold this rental requires. Top up, then retry.
account_past_due
402 ·billing_error
There is an unpaid balance. Settle it before starting new rentals.
key_spend_limit_exceeded
402 ·billing_error · carries limit_cents, committed_cents, resets_at
This key’s daily spend cap would be crossed. Raise the limit, use another key, or
wait until resets_at. See Spend limits.
Rate limits — 429
rate_limited
429 ·rate_limit_error · Retry-After header
Too many requests. Back off for the stated interval. See Rate limits.
daily_quota_exceeded
429 ·rate_limit_error
The daily request quota for this key is spent. It resets at 00:00 UTC. Slowing
down will not help before then.
Ours — 5xx
capacity_unavailable
503 ·api_error
Capacity we expected to be there was not, and no rental was created. Temporary
and not specific to the offer you asked for. Retry with backoff; if it persists
across several offers, check status.gpuoutlet.ai.
api_error
5xx ·api_error
Our fault. Retry with exponential backoff and jitter. If it persists, send us the
request_id.
A retry policy that works
type rather than on the status
code alone, it prefers the server’s Retry-After over its own guess, and it adds
jitter so a fleet of workers does not retry in lockstep.