> ## Documentation Index
> Fetch the complete documentation index at: https://docs.earthity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Every error the Outpost API can return: the RFC 9457 problem+json anatomy, and every code with what happened and what to do about it.

Every error is an [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457) `application/problem+json` body, with one exception noted below. `code` is the machine-readable value - stable across releases, safe to switch on in client code. `type` is a URI that resolves to this page's anchor for that code - this member *is* the documentation link.

## Problem anatomy

<a id="problem-anatomy" />

RFC 9457 problem details, the body of every error in this API except the legacy 429 described below. `code` is the value to branch on; `type` resolves to its section on this page.

| Property | Type | Required | Constraints | Description |
| - | - | - | - | - |
| `type` | `string` | yes | format: uri-reference | The documentation URI for `code`: `https://docs.earthity.com/errors/<code>`, which redirects to that code's section on this page. |
| `status` | `integer` | yes | - | The HTTP status, repeated in the body. |
| `title` | `string` | yes | - | A short summary of the code. Fixed per code; do not match on it. |
| `detail` | `string` | no | - | What went wrong in this instance, when there is more to say than `title`. |
| `code` | `string` | yes | - | The machine-readable error code — the value to branch on. Every code is listed on this page. |
| `field` | `string` | no | - | Which request field the problem concerns, when it concerns one. Each code below says whether it ever carries this. |
| `error` | `string` | no | - | The same text as `detail` (or `title` when there is no `detail`), duplicated for older consumers that read `.error`. Production route responses carry it; the sandbox and the rate limiter omit it. Read `detail` in new code. |
| `documentation_url` | `string` | no | - | The same URI as `type`, under the name some clients expect. Present on the same responses as `error`. |

## Legacy error body

<a id="legacy-error-body" />

The one error body in this API that is not problem+json: the per-IP rate limit's 429 on routes outside the dock-control plane, such as `PATCH /api/docks/{id}`. `{ "error": "Too many requests" }`, with `Retry-After`. Every other error is `application/problem+json`.

| Property | Type | Required | Constraints | Description |
| - | - | - | - | - |
| `error` | `string` | no | - | |

## Error catalog

