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

# Errors

> Error envelope, codes, and real examples

All errors use one envelope:

```json theme={null}
{
  "error": {
    "code": "INVALID_ARGUMENT",
    "message": "status filter other than open is not supported for type=poll",
    "details": { "field": "status" }
  }
}
```

`code` is the stable contract — branch on it, not on `message` wording.
`details` is optional context (offending `field`, `retry_after` seconds, …).

## Error codes

| code               | HTTP | When                                                                                                                     |
| ------------------ | ---- | ------------------------------------------------------------------------------------------------------------------------ |
| `UNAUTHORIZED`     | 401  | Missing, invalid, revoked, or expired key; or the key's account is no longer active                                      |
| `FORBIDDEN`        | 403  | Reserved for future scopes (not currently returned)                                                                      |
| `NOT_FOUND`        | 404  | Resource doesn't exist, unknown handle, hidden by privacy settings, or removed by moderation — existence is never leaked |
| `INVALID_ARGUMENT` | 400  | Parameter validation failed (`details.field` names it)                                                                   |
| `RATE_LIMITED`     | 429  | Over quota — see [Rate limits](/rate-limits)                                                                             |
| `SERVICE_DISABLED` | 503  | The Open API is temporarily switched off (maintenance/emergency)                                                         |
| `INTERNAL`         | 500  | Our bug — retry once, then back off                                                                                      |

## Real examples

**401 — no key** (captured live):

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Provide an API key: Authorization: Bearer sspat_…"
  }
}
```

<Note>
  401 responses carry a `WWW-Authenticate: Bearer realm="seesaw-open-api"`
  header. Depending on the network path it may arrive under the name
  `x-amzn-remapped-www-authenticate` — match either when debugging.
</Note>

**400 — invalid argument** (captured live):

```json theme={null}
{
  "error": {
    "code": "INVALID_ARGUMENT",
    "message": "status filter other than open is not supported for type=poll",
    "details": { "field": "status" }
  }
}
```

**429 — rate limited**: see [Rate limits](/rate-limits) for the full shape
and headers.

## 404 semantics worth knowing

A 404 does **not** distinguish between "never existed", "hidden by the
owner's privacy settings", and "removed by moderation" — deliberately. Don't
retry 404s; surface them as "not available".

Over **MCP**, errors arrive as tool errors with the same message text (e.g.
`resource not found`), so agents get the same signal.
