Errors
The status codes and error bodies the Coritan API returns, the fields to read in each, and what to do about them.
A request that fails answers with a status code of 400 or more and a JSON body. Read the status code first: it says what kind of failure it is. The body's detail field then says what went wrong, in one of the three shapes below.
The error body
Section titled The error bodyA sentence
Section titled A sentenceMost errors carry one sentence, written to be shown to a person:
{"detail": "Invoice not found"}
Branch on the status code, not on the words.
An object with a code
Section titled An object with a codeErrors that a program is expected to act on carry an object. error is a code to branch on, message is the sentence to show, and some codes add fields of their own:
{
"detail": {
"error": "rate_limited",
"message": "Too many requests for this action. Please wait and try again.",
"action": "container.power",
"retry_after_seconds": 60
}
}
A few errors name the code reason instead of error, such as a locked server:
{"detail": {"reason": "server_locked", "message": "We have locked this server because activity on it broke our acceptable use policy, and our team is reviewing it. ..."}}
A feature your plan does not include answers 403 with the feature and upgrade_required:
{
"detail": {
"feature": "backups",
"reason": "free_plan",
"message": "Backups are not included on the free plan. Upgrade to a paid plan, or download your world from the file manager.",
"upgrade_required": true
}
}
Some orders that fail a check of their settings answer 422 with a list of sentences: {"detail": {"errors": ["..."]}}.
A list of field errors
Section titled A list of field errorsA body, query or path value that is missing or has the wrong type answers 422 with one entry for each field. loc says where the field is, and msg what is wrong with it:
{
"detail": [
{
"type": "missing",
"loc": ["body", "password"],
"msg": "Field required",
"input": {"email": "alex@example.com"}
}
]
}
Status codes
Section titled Status codes| Status | Meaning | What to do |
|---|---|---|
400 |
The request is well formed, but it cannot be carried out as sent. detail says why. |
Change the request. |
401 |
The credential is missing, expired, or the wrong kind for the route. | Refresh the token or sign in again, as Authentication describes. |
402 |
A payment did not complete, such as a card the bank declined. | Read detail, then pay with another method. |
403 |
You may not do this: your role or plan does not allow it, the account is suspended, or the record belongs to someone else. A Client API request with no Authorization header also answers 403 Not authenticated. |
Check the credential and what it may do. Do not retry unchanged. |
404 |
The path or the record does not exist, or it belongs to another account. | Check the ID and the path. |
409 |
The request conflicts with the record's state: a name is taken, the same action is already running, or the record is being deleted. | Read the record again, then decide. |
413 |
A file or a body is larger than the route accepts. detail gives the limit. |
Send less. |
422 |
A field is missing or not valid. | Fix the fields detail names. |
423 |
The server is locked, and detail.reason is server_locked. The lock does not delete your files. |
Reply to the support ticket that came with the lock. |
429 |
Too many requests. | Wait as long as Retry-After says. Rate limits lists the limits. |
500 |
Something failed on Coritan's side. detail is Internal server error. |
Retry later. If it keeps failing, contact support with the time and the request. |
502 |
A system the API depends on refused or failed, such as a payment provider or a domain registrar. detail says which. |
Retry later. |
503 |
The API or one of its services is not available right now. | Retry after the Retry-After header, or later when there is none. |
A 503 while the API starts up has its own body, and asks you to wait two seconds with Retry-After: 2:
{"detail": "Service unavailable: database not ready", "status": "not_ready"}
Error codes
Section titled Error codesThese codes in detail.error or detail.reason come up on many routes. The page for each product lists the ones it adds.
| Code | Status | Meaning |
|---|---|---|
turnstile_failed |
403 |
The verification check is on, and turnstile_token is missing or did not pass. |
mfa_required |
401 |
A pending token from a sign-in with two-factor authentication was sent to a route that needs a full sign-in. |
reauth_required |
403 |
An Organization API action needs a step-up in the last 10 minutes. max_age_seconds says how long one lasts. |
rate_limited |
429 |
An action's own budget is spent. action names it, and retry_after_seconds gives the length of its window. |
free_limit_reached |
409 |
You already have the most of that free plan an account may hold. Remove one, or choose a paid plan. |
free_tier_paused |
503 |
Free servers are at capacity, so a storefront takes no orders for them right now. |
plan_not_sold_here |
403 |
The plan cannot be ordered through this API. |
server_locked |
423 |
The server is locked while Coritan reviews it. |
server_deleting |
409 |
The server is being deleted, so it takes no more actions. |
The Commerce API and the Store API answer every error with an object like this, with codes such as not_found, invalid, conflict, forbidden, commerce_not_enabled, scope_required and idempotency_key_reused. Authentication lists the codes about credentials, and Idempotent requests the codes about repeated requests.
Errors from in front of the API
Section titled Errors from in front of the APIThe proxy in front of the API can refuse a request before the API sees it. Its answers carry error at the top level and no detail:
| Status | Body | Meaning |
|---|---|---|
429 |
{"error":"Too many requests"} |
Your address sent too many requests or opened too many connections. Retry-After is 1. |
413 |
{"error":"Request body too large"} |
The body is larger than the proxy accepts. |
Handle both bodies: read detail when it is there, and error when it is not.