error field carries
the precise reason.
400 Bad Request
| Code | Meaning | Fix |
|---|---|---|
invalid_email | Email format invalid | Send a real user@host.tld |
invalid_amount | Top-up amount outside [$1, $5000] | Stay in range |
weak_key | SSH key strength below RSA 2048 / Ed25519 | Use ssh-keygen -t ed25519 |
duplicate_key | This public key is already on file | Use the existing one or delete first |
invalid_count | GPU count not 1/2/4/8 | Pick one of the four |
model_unavailable | No provider has this exact spec right now | Try a different config or wait |
billing_disabled | Stripe not configured (mock mode) | Use real backend |
validation_failed | Generic schema validation | Read details for specifics |
401 Unauthorized
| Code | Meaning | Fix |
|---|---|---|
unauthorized | No session cookie or session expired | Sign back in |
code_invalid | OTP code wrong or expired | Request a new code |
code_expired | Code older than 10 minutes | Request a new code |
oauth_state_mismatch | OAuth callback state didn’t match | Restart the OAuth flow |
403 Forbidden
| Code | Meaning | Fix |
|---|---|---|
forbidden | Authenticated but not allowed to access this resource | Check resource ownership |
insufficient_balance | Wallet < cost of operation | Top up |
404 Not Found
| Code | Meaning | Fix |
|---|---|---|
not_found | Path / resource doesn’t exist | Check the URL / ID |
rental_not_found | No rental with that ID owned by you | Check the ID |
key_not_found | SSH key ID doesn’t belong to you | Check the ID |
409 Conflict
| Code | Meaning | Fix |
|---|---|---|
already_stopped | Rental is already in Stopped state | No action needed |
card_already_on_file | Trying to add a card when one exists | Update or remove first |
429 Too Many Requests
| Code | Meaning | Fix |
|---|---|---|
rate_limited | Over 100 req/min on this session | Back off, retry after Retry-After header |
code_request_rate_limited | More than 1 OTP request per 30s | Wait |
500 Internal Server Error
| Code | Meaning | Fix |
|---|---|---|
internal_error | Something we didn’t anticipate | Retry once, then file a ticket if it persists |
provider_error | Upstream provider failed | Usually transient; retry. Persistent → ticket |
503 Service Unavailable
| Code | Meaning | Fix |
|---|---|---|
provider_pool_empty | No upstream provider has the requested GPU right now | Wait 30 seconds or try a different family |
maintenance | Planned maintenance | Check status.gpuoutlet.ai |
How to handle errors in client code
TypeScript example
Reporting bugs
If you hit aninternal_error that reproduces consistently, send the
x-request-id header value (in the response) to
help@gpuoutlet.ai — we can look up the exact
log trace from that.