# Authentication

One API key per request, as a bearer token or as Anthropic's x-api-key header.

## Send the key

Send your API key with every request, in either of two headers. Both work on every route; if a request has both, `Authorization` wins.

| Header | Sent by |
| --- | --- |
| `Authorization: Bearer <your API key>` | curl, and the OpenAI and OpenRouter SDKs. `Bearer` takes a capital B. |
| `x-api-key: <your API key>` | Anthropic's SDKs and Claude Code |

```bash
# Anthropic's SDKs send the key as x-api-key; the API reads it when there is no Authorization header
curl https://api.vultrinference.com/v1/messages \
  -H "x-api-key: $VULTR_INFERENCE_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model": "deepseek-v4.1-flash", "max_tokens": 256, "messages": [{"role": "user", "content": "Say hello."}]}'
```

Keys are matched exactly, case and all. Create and revoke them in the [Vultr console](https://console.vultr.com/inference/).

## What a wrong key gets

A request with no key, a key that does not exist, or one that is suspended or closed gets a 401:

```json
{
  "error": {
    "code": 401,
    "message": "Invalid API key",
    "type": "auth_error",
    "metadata": {
      "error_type": "authentication"
    }
  }
}
```

With no key at all, the message is "No API key provided". On `/v1/messages` the same failure comes in Anthropic's shape, as an `authentication_error`. A 401 is never worth retrying with the same key.

## Routes that need no key

These answer without a key, and ignore one that is sent, so a wrong key is no error there:

- [`GET /v1/models`](/docs/reference/list-models.md): List Models
- [`GET /v1/models/count`](/docs/reference/count-models.md): Count Models
- [`GET /v1/model/{author}/{slug}`](/docs/reference/get-model-by-author-and-slug.md): Get Model By Author And Slug
- [`GET /v1/embeddings/models`](/docs/reference/list-embedding-models.md): List Embedding Models

Every other route needs a key, including `GET /v1/models/{id}` and `GET /v1/health`.

## Keep it secret

- Keep the key on your servers. A key in a web page or a mobile app can be read by anyone who has it, and spends from your account.
- Your usage, files, vector stores, rate limits and webhook secret belong to your subscription: every key of it sees the same ones.
- A webhook receiver needs no API key at all: deliveries are signed with a separate [webhook secret](/docs/concepts/webhooks), so the server that receives them never holds a key that can spend.
