# Authentication

> Send an API key as a bearer token. Inference keys run requests, management keys administer inference keys, and each route accepts one kind.

Source: https://0.0.0.0:3000/docs/api-reference/authentication
Documentation index: https://0.0.0.0:3000/docs/llms.txt

Every request to `https://api.numes.ai/api/v1` carries an API key in the `Authorization` header. Create and manage keys in [API keys](/docs/account/api-keys); this page is the wire contract.

## Send the key

```http
Authorization: Bearer sk-...
```

- The scheme is exactly `Bearer`, case-sensitive, followed by one space and the key.
- The key has no surrounding or embedded whitespace.
- Keys are accepted only in the `Authorization` header, never in a query string or body.

A header that breaks these rules is treated as a missing key.

The OpenAI SDKs send the header for you from the `api_key` option:

:::code-group
```python title="Python"
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.numes.ai/api/v1",
    api_key=os.environ["NUMES_API_KEY"],
)
```

```typescript title="TypeScript"
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.numes.ai/api/v1",
  apiKey: process.env.NUMES_API_KEY,
});
```
:::

To check a key, call [`GET /key`](/docs/api-reference/keys/get-current-key). It accepts either key kind and returns the key's metadata, limit and usage.

## Which key each route accepts

There are two key kinds. **Inference keys** run model requests and are billed in their currency. **Management keys** create and administer inference keys; see [Management keys](/docs/account/management-keys).

| Route | Accepted key |
| --- | --- |
| `GET /models`, `GET /models/{author}/{slug}/endpoints` | Inference |
| `POST /chat/completions`, `GET /generation` | Inference |
| `POST /embeddings`, `POST /images`, `POST /audio/speech`, `POST /audio/transcriptions` | Inference |
| `POST /e2ee/resolve`, `POST /e2ee/chat/completions` | Inference |
| `GET /key` | Inference or management |
| `GET /keys`, `POST /keys`, `GET /keys/{hash}`, `PATCH /keys/{hash}`, `DELETE /keys/{hash}`, `GET /credits` | Management |

Sending the wrong kind is an authentication failure, not a permission error: a management key on `/chat/completions`, or an inference key on `/keys`, returns `401 invalid_credentials`.

Management routes address a key by its `hash`, the lowercase hex SHA-256 of the full key. [Key format](/docs/account/api-keys#key-format) explains the prefix, label and hash.

## Authentication failures

Every authentication failure returns the same response, whatever the reason:

```json
{
  "error": {
    "code": 401,
    "message": "invalid credentials",
    "metadata": { "error_type": "invalid_credentials" }
  }
}
```

A key fails when it's missing or malformed, unknown, the wrong kind for the route, expired, disabled or deleted, owned by an account that's no longer active, or an organization key whose creator has left the organization. Authorization is checked on every request, so disabling or deleting a key takes effect on the next request. [Why a key is rejected](/docs/account/api-keys#why-a-key-is-rejected) helps you find the cause.

| Status | `error_type` | Meaning | What to do |
| --- | --- | --- | --- |
| `401` | `invalid_credentials` | The key was refused | Check the key and the route's key kind |
| `429` | `rate_limited` | Too many failed authentications. Message: `too many authentication attempts` | Wait for the seconds in `Retry-After` |
| `503` | `authentication_unavailable` | Keys can't be verified | Retry with backoff |
| `503` | `rate_limit_unavailable` | The service is unavailable | Retry with backoff |

Keep keys on your server. Browser requests from third-party origins are rejected with `403 cors_forbidden`, so call the API from your own backend.

## Next steps

:::cards
- {key} [API keys](/docs/account/api-keys) Create, limit, rotate and revoke keys.
- {shield} [Management keys](/docs/account/management-keys) Provision inference keys from code.
- {alert} [Errors and debugging](/docs/api-reference/errors) Every status code and the retry strategy.
:::
