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

# Огляд AI API

> Інтеграція ІІ-моделей ER:LC Росія в сторонні програми, боти та сервіси через OpenAI-сумісний протокол

## Вступ

**ER:LC Russia AI API** підтримує описані в цьому розділі методи Chat Completions, отримання моделей і синтезу мовлення. Для чату використовуйте `chat.completions.create` в OpenAI SDK з `base_url` / `baseURL`, що дорівнює `https://api.erlcrussia.com/v1`. Розширення ER:LC Russia описано на сторінках методів; підтримка решти API OpenAI не передбачається.

> **OpenAI SDK**
>
> Запити чату використовують формат Chat Completions; потокові відповіді передаються як `chat.completion.chunk`. Підтримувані поля наведено в описі методу.

> **Міркування**
>
> Підтримка покрокового аналізу та глибоких міркувань для моделей із трансляцією думок у `reasoning_content`.

> **Контекст діалогу**
>
> `session_id` — розширення ER:LC Russia для продовження діалогу.

> **Зображення та файли**
>
> Прикріплення ігрових скріншотів, логів та документів у стандартному форматі `image_url` та `file`.

***

## Аутентифікація

Для виконання запитів передавайте ваш токен доступу в заголовку `Authorization`:

```http theme={null}
Authorization: Bearer YOUR_API_TOKEN
```

Також приймаються заголовки `erlcrussia-api-ai-key` і `erlcrussia-api-key`. Передавайте ключ лише в заголовку запиту.

## Помилки

