Vortholm — документация
Личный ключ

Как получить и передать ключ

Ключ, который сотрудник создаёт в настройках портала: от чьего имени он действует, как передать его в запросе, лимиты и коды отказов.

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

С чего начать

  1. Администратор включает вам «Доступ к API» в форме редактирования.

  2. Вы создаёте ключ в разделе «Настройки» → «API-ключи» и копируете его. Портал показывает ключ один раз, в момент создания.

    Кнопка «Создать ключ» в форме создания ключа
    Кнопка «Создать ключ» в форме создания ключа
  3. Отправляете первый запрос с заголовком Authorization. Пример — в разделе «Как передать» ниже.

Где создать

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

Галочка «Доступ к 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Когда задача создана и когда завершилась
paginationpage, 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.codeerror.message
Ключ не найден401UNAUTHORIZEDInvalid API key
Ключ отозван401UNAUTHORIZEDAPI key has been revoked
Ключ истёк401UNAUTHORIZEDAPI key has expired
Запись владельца отключена401UNAUTHORIZEDUser is not active
Ключ не личный, а выпущен администратором для папок403FORBIDDENThis API key cannot act on behalf of a user
Владелец — администратор403FORBIDDENAPI keys are not available for admin accounts
«Доступ к API» выключен403FORBIDDENAPI access is disabled for this account
Превышен лимит429RATE_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 секунд.

Дальше: задачи и чаты — полные списки запросов, которые принимает личный ключ.

На этой странице