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

# Authentication

> One header on every request.

```
Authorization: Bearer nj_sk_YOUR_API_KEY
```

## Get a key

Create one at [Developers → Connections → Apps](https://www.ninjachat.ai/developers/connections?tab=apps). Keys start with `nj_sk_` and are shown **once** — copy immediately.

Browsing and estimates are free. Paid calls draw from your **Developer Balance** — top up at [Developers → Billing](https://www.ninjachat.ai/developers/billing), or verify your phone on your first paid action to unlock a \$0.50 starter balance.

## Use it

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://www.ninjachat.ai/api/v1/chat \
    -H "Authorization: Bearer $NINJACHAT_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model": "gpt-5", "messages": [{"role": "user", "content": "Hello"}]}'
  ```

  ```python Python theme={null}
  import os, requests

  r = requests.post("https://www.ninjachat.ai/api/v1/chat",
      headers={"Authorization": f"Bearer {os.environ['NINJACHAT_API_KEY']}"},
      json={"model": "gpt-5", "messages": [{"role": "user", "content": "Hello"}]}
  )
  ```

  ```javascript Node.js theme={null}
  const r = await fetch("https://www.ninjachat.ai/api/v1/chat", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.NINJACHAT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "gpt-5",
      messages: [{ role: "user", content: "Hello" }],
    }),
  });
  ```
</CodeGroup>

## Keep it secret

Environment variables, never hardcoded:

```bash theme={null}
export NINJACHAT_API_KEY="nj_sk_YOUR_API_KEY"   # or a .env file in .gitignore
```

And never in frontend code — CORS is open on `/api/v1/*`, but a key in the browser is a key stolen. Proxy through your backend:

```python theme={null}
@app.post("/api/chat")
def proxy(req):
    return requests.post("https://www.ninjachat.ai/api/v1/chat",
        headers=HEADERS,  # server-side only
        json={"model": "gpt-5", "messages": req.json["messages"]}
    ).json()
```

## Key management

* Up to **5 active keys** per account — use separate keys for dev / staging / prod
* Revoke instantly from [Developers → Connections → Apps](https://www.ninjachat.ai/developers/connections?tab=apps); revoked keys stop **immediately**
* The same key works for the [MCP server](/mcp/overview) — agents and code share one balance

## Auth errors

| Status | Error             | Fix                                              |
| ------ | ----------------- | ------------------------------------------------ |
| 401    | `missing_api_key` | Add the `Authorization: Bearer nj_sk_...` header |
| 401    | `invalid_api_key` | Key is malformed or revoked — create a new one   |
