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

# OpenAI Compatibility

> Text chat through the official OpenAI SDK

Elumenta provides OpenAI-compatible endpoints for text chat:

* `POST /v1/chat/completions` — create a response, including streaming responses;
* `GET /v1/models` — list available text models in OpenAI format.

<Warning>
  The exact base URL is `https://elumenta.ru/v1`. Do not append `/api` or `/chat/completions`: the OpenAI SDK appends the endpoint path itself.
</Warning>

## Access

Use the same `nb_...` API key that you use with `/api/v2`; you do not need a separate key. API access requires the **Advanced plan or higher** (`t2_advanced` or `vip`, level 3). Lower plans receive a `403` response explaining the required plan.

## Complete Python example

Install the official SDK:

```bash theme={null}
pip install openai
```

Copy the entire example and replace only the API key:

```python theme={null}
from openai import OpenAI

client = OpenAI(api_key="nb_...", base_url="https://elumenta.ru/v1")

response = client.chat.completions.create(
    model="gpt-5-nano",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain recursion in one sentence."},
    ],
)

print(response.choices[0].message.content)
billing = getattr(response, "elumenta", {}) or {}
print(f"Charged: {billing.get('tokens_spent', 'unknown')} tkn")
print(f"Balance: {billing.get('balance', 'unknown')} tkn")
```

The `system`, `user`, and `assistant` roles are supported, as are `temperature` and `max_tokens`. The final message must use the `user` role.

## Streaming

Pass `stream=True` to consume response chunks as they arrive:

```python theme={null}
stream = client.chat.completions.create(
    model="gpt-5-nano",
    messages=[{"role": "user", "content": "Name three planets."}],
    stream=True,
)

for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="")

    billing = getattr(chunk, "elumenta", {}) or {}
    if billing:
        print(f"\nCharged: {billing.get('tokens_spent', 'unknown')} tkn")
        print(f"Balance: {billing.get('balance', 'unknown')} tkn")
```

The `elumenta` object arrives in the final stream chunk. Its `tokens_spent` and `balance` fields are included only when their values are known, so read them with `.get()` as shown above. The object can be empty, for example when streaming reconciliation does not run for a web session.

## Call cost

Each synchronous response contains two adjacent objects:

* `usage` — exactly the three standard OpenAI fields: `prompt_tokens`, `completion_tokens`, and `total_tokens`;
* `elumenta.tokens_spent` — the tkn actually charged for this call after reconciliation with the provider's real usage, when known;
* `elumenta.balance` — the balance remaining after the charge, when known.

Either cost field may be absent, and `elumenta` may be an empty object when neither value is known. In streaming mode Elumenta cannot completely populate `usage`, because the completion event does not contain the input and output token counts. To keep the response shape consistent in both modes, cost fields are placed alongside `usage` in `elumenta`, rather than inside `usage`.

For synchronous HTTP responses, `X-RateLimit-Limit` contains the request limit and `X-Token-Balance` contains the token balance. Streaming responses do not include `X-Token-Balance`: headers are sent before the stream finishes, while the final charge is not yet known. Read the current balance from `elumenta.balance` in the final chunk instead.

## List models

```python theme={null}
models = client.models.list()
for model in models.data:
    print(model.id)
```

`GET /v1/models` follows the OpenAI format and therefore does not include pricing; this is how the OpenAI specification is structured. Elumenta prices are available from [`GET /api/v2/models`](/en/api-reference/models/list).

For images, video, audio, and other capabilities, use the [unified Elumenta API](/en/api-reference/generate/create).
