---
title: Models
---

# Models

List the models CrossModel currently has available, or look up a single model.

## Endpoint

```http
GET https://api.crossmodel.ai/v1/models
GET https://api.crossmodel.ai/v1/models/{model}
Authorization: Bearer cm-YOUR_KEY
# Or: x-api-key: cm-YOUR_KEY
```

Both endpoints accept either OpenAI-style `Authorization: Bearer` authentication
or Anthropic-style `x-api-key` authentication. `anthropic-version` is accepted
but isn't required or validated for these endpoints.

**List models**

```bash
curl https://api.crossmodel.ai/v1/models \
  -H "Authorization: Bearer $CROSSMODEL_API_KEY"
```

```typescript
import OpenAI from "openai";

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

const models = await client.models.list();

for await (const model of models) {
  console.log(model.id);
}
```

```python
import os
from openai import OpenAI

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

models = client.models.list()

for model in models:
    print(model.id)
```

**Retrieve model**

```bash
curl https://api.crossmodel.ai/v1/models/deepseek%2Fdeepseek-v4-pro \
  -H "Authorization: Bearer $CROSSMODEL_API_KEY"
```

```typescript
import OpenAI from "openai";

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

const model = await client.models.retrieve("deepseek/deepseek-v4-pro");

console.log(model);
```

```python
import os
from openai import OpenAI

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

model = client.models.retrieve("deepseek/deepseek-v4-pro")

print(model)
```

## The model object

| Field | Type | Notes |
|------|------|------|
| `id` | string | Model ID in `vendor/short_name` form, e.g. `deepseek/deepseek-v4-pro`. For an alias, this is the alias name you defined. |
| `object` | string | Always `model`. |
| `type` | string | Always `model`. Anthropic-compatible equivalent of `object`. |
| `display_name` | string | Human-readable model name. |
| `created` | integer | Model release time, as a Unix timestamp (seconds). |
| `created_at` | string | Model release time in RFC 3339 format. |
| `owned_by` | string | The model's author, e.g. `deepseek`, `openai`, `anthropic`. |
| `context_length` | integer | Maximum context window, in tokens. Omitted when unknown. |
| `max_completion_tokens` | integer | Maximum output tokens. Omitted when unknown. |
| `architecture.input_modalities` | string[] | Accepted input modalities, e.g. `["text", "image"]`. |
| `architecture.output_modalities` | string[] | Produced output modalities, e.g. `["text"]`. |
| `capabilities` | object | Capability flags for the model. Omitted when none are set. |
| `root` | string | Only present for [model aliases](/docs/model-aliases): the real `vendor/short_name` the alias resolves to. |

## List models

`GET /v1/models`

Returns every model currently available.

```bash
curl https://api.crossmodel.ai/v1/models \
  -H "Authorization: Bearer cm-YOUR_KEY"
```

Anthropic-style authentication works on the same URL:

```bash
curl https://api.crossmodel.ai/v1/models \
  -H "x-api-key: cm-YOUR_KEY" \
  -H "anthropic-version: 2023-06-01"
```

```json
{
  "object": "list",
  "data": [
    {
      "id": "deepseek/deepseek-v4-pro",
      "object": "model",
      "type": "model",
      "display_name": "DeepSeek V4 Pro",
      "created": 1716239400,
      "created_at": "2024-05-20T22:30:00+00:00",
      "owned_by": "deepseek",
      "context_length": 65536,
      "max_completion_tokens": 8192,
      "architecture": { "input_modalities": ["text"], "output_modalities": ["text"] },
      "capabilities": { "tools": true }
    },
    {
      "id": "anthropic/claude-sonnet-4.6",
      "object": "model",
      "type": "model",
      "display_name": "Claude Sonnet 4.6",
      "created": 1716239401,
      "created_at": "2024-05-20T22:30:01+00:00",
      "owned_by": "anthropic",
      "context_length": 200000,
      "max_completion_tokens": 64000,
      "architecture": { "input_modalities": ["text", "image"], "output_modalities": ["text"] },
      "capabilities": { "tools": true }
    }
  ],
  "has_more": false,
  "first_id": "deepseek/deepseek-v4-pro",
  "last_id": "anthropic/claude-sonnet-4.6"
}
```

| Field | Type | Notes |
|------|------|------|
| `object` | string | Always `list`. |
| `data` | array | An array of model objects. |
| `has_more` | boolean | Currently always `false`; the complete catalog is returned. |
| `first_id` | string or null | ID of the first returned model, or `null` for an empty catalog. |
| `last_id` | string or null | ID of the last returned model, or `null` for an empty catalog. |

The response is a union of the OpenAI and Anthropic model schemas. Unknown
fields can be ignored. Pagination query parameters are accepted, but the
current implementation returns the complete catalog and doesn't paginate.

<Callout type="info">
  If you've configured [model aliases](/docs/model-aliases) on your API key, they appear **first** in `data`, each with a `root` field pointing at the real model it resolves to (carrying that model's capabilities). The full catalog follows, so real model IDs remain listed alongside your aliases.
</Callout>

## Retrieve a model

`GET /v1/models/{model}`

Get a single model. Use the full model ID for `{model}`; URL-encode the `/` as `%2F`.

```bash
curl https://api.crossmodel.ai/v1/models/deepseek%2Fdeepseek-v4-pro \
  -H "Authorization: Bearer cm-YOUR_KEY"
```

```json
{
  "id": "deepseek/deepseek-v4-pro",
  "object": "model",
  "type": "model",
  "display_name": "DeepSeek V4 Pro",
  "created": 1716239400,
  "created_at": "2024-05-20T22:30:00+00:00",
  "owned_by": "deepseek",
  "context_length": 65536,
  "max_completion_tokens": 8192,
  "architecture": { "input_modalities": ["text"], "output_modalities": ["text"] },
  "capabilities": { "tools": true }
}
```

You can also retrieve one of your own aliases by its name; the response includes a `root` field with the real model ID it resolves to.

For a prefix alias, querying a concrete matching name returns that concrete name
as `id` and the configured target as `root`. For example, if the prefix
`claude-opus` points to `anthropic/claude-opus-4-8`:

```json
{
  "id": "claude-opus-4-9",
  "object": "model",
  "root": "anthropic/claude-opus-4-8",
  "context_length": 1000000,
  "max_completion_tokens": 128000
}
```

If the model doesn't exist, the endpoint returns `404` with the code `model_not_found`.

## Errors

Bearer-authenticated requests use the OpenAI-compatible error format:

```json
{
  "error": {
    "message": "Model 'foo/bar' was not found or is unavailable.",
    "type": "invalid_request_error",
    "param": null,
    "code": "model_not_found"
  }
}
```

Requests carrying a non-empty `x-api-key` use the Anthropic-compatible error
format:

```json
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "Model 'foo/bar' was not found or is unavailable."
  },
  "request_id": "req_..."
}
```

| HTTP status | `type` | Common `code` | Notes |
|------------|--------|-------------|------|
| `401` | `authentication_error` | `missing_api_key`, `invalid_api_key` | API key missing or invalid. |
| `404` | `invalid_request_error` | `model_not_found` | The requested model doesn't exist or is currently unavailable. |
| `500` | `api_error` | `internal_error` | A CrossModel internal error. |
