---
title: Authentication & API keys
description: Creating CrossModel API keys, header formats, and safe-use guidance.
---

# Authentication & API keys

CrossModel authenticates with API keys. Keys start with `cm-` and are shown only once, at creation — save it to a secure server-side location right away.

<Callout type="warning">
  Never put an API key in web frontend code, a mobile bundle, a public repo, or your logs. Anyone who gets the key can spend your account balance.
</Callout>

## Creating a key

Sign in to the console and create an API key on the **API Keys** page. A key works for every enabled model — you don't need a separate key per provider.

If a key leaks or is no longer needed, disable or delete it in the console. The gateway checks key status and rejects any key that isn't active.

## OpenAI-compatible endpoints

OpenAI-compatible endpoints use the `Authorization: Bearer` header:

```http
Authorization: Bearer cm-YOUR_KEY
```

```bash
curl https://api.crossmodel.ai/v1/chat/completions \
  -H "Authorization: Bearer $CROSSMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4-pro",
    "messages": [{ "role": "user", "content": "Hello" }]
  }'
```

## Anthropic-compatible endpoints

The Anthropic Messages endpoint prefers the `x-api-key` header, and also accepts `Authorization: Bearer`:

```http
x-api-key: cm-YOUR_KEY
anthropic-version: 2023-06-01
```

```bash
curl https://api.crossmodel.ai/v1/messages \
  -H "x-api-key: $CROSSMODEL_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4.6",
    "max_tokens": 1024,
    "messages": [{ "role": "user", "content": "Hello" }]
  }'
```

## Environment variables

Use an environment variable on the server:

```bash
export CROSSMODEL_API_KEY="cm-YOUR_KEY"
```

Python:

```python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["CROSSMODEL_API_KEY"],
    base_url="https://api.crossmodel.ai/v1",
)
```

TypeScript:

```ts
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.CROSSMODEL_API_KEY,
  baseURL: "https://api.crossmodel.ai/v1",
});
```

## Authentication errors

| Situation | HTTP status | `type` | `code` |
|------|------------|--------|--------|
| No API key provided | `401` | `authentication_error` | `missing_api_key` |
| Key doesn't exist or signature mismatch | `401` | `authentication_error` | `invalid_api_key` |
| Key disabled or revoked | `401` | `authentication_error` | `api_key_inactive` |
| Account disabled | `401` | `authentication_error` | `user_inactive` |

<Callout type="info">
  If you suspect a key has leaked, disable or delete it in the console immediately and create a new one.
</Callout>
