Как получить и передать ключ
Ключ, который сотрудник создаёт в настройках портала: от чьего имени он действует, как передать его в запросе, лимиты и коды отказов.
Личный ключ создаёт сам сотрудник в разделе «Настройки» → «API-ключи». В отличие от ключа, который выпускает администратор, он не привязан к папкам базы знаний: портал принимает его в пользовательской части и выполняет запросы от имени сотрудника, который ключ создал.
С чего начать
-
Администратор включает вам «Доступ к API» в форме редактирования.
-
Вы создаёте ключ в разделе «Настройки» → «API-ключи» и копируете его. Портал показывает ключ один раз, в момент создания.

Кнопка «Создать ключ» в форме создания ключа -
Отправляете первый запрос с заголовком
Authorization. Пример — в разделе «Как передать» ниже.
Где создать
Карточка «API-ключи» появляется в настройках, только если администратор включил вам «Доступ к API» в форме редактирования. Без этой галочки карточки нет и ключ создать нельзя.

Создание, отзыв и лимит в пять ключей описаны в разделе «Настройки». Одновременно действует не больше пяти ключей: шестой портал не выпустит, пока вы не отзовёте один из старых.
Администратор видит созданные вами ключи в списке ключей и может отозвать любой из них.
От чьего имени действует
Портал выполняет запросы от имени владельца ключа: те же задачи и те же чаты, что видит владелец в портале. Задача, созданная по ключу, появляется в списке задач владельца, чат — в его списке чатов.
Как передать
Запросы идут на адрес пользовательской части портала — тот же, по которому вы открываете
портал в браузере. Ключ передаётся в заголовке Authorization:
Authorization: Bearer sk_forge_...Заголовок обязателен в каждом запросе. Сессионные cookie для этих запросов не нужны.
Список задач
Список своих задач:
curl "https://portal.example.com/api/tasks" \
-H "Authorization: Bearer sk_forge_..."Ответ 200. В data — задачи владельца ключа, в pagination — параметры страницы:
{
"data": [
{
"id": "6c5a1d1e-2b4f-4d9a-9f7c-8a1b2c3d4e5f",
"taskTypeId": "1f0a3c9d-7b2e-4a56-80c1-d2e3f4a5b6c7",
"userId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"title": "Сводка по продажам за сентябрь",
"status": "done",
"visibility": "private",
"currentStep": 3,
"totalSteps": 3,
"durationMs": 45210,
"createdAt": "2026-09-28T09:12:00.000Z",
"startedAt": "2026-09-28T09:12:04.000Z",
"finishedAt": "2026-09-28T09:12:49.000Z",
"scheduledTaskId": null,
"taskTypeVersion": 12,
"userParams": { "period": "2026-09" },
"injectionFlags": null,
"scheduledFor": null,
"taskType": {
"name": "Сводка по продажам",
"slug": "sales-summary",
"icon": "chart",
"version": 12,
"updatedAt": "2026-08-30T07:41:12.000Z"
}
},
{
"id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
"taskTypeId": "2a1b3c9d-8b2e-4a56-90c1-e2f3a4b5c6d7",
"userId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"title": "Коммерческое предложение для ООО «Вектор»",
"status": "pending",
"visibility": "private",
"currentStep": 0,
"totalSteps": 4,
"durationMs": null,
"createdAt": "2026-09-28T10:05:00.000Z",
"startedAt": null,
"finishedAt": null,
"scheduledTaskId": null,
"taskTypeVersion": 5,
"userParams": { "client": "ООО «Вектор»" },
"injectionFlags": null,
"scheduledFor": null,
"taskType": {
"name": "Коммерческое предложение",
"slug": "commercial-proposal",
"icon": "file-text",
"version": 5,
"updatedAt": "2026-09-01T11:20:00.000Z"
},
"queuePosition": 2
}
],
"pagination": {
"page": 1,
"pageSize": 20,
"total": 2,
"totalPages": 1
}
}Поля, которые нужны для работы:
| Поле | Что это |
|---|---|
id | Идентификатор задачи. Подставляется в остальные запросы |
title | Название задачи |
status | Статус: pending, processing, done, partial, failed, cancelled, cancel_requested |
taskType.slug | Тип задачи. По нему видно, что это за задача |
currentStep, totalSteps | Прогресс по шагам. У задачи в обработке currentStep меньше totalSteps |
queuePosition | Место в очереди. Есть только у задач в статусе pending |
createdAt, finishedAt | Когда задача создана и когда завершилась |
pagination | page, pageSize, total, totalPages — для постраничной навигации |
Страницы задаются параметрами page (с единицы) и pageSize (по умолчанию 20, потолок 100).
Тот же запрос на Python
import requests
BASE = "https://portal.example.com"
KEY = "sk_forge_..."
response = requests.get(
f"{BASE}/api/tasks",
headers={"Authorization": f"Bearer {KEY}"},
timeout=30,
)
response.raise_for_status()
for task in response.json()["data"]:
print(task["id"], task["status"], task["title"])Чего ключ не открывает
Личный ключ принимают только маршруты задач и чатов. Остальная часть портала отвечает отказом:
- запросы к папкам базы знаний — код
401, сообщениеThis API key cannot be used here. Для папок есть отдельный ключ, который выпускает администратор, «Ключи для внешних систем»; - остальные запросы администраторской части — код
401, сообщениеТребуется авторизация: они принимают только сессию администратора из браузера.
Лимиты
На владельца ключа действуют два независимых лимита: 300 запросов в минуту на задачи и
300 запросов в минуту на чаты. Счётчики не пересекаются: запросы к задачам не уменьшают
лимит чатов и наоборот. Превышение — код 429, см. раздел «Отказы».
На чат-маршруты наложен ещё лимит по IP-адресу. Он общий для всех, кто ходит с этого адреса, и по ключу, и из браузера:
| Запрос | Лимит |
|---|---|
POST /api/chat-sessions — создать чат | 20 в час |
GET /api/chat-sessions — список чатов | 600 в час |
POST /api/chat-sessions/:id/messages — отправить сообщение | 60 в час |
Отказы
Все отказы приходят в одном виде: поле error с кодом code и текстом message.
| Что произошло | Код | error.code | error.message |
|---|---|---|---|
| Ключ не найден | 401 | UNAUTHORIZED | Invalid API key |
| Ключ отозван | 401 | UNAUTHORIZED | API key has been revoked |
| Ключ истёк | 401 | UNAUTHORIZED | API key has expired |
| Запись владельца отключена | 401 | UNAUTHORIZED | User is not active |
| Ключ не личный, а выпущен администратором для папок | 403 | FORBIDDEN | This API key cannot act on behalf of a user |
| Владелец — администратор | 403 | FORBIDDEN | API keys are not available for admin accounts |
| «Доступ к API» выключен | 403 | FORBIDDEN | API access is disabled for this account |
| Превышен лимит | 429 | RATE_LIMITED | Слишком много попыток. Повторите через N минут. |
Тела отказов
Каждый отказ приходит целиком в этом виде. Показаны все восемь, в порядке таблицы.
Ключ не найден, 401:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid API key"
}
}Ключ отозван, 401:
{
"error": {
"code": "UNAUTHORIZED",
"message": "API key has been revoked"
}
}Ключ истёк, 401:
{
"error": {
"code": "UNAUTHORIZED",
"message": "API key has expired"
}
}Запись владельца отключена, 401:
{
"error": {
"code": "UNAUTHORIZED",
"message": "User is not active"
}
}Ключ не личный, 403:
{
"error": {
"code": "FORBIDDEN",
"message": "This API key cannot act on behalf of a user"
}
}Владелец — администратор, 403:
{
"error": {
"code": "FORBIDDEN",
"message": "API keys are not available for admin accounts"
}
}«Доступ к API» выключен, 403:
{
"error": {
"code": "FORBIDDEN",
"message": "API access is disabled for this account"
}
}Превышен лимит, 429:
{
"error": {
"code": "RATE_LIMITED",
"message": "Слишком много попыток. Повторите через 1 минут."
}
}Как ждать после 429
Заголовка Retry-After в ответе нет. Время ожидания стоит в тексте error.message.
Сообщение об ошибке — одно из трёх, все с кодом RATE_LIMITED:
| Сообщение | Когда | Единица |
|---|---|---|
Слишком много попыток. Повторите через N минут. | Лимит запросов в минуту или почасовой лимит чатов | минуты |
Подождите N сек. перед повторным запуском этой задачи. | Повторный запуск того же типа задачи раньше, чем через 60 секунд | секунды |
Превышен лимит задач (N в час). Попробуйте через M мин. | Лимит задач в час | минуты |
Текст сообщений — серверный, цитируем его как есть. «1 минут» — не опечатка.
Число перед «минут» или «мин.» — минуты, число перед «сек.» — секунды. Если число извлечь не удалось, ждите 60 секунд.
Дальше: задачи и чаты — полные списки запросов, которые принимает личный ключ.