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

# Errors

> HTTP status codes, error envelope shape, and common failure modes with fixes.

## Error envelope

Every non-2xx response returns the same JSON envelope. The `error`
field is a human-readable summary; `code` is a stable machine token;
`request_id` matches the `X-Request-Id` response header.

```json theme={null}
{
  "error": "Missing Authorization: Bearer sk_live_... header",
  "code": "MISSING_API_KEY",
  "request_id": "req_a1b2c3d4e5f6...",
  "detail": "optional context string",
  "retry_after": 42
}
```

Validation failures also include an `issues` array of `{ path, message }`
objects sourced from Zod, one entry per invalid field.

## HTTP status codes

| Status | When                                                                                                    |
| ------ | ------------------------------------------------------------------------------------------------------- |
| 200    | Successful call. Bulk endpoints may still report row-level errors inside the payload.                   |
| 400    | Body failed schema validation. See `issues[]`.                                                          |
| 401    | Missing, malformed, or invalid API key. Also revoked keys.                                              |
| 402    | Payment required. Either monthly quota exhausted or org downgraded below Growth.                        |
| 404    | Only from `/v1/rates` when no row exists for the country plus HS pair.                                  |
| 422    | Semantic failure the schema cannot catch (missing HS code, unsupported destination, domestic shipment). |
| 429    | Rate limit tripped. See [Rate limits](/rate-limits).                                                    |
| 500    | Unexpected server error. Retry with backoff.                                                            |

## Common error codes

### `MISSING_API_KEY`

Status: `401`. The `Authorization` header is missing or does not start
with `Bearer `. Add the header.

### `INVALID_API_KEY_FORMAT`

Status: `401`. The bearer token does not match the `sk_live_...` or
`sk_test_...` format. Copy the raw key from **Settings > API keys**
without trimming.

### `INVALID_API_KEY`

Status: `401`. The prefix matched a row but the full key hash did
not verify. Usually a typo. Rotate if you suspect the key was
truncated in a secret manager.

### `API_KEY_REVOKED`

Status: `401`. The key was revoked. Mint a new one.

### `TIER_DOWNGRADED`

Status: `402`. The organization dropped below the Growth tier. The
key is still valid; upgrade to resume.

### `QUOTA_EXCEEDED`

Status: `402`. Monthly quota exhausted for the current billing period.
Wait for the reset on the first of the next month or upgrade tier.

### `RATE_LIMIT_EXCEEDED`

Status: `429`. See [Rate limits](/rate-limits) for the retry pattern.

### `MISSING_HS_CODE`

Status: `422`. A line in `/v1/calc` has no `hs_code` and inline
classification failed to produce one above the confidence threshold.
Call `/v1/classify` first, or pass a longer, more descriptive
`description`.

### `UNSUPPORTED_DESTINATION`

Status: `422`. The `destination_country` is outside the covered list.
Coverage is documented in the [rates endpoint reference](/api-reference/endpoint/rates).

### `DOMESTIC_SHIPMENT`

Status: `422`. `origin_country` equals `destination_country`. There is
no landed cost to calculate.

### `INTERNAL`

Status: `500`. Something failed inside the engine. The `request_id` in
the envelope is enough for support to pull the call log. Send it to
`info@growyourbrand.io`.

## Bulk endpoints and partial failures

`/v1/calc/bulk` and `/v1/compare` do **not** fail the whole batch on
row-level errors. The response body carries an `errors` (or
per-origin) array alongside `results`. A `200` status only means the
request itself was accepted; always inspect the payload for per-row
outcomes.

```json theme={null}
{
  "results": [ ... ],
  "errors": [
    { "line_index": 12, "reason": "invalid HS code", "field": "hs_code" }
  ],
  "aggregate": { "ok_rows": 499, "error_rows": 1, ... }
}
```
