---
title: Chat completions API
description: Call chat models with POST /v1/chat/completions in the OpenAI Chat Completions format. Stream replies, billed per input and output token.
---

Send `POST /v1/chat/completions` with your [API key](/docs/authentication). Requests and responses use the OpenAI Chat Completions format. List the available models with `GET /v1/models` and pass a chat model's ID as `model`.

```bash
curl --fail --show-error https://api.sawtakarabi.ai/v1/chat/completions \
  -H "Authorization: Bearer $SAWTAK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<MODEL_ID>",
    "messages": [{"role": "user", "content": "مرحباً"}]
  }'
```

The OpenAI SDKs work when you set the base URL:

```python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://api.sawtakarabi.ai/v1",
    api_key=os.environ["SAWTAK_API_KEY"],
)
reply = client.chat.completions.create(
    model="<MODEL_ID>",
    messages=[{"role": "user", "content": "مرحباً"}],
)
print(reply.choices[0].message.content)
```

## Streaming

Set `"stream": true` to receive the reply as server-sent events. The stream ends with `data: [DONE]`.

Add `"stream_options": {"include_usage": true}` to receive a final chunk with `usage` and an empty `choices` list.

## Billing

Each request is charged for its input and output tokens at the model's prices per 1M tokens, rounded up to the nearest micro-dollar.

- A request is charged only once the reply, or any part of a stream, reaches you.
- If you stop a stream early, you pay for the tokens generated up to that point.
- If the model rejects your input as invalid (a `4xx` error), the request isn't charged.

If `max_tokens` or `max_completion_tokens` is larger than your balance covers at the model's output price, it is lowered to what your balance covers.

## Limits

Each request has a 10-minute deadline and a request body of up to 4 MiB. Requests are subject to your account's [concurrency limit](/docs/limits).

## Errors

| Status | `error.code`           | What to do                                                      |
| ------ | ---------------------- | --------------------------------------------------------------- |
| `400`  | `model_kind_mismatch`  | The model isn't a chat model. Choose one from `GET /v1/models`. |
| `402`  | `insufficient_balance` | Add credit in [Billing](/dashboard/billing).                    |
| `404`  | `model_not_found`      | Check the model ID.                                             |
| `429`  | `concurrency_limited`  | Wait for one of your requests to finish, then retry.            |
| `429`  | `capacity_full`        | Retry with backoff.                                             |
| `502`  | `backend_error`        | The model couldn't complete the request. Retry with backoff.    |
| `503`  | `no_backend`           | Capacity is starting. Retry shortly.                            |

See [Errors](/docs/errors) for the error format.