Помилки надходять у форматі OpenAI, тому SDK показує справжнє повідомлення. У `code` — рядковий код OpenAI (`invalid_api_key`, `model_not_found`, `insufficient_quota`, `rate_limit_exceeded`) або `null`. Числовий код ER:LC Росія з таблиці [кодів помилок](https://apidocs.erlcrussia.com/uk/documentation/error-codes.md) надходить у `erlc_code`.

```json theme={null}
{
  "error": {
    "message": "You exceeded your current quota, please check your plan and billing details.",
    "type": "insufficient_quota",
    "param": null,
    "code": "insufficient_quota",
    "erlc_code": "5038"
  }
}
```

## Сумісність з OpenAI

* `/v1/chat/completions`, `/v1/models`, `/v1/audio/speech` і `/v1/audio/transcriptions` працюють через OpenAI SDK.
* `/v1/realtime` працює за протоколом OpenAI Realtime: текст і голос на вході, голос на виході, хід позначається вручну. Див. [голосовий режим](https://apidocs.erlcrussia.com/uk/openai-api/v1/realtime.md).
* Поля `temperature`, `top_p`, `max_tokens`, `max_completion_tokens`, `stop`, `n` і `response_format` приймаються, але не застосовуються.
* `usage` є у звичайній відповіді. У потоці він надходить, лише якщо передати `stream_options: {"include_usage": true}`: окремим чанком з порожнім `choices` перед `data: [DONE]`. Додатково в `usage` є `cost_credits` — списані AI-кредити.
* Помилки використовують типи OpenAI: `invalid_request_error`, `requests`, `insufficient_quota`, `server_error`. Коли закінчуються AI-кредити, надходить 429 з типом `insufficient_quota`, як в OpenAI.
* Кожна відповідь має власний `id` виду `chatcmpl-…`, як в OpenAI. Ідентифікатор діалогу передається окремо в `session_id`.
* Запит без `messages` або з порожнім масивом отримує 400 з `param: "messages"` і кодом `missing_required_parameter` або `empty_array`.
* Кожна відповідь містить заголовки `x-request-id`, `openai-processing-ms`, `x-ratelimit-limit-requests`, `x-ratelimit-remaining-requests` і `x-ratelimit-reset-requests`.
* Якщо генерація обірвалася, у потоці надходить подія `{"error": {...}}` у форматі OpenAI, а за нею `data: [DONE]`.

***

## Доступні моделі

\| Модель | Персонаж Опис | Режим Роздумів |
\|---|---|---|---|
\| **`niya-1`** | **Нія** | Основна модель для швидких відповідей, консультацій щодо правил та модерації | Опціонально (за замовчуванням вимкнено, включається через `thinking: true`) |
\| **`emmy-1`** | **Еммі** | Просунута модель для глибокого аналізу логів, складних конфліктів та коду **Завжди включений** (налаштовується рівень роздумів через `effort`) |
\| **`hubert-1`** | **Хуберт** | Кастомний персонаж спільноти, що відповідає характерному ігровому стилі | Вимкнено |

Для Хуберта фірмовий суржик вимкнено за замовчуванням: він відповідає мовою останнього повідомлення користувача. Передайте `"surzhyk": true` у тілі запиту до `/v1/chat/completions`, щоб увімкнути фірмовий стиль.

## Ролі повідомлень

У масиві `messages` підтримуються стандартні ролі діалогу:

* `system` - додаткова інструкція або контекст вашого проекту (наприклад, роль Discord-бота або завдання сервісу), що накладається поверх базових правил моделі;
* `user` - повідомлення від користувача;
* `assistant` - попередня відповідь моделі для збереження контексту розмови.

***

## Параметри роздуми

Управління ланцюжком міркувань залежить від обраної моделі:

* **Для Еммі (`emmy-1`):** режим без роздумів **не підтримується** — модель завжди аналізує завдання перед відповіддю. Глибина аналізу налаштовується параметром **`effort`** (`string`) або заголовком `X-Reasoning-Effort`:
* `low` - коротка перевірка фактів та правил;
* `medium` *(за замовчуванням)* - збалансований детальний аналіз;
* `high` - вичерпний покроковий розбір;
* `extra` / `max` - граничний рівень аналітики з перевіркою гіпотез.
* **Для Нії (`niya-1`):** за умовчанням роздуми вимкнені для максимальної швидкості. Включаються параметром `thinking: true` (або `variant: "on"` / заголовком `X-Reasoning: on`).
* **Для Хуберта (`hubert-1`):** ланцюжок роздумів не використовується.

***

## Приклади інтеграції

**Python**

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

client = OpenAI(
    base_url="https://api.erlcrussia.com/v1",
    api_key="YOUR_API_TOKEN",
)

response = client.chat.completions.create(
    model="niya-1",
    messages=[
        {"role": "system", "content": "Ты — официальный ассистент сервера ER:LC Россия."},
        {"role": "user", "content": "Какие команды доступны офицеру полиции?"},
    ],
    temperature=0.7,
)

print(response.choices[0].message.content)
```

**TypeScript**

```typescript theme={null}
import OpenAI from 'openai';

const openai = new OpenAI({
  baseURL: 'https://api.erlcrussia.com/v1',
  apiKey: 'YOUR_API_TOKEN',
});

async function main() {
  const stream = await openai.chat.completions.create({
    model: 'emmy-1',
    messages: [
      { role: 'system', content: 'Ты — Эмми, аналитик игрового процесса.' },
      { role: 'user', content: 'Проанализируй спорную ситуацию с погоней.' },
    ],
    stream: true,
  });

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta as any;
    if (delta?.reasoning_content) {
      process.stdout.write(`[Мышление]: ${delta.reasoning_content}`);
    }
    if (delta?.content) {
      process.stdout.write(delta.content);
    }
  }
}

main();
```

**JavaScript**

```javascript theme={null}
const OpenAI = require('openai');

const openai = new OpenAI({
  baseURL: 'https://api.erlcrussia.com/v1',
  apiKey: 'YOUR_API_TOKEN',
});

async function main() {
  const stream = await openai.chat.completions.create({
    model: 'emmy-1',
    messages: [
      { role: 'system', content: 'Ты — Эмми, аналитик игрового процесса.' },
      { role: 'user', content: 'Проанализируй спорную ситуацию с погоней.' },
    ],
    stream: true,
  });

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta;
    if (delta?.reasoning_content) {
      process.stdout.write(`[Мышление]: ${delta.reasoning_content}`);
    }
    if (delta?.content) {
      process.stdout.write(delta.content);
    }
  }
}

main();
```

**cURL**

```bash theme={null}
curl https://api.erlcrussia.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{
    "model": "niya-1",
    "messages": [
      {
        "role": "user",
        "content": "Привет! Расскажи о проекте ER:LC Россия"
      }
    ],
    "stream": false
  }'
