# Authentication

> Send your router.africa API key as a Bearer token. Key format, handling and the errors you can get.

Source: https://router.africa/docs/authentication

Every request to `https://api.router.africa/v1` needs an API key. Send it in the `Authorization` header as a Bearer token. This is the same form the OpenAI SDK uses, so the SDK only needs a new base URL and key.

**curl**

```bash
curl https://api.router.africa/v1/models \
  -H "Authorization: Bearer $ROUTER_AFRICA_API_KEY"
```

**Python**

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.router.africa/v1",
    api_key=os.environ["ROUTER_AFRICA_API_KEY"],  # sent as Authorization: Bearer
)

print([m.id for m in client.models.list()])
```

**TypeScript**

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.router.africa/v1",
  apiKey: process.env.ROUTER_AFRICA_API_KEY, // sent as Authorization: Bearer
});

const models = await client.models.list();
console.log(models.data.map((m) => m.id));
```

## Key format

- Keys start with `sk-ra-`.
- A key is shown once, when you create it. router.africa stores only a hash, so it can't show it again. Create a new key if you lose one.
- Create, rotate and revoke keys in the dashboard under **API keys**.

## Rules

- `Authorization: Bearer <key>` is accepted on every endpoint. The word `Bearer` is not case-sensitive.
- `POST /v1/messages` also accepts `x-api-key: <key>`, so the Anthropic SDK works with its default `api_key`. No other endpoint accepts `x-api-key`.
- Don't send a key in the URL or the request body. The request fails with `400` and the reason `key_not_in_header`. If you did this, rotate the key.
- Use HTTPS only.
- Keep keys on your server. Never put one in a browser app, a mobile app or a public repository.
- The `OpenAI-Organization`, `OpenAI-Project` and `OpenAI-Beta` headers are accepted and ignored, so SDK settings for them do no harm.

## Authentication errors

| Status | `reason` | Meaning |
|---|---|---|
| `401` | `missing_api_key` | No `Authorization` header, or it isn't a Bearer token. On `POST /v1/messages`, no `x-api-key` either. |
| `401` | `invalid_api_key` | The key is unknown, malformed, revoked, expired or not yet active. You get the same answer for all of these. |
| `403` | `account_suspended` | The account or workspace is suspended. Contact support. |

Every `401` carries `WWW-Authenticate: Bearer realm="router.africa"`. See [Errors](https://router.africa/docs/errors) for the response body. On `POST /v1/messages` the body is in Anthropic's format.

You can limit what a key can do. See [Spend caps and key scoping](https://router.africa/docs/spend-caps-and-key-scoping).
