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

# Authentication

> Auth header formats and examples for the three protocol endpoints

All OpenPAI APIs require authentication. Auth information is carried in the **request headers**, not in the URL query.

## OpenAI-compatible protocol

```
Authorization: Bearer sk-XXXXXXXXXXXXXXXX
```

```bash theme={null}
curl https://openp.ai/v1/chat/completions \
  -H "Authorization: Bearer $OPENPAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"hi"}]}'
```

## Claude Messages protocol

```
x-api-key: sk-XXXXXXXXXXXXXXXX
anthropic-version: 2023-06-01
```

```bash theme={null}
curl https://openp.ai/v1/messages \
  -H "x-api-key: $OPENPAI_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model":"claude-opus-4-8",
    "max_tokens":1024,
    "messages":[{"role":"user","content":"hi"}]
  }'
```

<Note>SDKs usually add `anthropic-version` automatically, so you don't need to set it manually when using an SDK.</Note>

## Gemini native protocol

```
x-goog-api-key: sk-XXXXXXXXXXXXXXXX
```

```bash theme={null}
curl "https://openp.ai/v1beta/models/gemini-3.1-pro-preview:generateContent" \
  -H "x-goog-api-key: $OPENPAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents":[{"role":"user","parts":[{"text":"hi"}]}]
  }'
```

Gemini also supports query-parameter auth (`?key=sk-...`), but this is **not recommended** — the URL gets logged by proxies.

## Failure examples

| Status                   | Cause                                                          |
| ------------------------ | -------------------------------------------------------------- |
| `401 invalid_api_key`    | Key doesn't exist / disabled / wrong format / trailing newline |
| `401 expired_api_key`    | The token has expired                                          |
| `403 insufficient_quota` | Account or token quota insufficient                            |
| `403 ip_not_allowed`     | The source IP isn't in the token's allowlist                   |
| `403 model_not_allowed`  | The token lacks permission to call this model                  |

How to troubleshoot:

1. Copy the `X-OpenPAI-Request-Id` header.
2. Console → **Logs** → search for that Request ID to see the detailed failure reason.

## Key safekeeping

* **Do not** commit keys to Git or paste them into chats / issues.
* Inject them via environment variables / a secret manager.
* If you suspect a leak, disable and regenerate immediately in the console.
* Create separate tokens per app / environment for fine-grained tracking.
