---
title: "API reference: endpoints and headers — AI Creator API"
description: "AI Creator API endpoints: Messages, Responses, Chat Completions, token counting and models, plus streaming and headers."
url: https://llm.aicreator.app/en/docs/api/
lang: en
updated: 2026-11-10
---

# API reference

The API lives at `https://api.aicreator.app`. Request and response bodies are those of the official Anthropic and OpenAI APIs, so their docs hold for us too. The request body goes to the provider as is; only the model name changes when it is an alias.

For Russia the same API has a second address, `https://api-ru.aicreator.app`: keys, paths and the balance are shared.

## Endpoints

| Request                          | Protocol                | Used by                            |
| -------------------------------- | ----------------------- | ---------------------------------- |
| `POST /v1/messages`              | Anthropic Messages      | Claude Code, Anthropic SDK         |
| `POST /v1/messages/count_tokens` | Anthropic Messages      | Claude Code, Anthropic SDK         |
| `POST /v1/responses`             | OpenAI Responses        | Codex CLI, OpenAI SDK              |
| `POST /v1/chat/completions`      | OpenAI Chat Completions | Cline, OpenCode, Aider, OpenAI SDK |
| `GET /v1/models`                 | Anthropic and OpenAI    | any client                         |

Not every model is on every protocol; which ones are is on the [pricing page](https://llm.aicreator.app/en/pricing/). A request for a model on a protocol it lacks returns 400 `model_not_available`: we don’t translate one protocol into another.

A request body can be up to 32 MB. One request lasts 30 minutes at most.

## The key

Either header works:

- `Authorization: Bearer sk-aic-…`
- `x-api-key: sk-aic-…`

If both arrive with different values, `x-api-key` wins. A dashboard sign-in, a login or a cookie, doesn’t work here: it has to be a key.

## Models

`GET /v1/models` returns one list in a shape both Anthropic and OpenAI clients read: `{"object": "list", "data": [{"id": …, "display_name": …, "context_window": …}]}`. A key restricted to some models sees only those.

Which protocol you mean comes from a request header or from the `?surface=` parameter; the parameter wins over the header:

| Header              | Parameter            | What is listed                    |
| ------------------- | -------------------- | --------------------------------- |
| `anthropic-version` | `?surface=anthropic` | models on Anthropic Messages      |
| `OpenAI-Beta`       | `?surface=responses` | models on OpenAI Responses        |
| —                   | `?surface=chat`      | models on OpenAI Chat Completions |

With neither, the list holds the models that are on both Chat Completions and Responses: any OpenAI client can call them. Any other value of `surface` is 400 `invalid_surface`.

```bash
curl "https://api.aicreator.app/v1/models?surface=responses" \
  -H "Authorization: Bearer $AIC_API_KEY"
```

## Token counting

`POST /v1/messages/count_tokens` counts the tokens of a Messages request and generates nothing. It is free and stays out of the stats, but it spends the key’s per-minute request and token limits like any other call.

```bash
curl https://api.aicreator.app/v1/messages/count_tokens \
  -H "x-api-key: $AIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model": "claude-sonnet-5-5", "messages": [{"role": "user", "content": "Hello"}]}'
```

## Streaming

With `"stream": true` the answer comes as SSE. We pass the provider’s stream through byte for byte, the same events in the same order, so Claude Code and Codex treat it just like the official API.

If the model is silent for more than 15 seconds, for example while thinking, we send a keepalive: `event: ping` on Anthropic, an SSE comment `: ping` on OpenAI. The client doesn’t drop the connection on a timeout.

In a Chat Completions stream we always turn on `stream_options.include_usage`: the last chunk has an empty `choices: []` and the token usage.

### Long answers: stream them

A request without streaming waits for the whole answer in silence. If the model takes more than about two minutes, Cloudflare in front of our API closes the connection with code 524 while the model is still working. A stream with keepalives passes that limit: for long answers and long thinking turn on `"stream": true`.

## Headers

### Request

- `anthropic-version`, `anthropic-beta` and `openai-beta` go to the provider as is, so Claude Code betas work.

### Response

- `X-Billing-Id` — the request’s billing id. It finds a request that reached the provider in the usage export (the `request_id` field).
- `retry-after` and `x-should-retry` say when and whether to retry. We set them on our own errors (except 401 and the refusals without JSON) and pass them on from the provider.
- `anthropic-ratelimit-*` and `x-ratelimit-*` are not returned: at the provider they describe our account, not your key. The key’s limits are in [Errors and limits](https://llm.aicreator.app/en/docs/errors/).

## Examples

### Anthropic Messages

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

### OpenAI Responses

```bash
curl https://api.aicreator.app/v1/responses \
  -H "Authorization: Bearer $AIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-6-astra", "input": "Hello"}'
```

### OpenAI Chat Completions

```bash
curl https://api.aicreator.app/v1/chat/completions \
  -H "Authorization: Bearer $AIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-6-astra", "messages": [{"role": "user", "content": "Hello"}]}'
```

### Models

```bash
curl https://api.aicreator.app/v1/models \
  -H "Authorization: Bearer $AIC_API_KEY"
```
