> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokenchange.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a chat completion

> Stream a chat completion from a TokenChange model with POST /v1/chat/completions. Request fields, price options, the event stream format and token usage.

Streams a chat completion from one of the model's endpoints. The request and response follow the OpenAI chat completions format.

## Request

**Authorization** `string` *required*

`Bearer ask_...`, an [inference key](https://docs.tokenchange.io/guides/api-keys.md).

**model** `string` *required*

A model slug from the catalog, or `<model-slug>/ep/<endpoint>` to [pin one endpoint](https://docs.tokenchange.io/guides/models-and-endpoints.md#pin-a-request-to-one-endpoint).

**messages** `object[]` *required*

The conversation, in the OpenAI messages format.

**stream** `boolean` *required*

Must be `true`.

**max\_tokens** `integer`

Maximum tokens to generate. At least `1`.

**temperature** `number`

Sampling temperature, from `0` to `2`.

**stream\_options.include\_usage** `boolean` (default: false)

Set to `true` to receive token usage in the final chunk.

**prompt\_cache\_key** `string`

Requests with the same key are routed to the same endpoint so its prompt cache is reused. See [Prompt caching](https://docs.tokenchange.io/guides/routing.md#prompt-caching).

**provider** `object`

Price options. See [Price options](https://docs.tokenchange.io/guides/routing.md#price-options).

**properties**

**max\_price.prompt** `number | string`

Highest input price you accept, in USD per million tokens.

**max\_price.completion** `number | string`

Highest output price you accept, in USD per million tokens.

**sort** `string`

`"price"` to try the cheapest endpoints first.

Other OpenAI chat completion fields, such as `tools`, `tool_choice`, `response_format`, `top_p`, `stop` and `seed`, are passed to the endpoint unchanged. Support depends on the endpoint's [capabilities](https://docs.tokenchange.io/guides/models-and-endpoints.md#capabilities).

```bash curl theme={null}
curl https://inference.tokenchange.io/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKENCHANGE_API_KEY" \
  -d '{
    "model": "<model-slug>",
    "stream": true,
    "stream_options": { "include_usage": true },
    "messages": [
      { "role": "system", "content": "You are a concise assistant." },
      { "role": "user", "content": "What is the capital of France?" }
    ]
  }'
```

```python Python theme={null}
stream = client.chat.completions.create(
    model="<model-slug>",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "What is the capital of France?"},
    ],
    stream=True,
    stream_options={"include_usage": True},
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
    if chunk.usage:
        print("\n", chunk.usage)
```

```javascript JavaScript theme={null}
const stream = await client.chat.completions.create({
  model: "<model-slug>",
  messages: [
    { role: "system", content: "You are a concise assistant." },
    { role: "user", content: "What is the capital of France?" },
  ],
  stream: true,
  stream_options: { include_usage: true },
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  if (chunk.usage) console.log("\n", chunk.usage);
}
```

## Response

The response is a stream of server-sent events. Each event's `data` is a JSON chat completion chunk, and the stream ends with `data: [DONE]`.

**id** `string`

Identifier for the completion.

**object** `string`

`chat.completion.chunk`.

**model** `string`

The model you requested.

**choices** `object[]`

**properties**

**index** `integer`

Choice index.

**delta** `object`

The new content in this chunk, such as `role` and `content`.

**finish\_reason** `string | null`

Why generation stopped, in the last chunk of a choice.

**usage** `object | null`

Only sent when `stream_options.include_usage` is `true`, in the final chunk.

**properties**

**prompt\_tokens** `integer`

Prompt tokens, including cached tokens.

**completion\_tokens** `integer`

Generated tokens.

**total\_tokens** `integer`

Sum of prompt and completion tokens.

**prompt\_tokens\_details.cached\_tokens** `integer`

Prompt tokens served from the endpoint's prompt cache.

```text Stream theme={null}
data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1767225600,"model":"<model-slug>","choices":[{"index":0,"delta":{"role":"assistant","content":"The"},"finish_reason":null}]}

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1767225600,"model":"<model-slug>","choices":[{"index":0,"delta":{"content":" capital of France is Paris."},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-123","object":"chat.completion.chunk","created":1767225600,"model":"<model-slug>","choices":[],"usage":{"prompt_tokens":24,"completion_tokens":8,"total_tokens":32,"prompt_tokens_details":{"cached_tokens":0}}}

data: [DONE]
```

The values above are illustrative. Chunks come from the endpoint that served the request, so extra fields it sends, such as reasoning content, are passed through.

## Errors during a stream

Errors before the stream starts return an HTTP error status. See [Errors](https://docs.tokenchange.io/inference/errors.md).

If the endpoint fails after the stream has started, you receive an error event and then `data: [DONE]`:

```text theme={null}
data: {"error":{"message":"upstream stream interrupted","type":"server_error"}}
```

Output delivered before the error is billed.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.