```

**OpenCode**

```json theme={null}
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "erlcrussia": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "ERLC Russia AI",
      "options": {
        "baseURL": "https://api.erlcrussia.com/v1",
        "apiKey": "YOUR_API_TOKEN"
      },
      "models": {
        "emmy-1": {
          "name": "Emmy 1",
          "limit": {
            "context": 1048576,
            "output": 131072
          },
          "reasoning": true,
          "capabilities": {
            "reasoning": true
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video",
              "pdf"
            ],
            "output": [
              "text"
            ]
          },
          "variants": {
            "low": {
              "name": "Low",
              "reasoningEffort": "low"
            },
            "medium": {
              "name": "Medium",
              "reasoningEffort": "medium"
            },
            "high": {
              "name": "High",
              "reasoningEffort": "high"
            },
            "extra": {
              "name": "Extra",
              "reasoningEffort": "extra"
            },
            "max": {
              "name": "Max",
              "reasoningEffort": "max"
            }
          }
        },
        "niya-1": {
          "name": "Niya 1",
          "limit": {
            "context": 1000000,
            "output": 32000
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video"
            ],
            "output": [
              "text"
            ]
          },
          "variants": {
            "off": {
              "name": "Reasoning Off"
            },
            "on": {
              "name": "Reasoning On"
            }
          }
        },
        "hubert-1": {
          "name": "Hubert 1",
          "limit": {
            "context": 1000000,
            "output": 32000
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video"
            ],
            "output": [
              "text"
            ]
          }
        }
      }
    }
  }
}
```

Документація з налаштування: [OpenCode Documentation](https://opencode.ai/docs/ru/models/)

**Kilo Code**

```json theme={null}
{
  "$schema": "https://app.kilo.ai/config.json",
  "model": "openai-compatible/emmy-1",
  "provider": {
    "openai-compatible": {
      "options": {
        "baseURL": "https://api.erlcrussia.com/v1",
        "apiKey": "YOUR_API_TOKEN"
      },
      "models": {
        "emmy-1": {
          "name": "Emmy 1",
          "tool_call": true,
          "reasoning": true,
          "limit": {
            "context": 1048576,
            "output": 131072
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video",
              "pdf"
            ],
            "output": [
              "text"
            ]
          },
          "variants": {
            "low": {
              "reasoningEffort": "low"
            },
            "medium": {
              "reasoningEffort": "medium"
            },
            "high": {
              "reasoningEffort": "high"
            },
            "extra": {
              "reasoningEffort": "extra"
            },
            "max": {
              "reasoningEffort": "max"
            }
          }
        },
        "niya-1": {
          "name": "Niya 1",
          "tool_call": true,
          "limit": {
            "context": 1000000,
            "output": 32000
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video"
            ],
            "output": [
              "text"
            ]
          },
          "variants": {
            "off": {
              "reasoning": false
            },
            "on": {
              "reasoning": true
            }
          }
        },
        "hubert-1": {
          "name": "Hubert 1",
          "tool_call": true,
          "limit": {
            "context": 1000000,
            "output": 32000
          },
          "modalities": {
            "input": [
              "text",
              "image",
              "audio",
              "video"
            ],
            "output": [
              "text"
            ]
          }
        }
      }
    }
  }
}
```

Документація з налаштування: [Kilo Code Documentation](https://kilo.ai/docs/code-with-ai/agents/custom-models)

***

## Потоковий режим

Під час передачі `"stream": true` сервер повертає потік подій `text/event-stream`. Кожна подія містить стандартну структуру `chat.completion.chunk`:

```json theme={null}
data: {"id":"chatcmpl-9b2f6c1e4a7d4c0e9f1a2b3c","object":"chat.completion.chunk","created":1726838400,"model":"emmy-1","choices":[{"index":0,"delta":{"role":"assistant","reasoning":"Анализирую правила сервера...","reasoning_content":"Анализирую правила сервера..."},"finish_reason":null}]}

data: {"id":"chatcmpl-9b2f6c1e4a7d4c0e9f1a2b3c","object":"chat.completion.chunk","created":1726838400,"model":"emmy-1","choices":[{"index":0,"delta":{"content":"Приветствую!"},"finish_reason":null}]}

data: {"id":"chatcmpl-9b2f6c1e4a7d4c0e9f1a2b3c","object":"chat.completion.chunk","created":1726838400,"model":"emmy-1","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-9b2f6c1e4a7d4c0e9f1a2b3c","object":"chat.completion.chunk","created":1726838400,"model":"emmy-1","choices":[],"usage":{"prompt_tokens":812,"completion_tokens":96,"total_tokens":908}}

data: [DONE]
```

prompt\_tokens містить системний контекст сервісу та передану історію, а не лише повідомлення користувача. Навіть короткий запит може містити близько 7000 вхідних токенів і коштувати приблизно 1 кредит; це приклад спостереження, а не фіксована ціна чи мінімум. Фактична вартість залежить від моделі, кешу та відповіді: перевіряйте usage.cost\_credits. web\_search:true дозволяє пошук, але не гарантує виклик; кожен виконаний пошук оплачується окремо.

Повний секрет повертається лише під час створення або ротації. Списки AI-ключів, перейменування та видалення повертають маску. GET /keys розкриває лише ключ виклику; інші ключі, навіть власні, замасковані. teamId — ID прив’язаної команди або null.

Створення AI-ключа та обмін монет потребують сесії власника. Звичайний HTTP-ключ, навіть з повним доступом, не дозволяє ці операції. Довірені сервіси використовують адміністративні методи з майстер-ключем.


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