| Code | Status | `field` member | Source |
| - | - | - | - |
| [`validation_failed`](#validation_failed) | `400` | sometimes present | `service_error` |
| [`unauthorized`](#unauthorized) | `401` | never present | `route` |
| [`forbidden`](#forbidden) | `403` | sometimes present | `service_error` |
| [`demo_read_only`](#demo_read_only) | `403` | never present | `service_error` |
| [`not_found`](#not_found) | `404` | never present | `service_error` |
| [`conflict`](#conflict) | `409` | sometimes present | `service_error` |
| [`invite_expired`](#invite_expired) | `410` | never present | `route` |
| [`rate_limited`](#rate_limited) | `429` | never present | `infra` |
| [`internal_error`](#internal_error) | `500` | never present | `infra` |
| [`temporarily_unavailable`](#temporarily_unavailable) | `503` | never present | `infra` |
| [`dock_busy`](#dock_busy) | `409` | never present | `route` |
| [`idempotency_key_reused`](#idempotency_key_reused) | `409` | never present | `route` |
| [`command_unavailable`](#command_unavailable) | `503` | never present | `route` |
| [`stale_result`](#stale_result) | `409` | never present | `route` |
| [`camera_unavailable`](#camera_unavailable) | `503` | never present | `route` |

### Validation failed

<a id="validation_failed" />

**Code:** `validation_failed`  ·  **Status:** `400`  ·  **`field` member:** sometimes present

The request body or parameters did not pass validation: a required field was missing, a value was out of range, or an enum value was not recognized.

Check the `detail` member for the specific problem, fix the request, and resend it.

### Unauthorized

<a id="unauthorized" />

**Code:** `unauthorized`  ·  **Status:** `401`  ·  **`field` member:** never present

The request carried no credential, or the credential it carried was missing or invalid.

Send a valid `Authorization: Bearer` credential and retry.

### Forbidden

<a id="forbidden" />

**Code:** `forbidden`  ·  **Status:** `403`  ·  **`field` member:** sometimes present

The credential was valid, but does not carry permission for this action; for example, a non-admin member trying to change org settings.

Use a credential with the required role, or ask an admin to perform the action.

### Demo mode is read-only

<a id="demo_read_only" />

**Code:** `demo_read_only`  ·  **Status:** `403`  ·  **`field` member:** never present

This request would mutate data, but the current session is a demo session, and demo sessions cannot write.

Sign in with a real account to perform this action.

### Not found

<a id="not_found" />

**Code:** `not_found`  ·  **Status:** `404`  ·  **`field` member:** never present

The resource named in the request path does not exist, or exists but is not visible to this credential.

Check the id in the path. A resource outside your visibility scope also reports as not found, not forbidden.

### Conflict

<a id="conflict" />

**Code:** `conflict`  ·  **Status:** `409`  ·  **`field` member:** sometimes present

The request conflicts with the resource's current state; for example, adding a member who already belongs, or reusing a value that must be unique.

Check the `detail` member for the specific conflict and adjust the request; this is not something a bare retry fixes.

### Invite expired

<a id="invite_expired" />

**Code:** `invite_expired`  ·  **Status:** `410`  ·  **`field` member:** never present

The invite this request references is past its expiry window and can no longer be redeemed.

Ask whoever sent the invite to send a new one.

### Too many requests

<a id="rate_limited" />

**Code:** `rate_limited`  ·  **Status:** `429`  ·  **`field` member:** never present

Too many requests in a short window: more than 30 mutating requests from one IP in 10 seconds; more than 120 command reads from one IP in 10 seconds, 1,200 for one organization in a minute, or 600 for one API key in a minute; more than 30 sandbox reads from one IP in 10 seconds; or, for dock commands, more than 6 commands to one dock, 30 from one organization or 15 from one API key in a minute.

Back off and retry. Honour `Retry-After` when it is present: every read limit, every per-IP limit and every per-key limit sends it; the per-dock and per-organization command limits do not — and the per-dock one is a physical cycle time, not a quota to work around.

### Internal server error

<a id="internal_error" />

**Code:** `internal_error`  ·  **Status:** `500`  ·  **`field` member:** never present

Something went wrong on the server that was not anticipated by the request-handling code.

Retry with backoff. If it persists, the failure has already been recorded on our side; contact support with the time of the request.

### Temporarily unavailable

<a id="temporarily_unavailable" />

**Code:** `temporarily_unavailable`  ·  **Status:** `503`  ·  **`field` member:** never present

A dependency this request needs is not currently configured or reachable, so the request is refused rather than served incorrectly.

Retry with backoff. This is a fail-closed condition on our side, not something your request can fix.

### Dock is busy

<a id="dock_busy" />

**Code:** `dock_busy`  ·  **Status:** `409`  ·  **`field` member:** never present

A dock runs one command at a time, and this dock already has a command in flight.

Back off and retry later with a FRESH `Idempotency-Key`; reusing the same key just replays into the same busy dock.

### Idempotency key reused with different parameters

<a id="idempotency_key_reused" />

**Code:** `idempotency_key_reused`  ·  **Status:** `409`  ·  **`field` member:** never present

The same `Idempotency-Key` was sent with a request the dock-control executor had already reserved that key for, with different parameters. Neither Outpost server raises this any more: a reused key carrying a different command is treated as a new command on both.

Use a new `Idempotency-Key` for a genuinely different request. Resend the ORIGINAL body unchanged if you're retrying the same request.

### Command channel unavailable

<a id="command_unavailable" />

**Code:** `command_unavailable`  ·  **Status:** `503`  ·  **`field` member:** never present

The channel this command would travel through is not currently available, so the command was refused rather than accepted and silently dropped.

Retry with backoff.

### Stale command result

<a id="stale_result" />

**Code:** `stale_result`  ·  **Status:** `409`  ·  **`field` member:** never present

This command already has a different completion event recorded against it. Each command is resolved exactly once, and a second, conflicting outcome is rejected rather than overwriting the first.

Read the command's own resource to see the outcome that was recorded. A result that simply arrives late is not an error and does not return this code — it is accepted as long as nothing has resolved the command yet.

### Camera unavailable

<a id="camera_unavailable" />

**Code:** `camera_unavailable`  ·  **Status:** `503`  ·  **`field` member:** never present

The dock's camera could not produce a live video answer — the connection to it failed, or the WebRTC handshake itself failed or timed out.

Retry with backoff. If it persists, the dock may be offline or its camera module may be down.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.