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

# Authentication and limits

> Send an API key with each request. The limits of a plan apply to the account, across REST and MCP.

## API keys

Send an API key with every request, except `GET /v1`, `GET /v1/openapi.json`, `GET /v1/openapi.yaml` and the [account routes](#account-routes), which take a session of the web app. Make and revoke keys on the [account page](https://numi.sh/account). A key is `numi_live_` followed by 32 letters and digits.

Send the key in the `X-API-Key` header:

```bash theme={null}
curl https://api.numi.sh/v1/me -H "X-API-Key: $NUMI_API_KEY"
```

Or send it as a bearer token:

```bash theme={null}
curl https://api.numi.sh/v1/me -H "Authorization: Bearer $NUMI_API_KEY"
```

`GET /v1/me` returns the plan of the key's account (`plan`), the limits of that plan (`limits`) and the number of requests on the account today, this one included (`requests_today`).

The account page shows a new key only once, because only a hash of the key is stored. If you lose a key, revoke it. Then make a new key. An account can have as many active keys at once as its [plan](https://docs.numi.sh/plans.md) allows.

## Errors

Every error response has this form:

```json theme={null}
{
  "error": {
    "code": "unauthorized",
    "message": "The request has no API key. Send a numi API key in the X-API-Key header."
  },
  "meta": { "request_id": "req_Q2p8fWm3Xh0aLk7v" }
}
```

The `request_id` is also in the `x-request-id` header.

| Status | `code` | When |
| - | - | - |
| 400 | `bad_request` | A parameter is missing or wrong. The message says which one. |
| 401 | `unauthorized` | The request has no API key. |
| 401 | `invalid_key` | The key is wrong, or it was revoked. |
| 403 | `plan_required` | The plan of the account does not include the endpoint: on-demand extraction on the sandbox plan. |
| 403 | `sandbox_restricted` | The request is for a company outside the sandbox, and its key is on the sandbox plan. See [the sandbox](https://docs.numi.sh/plans.md#the-sandbox). |
| 404 | `not_found` | No company, filing or axis matches the request. |
| 429 | `rate_limit_exceeded` | The account is at the request limit of its plan for the minute or the day, or the IP address is at its limit for the minute. |
| 500 | `internal_error` | The server failed. When you write to [hello@numi.sh](mailto:hello@numi.sh), quote the `request_id`. |

## Rate limits

Each plan has a limit of requests a minute and a limit of requests a day, listed on the [plans](https://docs.numi.sh/plans.md) page. REST requests and MCP tool calls count toward the same limits, and the daily count is reset at midnight UTC.

The response to a request within the limits has the `RateLimit-Remaining` header: the number of requests that the account has left today. The response to a request over a limit has status 429, code `rate_limit_exceeded`, a `Retry-After` header with the number of seconds to wait, and a `scope` field: `minute` for the limit a minute, `day` for the limit a day.

The API also accepts at most 600 requests a minute from one IP address on the REST API, and 600 a minute on the MCP server, whatever keys the requests have.

## Account routes

The `/v1/account` routes serve the account page of numi.sh. They take a session of the web app, not an API key.


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