# Authentication

One DirectInference key authenticates every surface. Only the header convention differs, matching what each SDK already sends.

## API keys

Authenticate with a key you issue on the [API Keys](https://app.directinference.com/api-keys) page. The same `llm_live_…` key works across the OpenAI, Anthropic, and Gemini surfaces — there are no per-surface credentials.

| Surface | Credential header(s) |
| --- | --- |
| OpenAI-compatible | `Authorization: Bearer <key>` |
| Anthropic Messages | `x-api-key: <key>`<br />`anthropic-version: 2023-06-01` |
| Gemini | `x-goog-api-key: <key>`<br />`?key=<key>`<br />`Authorization: Bearer <key>` |

## OpenAI-compatible

Pass the key as `api_key`; the SDK sends it as a bearer token.

```python
from openai import OpenAI

client = OpenAI(
    api_key="llm_live_...",                       # sent as: Authorization: Bearer ...
    base_url="https://app.directinference.com/di/v1",
)
```

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "llm_live_...",                         // sent as: Authorization: Bearer ...
  baseURL: "https://app.directinference.com/di/v1",
});
```

```bash
curl https://app.directinference.com/di/v1/chat/completions \
  -H "Authorization: Bearer llm_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "model": "gpt-5.5-mini", "messages": [{ "role": "user", "content": "ping" }] }'
```

```go
client := openai.NewClient(
	option.WithAPIKey("llm_live_..."),            // sent as: Authorization: Bearer ...
	option.WithBaseURL("https://app.directinference.com/di/v1"),
)
```

## Anthropic Messages

The Anthropic SDK sends `x-api-key` plus an `anthropic-version` header. Set the SDK base URL to `…/di` (it appends `/v1/messages` for you).

```bash
curl https://app.directinference.com/di/v1/messages \
  -H "x-api-key: llm_live_..." \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-6",
    "max_tokens": 64,
    "messages": [{ "role": "user", "content": "ping" }]
  }'
```

## Gemini

Three credential forms are accepted, resolved in this order: `x-goog-api-key`, then the `?key=` query parameter, then `Authorization: Bearer`. The Google GenAI SDKs use the first.

```bash
# x-goog-api-key is what the Google GenAI SDKs send
curl "https://app.directinference.com/di/v1beta/models/gemini-2.5-flash:generateContent" \
  -H "x-goog-api-key: llm_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "contents": [{ "parts": [{ "text": "ping" }] }] }'

# also accepted: ?key=llm_live_...   and   Authorization: Bearer llm_live_...
```

:::note[Missing or invalid keys]
A bad or absent credential returns `401` in the error envelope of the surface you called. See [Errors & limits](https://docs.directinference.com/errors/) for the exact shapes.
:::