# Account API errors

Account API errors are REST JSON responses. They are not related to numeric [proxy error codes](/docs/proxy-errors).

## Error envelope

```json
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication failed.",
    "requestId": "req_example",
    "docsUrl": "https://litport.net/docs/api/errors"
  }
}
```

The same request ID appears in the `X-Request-ID` header. Log it with the HTTP status and error code. Never log the `Authorization` header.

## Status reference

| Status | Codes | Client action |
| ---: | --- | --- |
| `400` | `INVALID_LIMIT`, `INVALID_TYPE`, `INVALID_STATUS`, `INVALID_CURSOR`, `INVALID_TIME_RANGE`, `INVALID_GROUP_BY`, `INVALID_INCLUDE` | Correct the request. Do not retry it unchanged. |
| `401` | `UNAUTHORIZED` | Supply a current account API key using the Bearer scheme. The response does not reveal whether a key or user exists. |
| `404` | `TOKEN_NOT_FOUND` | Check the token ID and ownership. The response does not disclose another user's token. |
| `404` | `NOT_FOUND` | Correct the API route. |
| `405` | `METHOD_NOT_ALLOWED` | Use `GET`. The initial account API has no write or token-creation methods. |
| `429` | `RATE_LIMITED` | Respect `Retry-After` when present and use jittered backoff. |
| `503` | `SERVICE_UNAVAILABLE`, `TOKEN_DATA_INVALID` | Respect `Retry-After`, retry with bounded backoff, then contact support with the request ID. |

## Retry algorithm

Retry only `429` and transient `503` responses automatically. Honor `Retry-After`, add jitter, cap attempts, and make the total retry budget visible to the caller. All current operations are `GET`, but callers should still avoid unbounded retries.

## Error code details

### Invalid limit

`INVALID_LIMIT` means `limit` is not an integer from 1 through 100.

### Invalid type

`INVALID_TYPE` means `type` is not `unlimited` or `ppg`.

### Invalid status

`INVALID_STATUS` means `status` is not `active`, `expired`, or `disabled`.

### Invalid cursor

`INVALID_CURSOR` means the opaque cursor is malformed, edited, or cannot be authenticated. Restart pagination without a cursor.

### Invalid time range

`INVALID_TIME_RANGE` means a timestamp is not canonical UTC, `from` is not before `to`, or the requested span is too large.

### Invalid group by

`INVALID_GROUP_BY` means `groupBy` is not `hour`, `day`, or `month`.

### Invalid include

`INVALID_INCLUDE` means the requested expansion is incompatible with the token or grouping; charge components require a PPG token and hourly buckets.

### Unauthorized

`UNAUTHORIZED` covers missing, malformed, unknown, rotated, and ownerless keys without revealing which condition occurred.

### Token not found

`TOKEN_NOT_FOUND` covers both missing and unowned token IDs.

### Not found

`NOT_FOUND` means the requested `/api/v1` route does not exist.

### Method not allowed

`METHOD_NOT_ALLOWED` means a known read-only endpoint received a non-GET method. The response includes `Allow: GET`; there is no proxy-token creation method in this release.

### Rate limited

`RATE_LIMITED` means the API key exhausted its current account API window. Respect `Retry-After`.

### Token data invalid

`TOKEN_DATA_INVALID` means token metadata is temporarily unavailable. Retry later, then report the request ID.

### Service unavailable

`SERVICE_UNAVAILABLE` means an account API dependency is temporarily unavailable. Respect `Retry-After`.

## Authentication failures

The API deliberately returns the same `401` envelope for malformed, unknown, rotated, and ownerless keys. Create or rotate an account API key in [Settings](/users/settings). A rotation immediately invalidates the previous active key.
