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

# Errors

> Every error code the PolyTape agent plane returns, what it means, and whether to retry.

Errors are structured JSON:

```json theme={null}
{ "error": "<code>", "message": "<human text>", "retry_after": <seconds> }
```

`retry_after` is present on `429`s. On MCP the same failures arrive as readable
tool results (`isError: true` with text), never as opaque protocol errors.

## The table

| HTTP | error                    | meaning                                                                            |
| ---- | ------------------------ | ---------------------------------------------------------------------------------- |
| 400  | `bad_cursor`             | malformed cursor — only ever page with a `next_cursor` you were handed             |
| 400  | `bad_limit`              | `limit` must be ≥ 1                                                                |
| 400  | `invalid_wallet`         | a `0x…` string of the wrong hex length. It never falls through to name resolution. |
| 400  | `unknown_event_type`     | an unrecognized value in `types`                                                   |
| 401  | `missing_credentials`    | no `Authorization` header (`WWW-Authenticate: Bearer`)                             |
| 401  | `invalid_api_key`        | unknown or revoked key                                                             |
| 403  | `depth_gated`            | the market is past your history window (Basic Intelligence = 5 markets per trader) |
| 403  | `wallet_quota`           | Basic Intelligence's 3-distinct-wallets-per-UTC-day cap                            |
| 404  | `not_found`              | no such market for this trader                                                     |
| 404  | `unknown_trader`         | no resolvable wallet, URL, or name                                                 |
| 404  | `tape_not_found`         | no such tape in your library                                                       |
| 429  | `rate_limited`           | token bucket or per-minute ceiling hit                                             |
| 429  | `daily_limit`            | **the paywall** — Basic Intelligence's daily call quota is spent                   |
| 429  | `monthly_limit`          | **the paywall** — Pro / Max monthly call quota is spent                            |
| 429  | `busy`                   | heavy-read admission lane full                                                     |
| 429  | `too_many_auth_failures` | too many bad keys from your IP                                                     |
| 503  | `agent_api_disabled`     | the agent surface is temporarily off                                               |
| 503  | `archive_offline`        | the archive is temporarily unreachable                                             |
| 503  | `pm_offline`             | Polymarket's upstream is temporarily unreachable                                   |
| 504  | `query_timeout`          | the query was too broad (or `top-markets` `n` too large) — narrow and retry        |

## How to react

<AccordionGroup>
  <Accordion title="Transient — wait and retry" icon="rotate">
    `rate_limited` · `busy` · `archive_offline` · `agent_api_disabled`

    Honor `Retry-After` (seconds) where present. These clear in seconds. A
    well-behaved agent waits rather than failing the turn.

    `pm_offline` is a special case: the trader card and pnl-series **degrade
    gracefully** rather than erroring. The card serves with
    `"polymarket": {"status": "pm_offline"}` and carries the archive's realized
    P/L as a labeled fallback. Use it, say which voice you are quoting, and move
    on.
  </Accordion>

  <Accordion title="The paywall — relay, do not retry" icon="lock">
    `daily_limit` · `monthly_limit`

    The `message` is **written to be relayed to your human**. It names the
    upgrade and links `https://polytape.io/pricing`, and it is plan-aware (Pro is
    told about Max).

    Surface it and stop. `retry_after` on a daily cap points hours out and on a
    monthly cap points weeks out.
  </Accordion>

  <Accordion title="Plan walls — surface the upgrade" icon="ban">
    `depth_gated` · `wallet_quota`

    Not outages. Retrying changes nothing — the answer will be identical until
    the plan changes or the day rolls over.

    ```json theme={null}
    HTTP 403
    { "error": "wallet_quota",
      "message": "…names the plan, the upgrade, and the reset…",
      "used": 3,
      "limit": 3,
      "resets_at": "2026-07-29T00:00:00Z" }
    ```

    `resets_at` is an ISO 8601 UTC string (next midnight UTC) — the one timestamp
    on this API that is not epoch seconds. There is **no `retry_after`** here.

    Treat `depth_gated` as an upgrade prompt, or as a not-found if you would
    rather not interrupt.
  </Accordion>

  <Accordion title="Your mistake — fix the input" icon="wrench">
    `bad_cursor` · `bad_limit` · `invalid_wallet` · `unknown_event_type` ·
    `not_found` · `unknown_trader` · `tape_not_found`

    Do not retry the same request. Fix the argument.

    These **burn a call** (the counter charges served work), so validate before
    you fire — a typo'd `condition_id` costs a Basic user 1/50th of their day.
  </Accordion>

  <Accordion title="Credential trouble" icon="key">
    `missing_credentials` · `invalid_api_key` · `too_many_auth_failures`

    Revocation is instant, so a key that worked a minute ago can be dead now. Fix
    the credential, then wait out the auth-failure window before retrying.
  </Accordion>

  <Accordion title="Too broad" icon="hourglass-end">
    `query_timeout`

    Almost always a mega-maker (a 100k+ market account) plus a wide `n` on
    `top-markets`. Narrow `n` and retry — a small `n` is both cheaper and
    likelier to return.
  </Accordion>
</AccordionGroup>

## What burns a call

<Columns cols={2}>
  <Card title="Burns a call" icon="fire">
    Every successful GET or tool call. **And** application errors on real routes —
    `400`, `403`, `404`, even `304`.
  </Card>

  <Card title="Free" icon="check">
    All `429` rejections. MCP protocol handshakes: connect, `tools/list`,
    `prompts/list`, fetching a prompt.
  </Card>
</Columns>

## MCP error text

The same failures, as tool results:

| Text                                                  | Underlying                                        |
| ----------------------------------------------------- | ------------------------------------------------- |
| `rate limit: retry in Ns`                             | `rate_limited` or `busy`                          |
| A message naming an upgrade and `polytape.io/pricing` | `daily_limit`, `monthly_limit`, or `wallet_quota` |
| `this market is outside your history window`          | `depth_gated`                                     |
| `no such market for this trader`                      | `not_found`                                       |
| `no such tape in your library`                        | `tape_not_found`                                  |
| `the trader archive is not available…`                | `archive_offline`                                 |
