Справка Открыть Искру

API Искры: REST API, MCP и OpenAI Like API

API-ключ даёт доступ к Искре из скриптов, ботов и внешних систем. Можно получить каталоги, выбрать навыки и специалистов, подключить папки и коллекции Памяти, подготовить разговор и выполнить задачу. Ключ создаётся в Настройки → API-ключи; окно «Документация API» показывает актуальную справку с адресом вашего контура.

Ключ привязан к профилю пользователя, выбранному при создании. Параметр iskra_exec.profile_id выбирает профиль модели, а не владельца запроса. Ключ организации с правом run:delegate может указать сотрудника через X-Iskra-Run-As; сам ключ не подключает проект или базу знаний.

Для работы с материалами сначала создайте разговор через POST /api/v1/conversations: рабочую папку задаёт workspace_directory_id, подключения Памяти — memory_refs с locator или collection_id и режимом access_mode. Затем выполняйте POST /api/v1/chat с полученным conversation_id. Тот же ID продолжает разговор. Idempotency-Key в native дедуплицирует только создание разговора: повтор может выполнить ещё один ход. Для POST /api/v1/runs тот же ключ и тело возвращают прежний run_id без второго исполнения. Права и примеры каждого шага приведены ниже.

Как выбрать способ подключения

В справке способы подключения идут в одном порядке:

Способ Для чего
REST API Скрипты и приложения: запуски, Память, доски, файлы и другие операции Искры
MCP Внешний агент сам находит и вызывает те же операции
OpenAI Like API Приложения, которым нужен вызов в формате OpenAI Chat Completions

Память и доски входят в REST API. MCP использует те же права профиля и ключа: подключение агента не добавляет ему разрешений.

Вкладка Обзор показывает три способа подключения с адресами и пояснениями; нажатие на строку открывает соответствующую вкладку. «Полная справка и все методы» открывает REST-каталог в этом же окне.

Вкладка REST API показывает сгруппированный каталог из текущего openapi.json. Раскройте строку метода, чтобы увидеть параметры, тела запросов, ответы, схемы и права. В окне нет отправки пробного запроса. Ссылка openapi.json открывает актуальный машиночитаемый контракт. «Скопировать для агента» копирует актуальный контракт, адреса REST и MCP и инструкцию подключения. В инструкции стоит место для вашего ключа; справка не получает секреты ранее созданных ключей.

Вкладка MCP также показывает имена инструментов и их назначение из текущего контракта. Во вкладке OpenAI Like API есть отдельный каталог методов: раскройте строку, чтобы посмотреть параметры и схемы запросов и ответов.

Для MCP нужен клиент, который умеет передавать ключ в заголовке Authorization: Bearer <токен> к адресу /mcp вашего контура. Если клиент поддерживает только вход через OAuth, такое подключение не заявлено. Обнаружение операций доступно и ключу только для чтения; вызов каждой операции проверяет её собственные права. Долгую работу агент запускает фоном и проверяет её по run_id. Большие файлы передаются через REST, с ключом в заголовке, без секрета в адресе.

В OpenAI Like API два режима: iskra вызывает агента Искры с его инструментами, а iskra-llm вызывает модель с инструментами, которые исполняет клиент. Для первого нужен chat:run, для второго — также llm:raw и доступный на контуре режим. Подробности обоих режимов приведены ниже.

Если агенту нужен только готовый результат одной доски, используйте вкладку «API и MCP доступ» в настройках доски. Она не передаёт доступ ко всему профилю.

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

Все вызовы ниже используют Authorization: Bearer <токен>. Для JSON-тела добавьте Content-Type: application/json; загрузка файлов использует multipart/form-data (с curl -F тип и границу формы устанавливает сам curl).

Возможность Метод Права ключа (scope)
Профиль и права ключа GET /api/v1/me chat:run
Новые результаты расписаний GET /api/v1/agenda/results agenda:read
Каталог навыков GET /api/v1/skills skills:run
Каталог специалистов и превью плана GET /api/v1/specialists, GET /api/v1/exec-plan/defaults chat:run
Папки и файлы Памяти GET /api/v1/memory/browse memory:read
Коллекции и их состав GET /api/v1/memory/collections, GET /api/v1/memory/collections/{id}/members memory:read
Создать постоянные папки, загрузить файл POST /api/v1/memory/resources/roots, /folders, /files memory:read + memory:write
Скачать постоянный файл GET /api/v1/memory/resources/files/{id}/content?directory_id=<uuid> memory:read
Подготовить разговор без запуска задачи POST /api/v1/conversations chat:run; права Памяти по выбранным целям
Прочитать и изменить контекст GET /api/v1/chat/{id}/context; PUT/DELETE /api/v1/chat/{id}/workspace; POST /api/v1/chat/{id}/memory-refs, PATCH/DELETE /api/v1/chat/{id}/memory-refs/{ref_id} chat:run + memory:read; выбор workspace и режим write также требуют memory:write
Синхронная задача POST /api/v1/chat chat:run
Фоновая задача, опрос, события, отмена POST /api/v1/runs, GET/DELETE /api/v1/runs/{run_id}, GET /api/v1/runs/{run_id}/events chat:run
Загрузка и скачивание файлов разговора POST /api/v1/chat/files, GET /api/v1/chat/{id}/files/{path} files:write / files:read соответственно
Удалить разговор DELETE /api/v1/chat/{id} chat:run
OpenAI-совместимый агент или модель POST /api/openai/v1/chat/completions, GET /api/openai/v1/models chat:run; для iskra-llm* также llm:raw
Публикация приложений POST /api/v1/apps, POST /api/v1/apps/{id}/versions, GET /api/v1/apps/{id}?version={version} apps:publish
Смена доступа своего приложения PATCH /api/v1/apps/{id}/access apps:publish
Публикация выбранных файлов на своей доске POST /api/v1/board-publications boards:write
Проверка готовности принятой публикации GET /api/v1/board-publications/{request_id} boards:write

Для веб-поиска нужен web_search, для запуска навыков — skills:run, для передачи вложений — files:write; контекст Памяти добавляет свои права к правам запуска и файлов.

Фоновый запуск возвращает run_id принятой задачи, а не готовый результат. Проверяйте GET /api/v1/runs/{run_id}: при queued или running продолжайте опрос, при completed заберите результат. Другие итоговые состояния требуют отдельного действия — см. «Асинхронные прогоны API».

Обычный порядок: каталоги → выбор доступного bundle → POST /api/v1/conversations с workspace_directory_id и memory_refs → ход с полученным conversation_id и iskra_exec → скачивание результата. В memory_refs цель задаётся через locator: {directory_id, folder_id?} или collection_id, режим — через access_mode: "read" или "write".

iskra_exec задаёт один запрос: skills (массив bundle), specialist_id, secondary_specialist_id, profile_id (профиль модели, а не профиль пользователя), complexity (simple, normal, hard), antonym. Ручной набор навыков включает все mandatory; выбирайте строки каталога с available: true и setup_state: "ready". Это настройка запуска уже доступных навыков; установка и настройка навыка выполняются в интерфейсе.

Права memory:read и memory:write при создании ключа отмечают явно; запись требует оба. Права ключа ограничены текущим доступом вашего профиля. Рабочая папка — только личный корень Памяти с правом записи, выбранный до первого сообщения или upload. После снятия memory_refs разговор по-прежнему требует memory:read для продолжения, файлов и результатов: история могла сохранить прочитанные материалы. Файлы Памяти постоянные, срок ключа и TTL разговора задаются отдельно. Подробный исполнимый пример — «Полный сценарий API».

Подключённые приложения: вход без копирования API-ключа

Приложение с кнопкой «Подключить Искру» может запросить доступ через сайт Искры. Создавать и копировать API-ключ для такого подключения не требуется.

  1. Начните подключение в самом приложении.
  2. На сайте Искры войдите доступным способом — через Яндекс, VK или почту. Если вы уже вошли, проверьте имя аккаунта на странице согласия. «Другой аккаунт» позволяет выйти и продолжить с нужным аккаунтом.
  3. Выберите профиль: личный или профиль организации. Приложение будет обращаться к данным, навыкам и лимитам именно этого профиля.
  4. Прочитайте название приложения, его владельца и запрашиваемые права. Дополнительные возможности включаются отдельно; обязательные нужны для работы подключения.
  5. Подтвердите доступ и завершите подключение в приложении. Для Telegram последний шаг выполняется в исходном личном чате с ботом.

Переключение профиля на сайте не переключает уже подключённое приложение. Чтобы выбрать другой профиль или изменить права, начните подключение заново в приложении. Если форма истекла или сообщает об изменении условий, получите новую ссылку либо повторно просмотрите предложенное согласие.

В Настройки → Подключённые приложения видны подключения выбранного профиля, выданные права, срок доступа и последняя активность. Если список пуст, начните подключение из нужного приложения. Для другого профиля переключите профиль в Искре. Здесь не перечисляются ручные API-ключи — у них свой раздел настроек.

Чтобы отозвать доступ, выберите подключение, нажмите «Отключить» и подтвердите действие. Новые запросы этого подключения будут отклоняться; уже начатая задача может завершиться. Другие подключения и ручные ключи сохраняются. Для возвращения доступа снова начните подключение в приложении.

Подписка и лимиты относятся к выбранному профилю. Если приложение сообщает об ограничении по оплате, восстановите доступ в Искре; переподключать приложение только из-за оплаты не требуется. Когда подключение приложений недоступно на вашей установке, обратитесь к её администратору. Интеграция может отдельно предлагать прежний способ с ручным API-ключом.

Создание ключа

  1. Выберите личный профиль или профиль организации, для которого нужен доступ, и откройте Настройки → API-ключи.
  2. Нажмите Создать ключ.
  3. Укажите название — оно нужно только для того, чтобы отличать ключи в списке (например, «CI-бот» или «Скрипт выгрузки»).
  4. Выберите срок действия: 7, 30, 90, 180 или 365 дней. По умолчанию выбран срок 30 дней.
  5. Оставьте только нужные права доступа. Их состав показан до создания; чувствительные права выдаются отдельно — см. список ниже.
  6. Нажмите Создать и сразу сохраните токен в секретном хранилище интеграции, например в переменной окружения.

После создания токен показывается один раз. Скопируйте его немедленно — повторно увидеть токен невозможно, платформа хранит только его хэш. Если потеряли токен — отзовите ключ и создайте новый.

Ключ относится к выбранному профилю; ID профиля не заменяет токен. Проверить доступ можно запросом GET /api/v1/me с Authorization: Bearer <токен> и правом chat:run. Окно «Документация API» показывает примеры с адресом вашей установки.

Дата окончания действия показана после создания и в списке ключей. Новый выбор срока не меняет даты у ранее созданных ключей. По истечении срока ключ перестаёт работать; для продолжения интеграции создайте новый. Если настройки создания временно недоступны, ключ можно создать с серверным сроком по умолчанию — 30 дней; выбор другого срока в этом состоянии недоступен.

Выбор прав API-ключа

Перед созданием окно показывает список областей доступа с флажками. Стандартные права уже отмечены: чат, веб-поиск, запуск навыков, запись и скачивание файлов разговора — можно снять лишние, если ключу они не нужны (например, оставить только чат). Чувствительные права по умолчанию не отмечены и выдаются только явно. Итоговый состав прав виден до создания ключа; относитесь к токену как к паролю.

Чувствительные права в списке:

  • «Результаты расписаний» (agenda:read) — позволяет получать новые результаты задач по расписанию вашего профиля, в том числе в Telegram-боте Искры. Право выбирается явно.
  • «Чтение Памяти» (memory:read) — позволяет интеграции просматривать доступные вашему профилю папки, файлы и коллекции, подключать материалы для чтения и получать результаты работы с ними.
  • «Изменение Памяти» (memory:write) — позволяет создавать папки, загружать материалы и разрешать запись в подключённую Память. Выдаётся вместе с правом чтения; одно право записи не включает чтение автоматически.
  • «Прогоны от имени сотрудников организации» (run:delegate) — есть только у ключей профиля организации. Отмечайте, только если ключ должен выполнять запросы от имени других сотрудников (например, интеграция, которая обрабатывает документы за конкретного сотрудника): такой ключ сможет действовать от имени любого коллеги в организации.
  • «Сырой доступ к модели» (llm:raw) — открывает OpenAI-совместимый режим прямого обращения к модели с вашими собственными инструментами. Право добавляется к остальным отмеченным правам ключа; в самом режиме прямого обращения агентные функции Искры и навыки не применяются.
  • «Публикация приложений» (apps:publish) — позволяет ключу создавать приложения, публиковать и проверять версии, менять доступ своих приложений. Для включения public также нужно действующее право вашего профиля на внешнюю публикацию. Право ключа действует только в вашем профиле: управлять им приложением другого владельца нельзя, даже если у ключа есть право прогонов от имени сотрудников. Как устроены сами приложения — в главе «Приложения».
  • «Чтение навыков» (skills:read) — позволяет интеграции читать исходный код ваших навыков и навыков, которые вам видны, историю версий, разницу версий, предпросмотр копии и настройки без значений секретов.
  • «Изменение своих навыков» (skills:write) — позволяет делать копии, править файлы своих навыков и копий (каждая правка проходит проверку), откатывать версии, обновлять копии из источника, управлять автообновлением и версией своих установок из каталога. Удалить навык ключом нельзя. Отмечайте, только если интеграции действительно нужно менять ваши навыки: ключ сможет менять исполняемый код навыков от вашего имени.
  • «Навыки организации» (skills:admin) — только для владельца и администраторов организации: строка есть в окне, когда ключ создаётся в профиле организации с такой ролью; остальным она не показывается, а попытка выдать право отклоняется («Право skills:admin выдаётся только владельцу и админам организации в профиле организации»). Позволяет интеграции читать личные навыки сотрудников в профилях этой организации — список, карточку, файлы, версии, разницу версий и настройки без значений ключей, — а также всё, что читает право skills:read. Только чтение: удалять навыки и поднимать их в организацию по ключу нельзя — только в интерфейсе или в чате. Ключ администратора читает навыки рядовых участников, ключ владельца — всех. Если роль у вас забрали, ключ перестаёт читать навыки со следующего запроса.
  • Чтение досок (boards:read) — открывает интеграции материал досок, которыми управляет ваш профиль: список досок, состав показанной версии, её содержимое и скачивание.
  • Подготовка размещения на доске (boards:publish) — позволяет интеграции подготовить размещение файла на доске. Само размещение ключ не выполняет: подготовленное действие подтверждает человек.
  • Публикация на своих досках (boards:write) — позволяет интеграции самостоятельно разместить выбранные файлы и проверить готовность результата. Это отдельное разрешение для API-ключа, созданного вручную; подключённые приложения через OAuth его не получают.

Все три области досок выдаются только явно и в стандартный набор прав ключа не входят: доска показывает готовые документы людям за пределами чата, поэтому доступ к ней ключ получает отдельным решением. Подробности — в разделе «Доски по API-ключу» ниже.

Список показывает только области, разрешённые на вашей платформе: если какого-то права в окне нет, оно недоступно на этом контуре — обратитесь к администратору.

Каталоги API: выбор навыков skills и специалистов specialists

GET /api/v1/skills возвращает {"skills":[...]}. У каждого навыка есть bundle, name, title, description, version, mode, available, requires_setup, mandatory, setup_state. В iskra_exec.skills передаются bundle, а не имена инструментов. requires_setup показывает необходимость настройки; setup_state бывает ready, missing, invalid, unknown. Наличие строки в каталоге само по себе не означает готовность к запуску. Если выбранный или обязательный навык недоступен, сначала завершите его настройку в интерфейсе и снова получите каталог.

GET /api/v1/specialists возвращает {"specialists":[...]} с полями id, title, description, icon. Используйте выбранные id в запросе. GET /api/v1/exec-plan/defaults возвращает plan, pins, version и options, включая доступные уровни, mandatory_bundles и специалистов. Это превью до создания разговора, которое помогает составить запрос.

Поле iskra_exec Как выбрать
profile_id Разрешённый профиль модели из доступных вариантов; отличается от профиля пользователя, к которому привязан ключ
complexity simple, normal или hard; hard выбирают явно, расход зависит от фактической модели
specialist_id Основной специалист: задаёт полный рабочий стиль
secondary_specialist_id Дополнительная предметная экспертиза вместе с основным; максимум две разные роли, «Общий» в паре не используется
skills Ручной массив bundle, включающий все mandatory; каждый выбранный навык доступен и готов
antonym true включает режим Антонима, если организация его не запретила; явное false выключает его, если режим не обязателен по политике платформы или организации

Отсутствующее поле оставляет решение автоматике. Для навыков отсутствие поля или null сохраняет обычный подбор; skills: [] означает ручной пустой набор и допустим только при отсутствии обязательных навыков. Иначе — 403 mandatory_skill_required. Недоступный bundle — 403 skill_not_available.

Пара, например {"specialist_id":"dev","secondary_specialist_id":"finance"}, даёт один ответ с основной и дополнительной экспертизой. Все значения iskra_exec действуют на один запрос в native, async и OpenAI agent; передавайте их снова для следующего хода, если они нужны. Они не меняют постоянные настройки разговора. Без override разговор использует сохранённый автоматический выбор специалистов; сложность API без override — normal.

Память через API: папки, коллекции и файлы memory

Ключу явно выдаются memory:read для чтения и дополнительно memory:write для записи. Права files:read/files:write относятся к файлам разговора и сами по себе Память не открывают. Уже созданный ключ новые права автоматически не получает.

GET /api/v1/memory/browse показывает доступные корни. Добавьте ?directory_id=<uuid> для содержимого корня, &folder_id=<uuid> для подпапки. Доступны фильтры q, origin, target_kind, candidates, сортировка sort, direction и страницы cursor, limit. GET /api/v1/memory/collections возвращает {"collections":[...]}, а GET /api/v1/memory/collections/{id}/members — {"members":[...]} своей коллекции. Используйте идентификаторы и locator из ответа каталога.

Запись или скачивание Памяти Тело / параметры
POST /api/v1/memory/resources/roots JSON {"name":"Материалы интеграции"} → 201, корень с id
POST /api/v1/memory/resources/folders JSON {"directory_id":"<uuid>","path":"input"} → 201, папка с id
POST /api/v1/memory/resources/files multipart: directory_id, file, необязательные path, conflict_policy → 201, file и version
GET /api/v1/memory/resources/files/{id}/content ?directory_id=<uuid>; {id} — file.id, ответ — байты файла

Для upload path по умолчанию равен имени файла; conflict_policy: create отклоняет совпадение имени, rename выбирает свободное имя. Файлы и папки постоянные: TTL разговора их не удаляет. Сохраняются права доступа, квоты и ограничения загрузки.

Bearer API предоставляет чтение коллекций и их состава. Создание, редактирование состава и удаление коллекций выполняются в интерфейсе; маршрутов bearer CRUD коллекций нет. Операции записи ресурсов в таблице создают корни и подпапки или загружают файлы.

Контекст API: подключить Память memory к разговору conversations

POST /api/v1/conversations со scope chat:run создаёт разговор без сообщения и запуска задачи. Минимальное тело — {}; настройка Памяти:

{
  "ttl_seconds": 3600,
  "workspace_directory_id": "<UUID личного корня для результатов>",
  "memory_refs": [
    {"locator":{"directory_id":"<UUID материалов>","folder_id":"<UUID подпапки>"},"access_mode":"read"},
    {"collection_id":"<UUID своей коллекции>","access_mode":"read"}
  ]
}

Каждая из максимум 100 ссылок задаёт ровно одну цель: locator с directory_id и необязательным folder_id, либо collection_id. Режим access_mode обязателен: read или write. Цели идут без дублей; рабочий корень уже подключён как workspace и отдельной ссылки не требует. Ответ 201: conversation_id, expires_at, workspace, references. При ошибке контекст не создаётся частично; повторный POST создаёт новый разговор.

Workspace можно выбрать или снять только до первого сообщения или upload: это личный корень с правом записи, не подпапка, коллекция или корень организации. Замена уже выбранной папки возвращает 409; повтор того же выбора идемпотентен. Без выбора файлы хранятся во временной папке разговора. В выбранном корне результаты сохраняются в Памяти и переживают удаление разговора.

Контекст существующего разговора Тело Права сверх chat:run
GET /api/v1/chat/{id}/context — memory:read
PUT /api/v1/chat/{id}/workspace {"directory_id":"<uuid>"} оба права Памяти
DELETE /api/v1/chat/{id}/workspace — оба права Памяти
POST /api/v1/chat/{id}/memory-refs Одна цель как в массиве memory_refs memory:read, для write ещё memory:write
PATCH /api/v1/chat/{id}/memory-refs/{ref_id} {"access_mode":"read"} или {"access_mode":"write"} memory:read, для нового write ещё memory:write
DELETE /api/v1/chat/{id}/memory-refs/{ref_id} — memory:read, в том числе для снятия ссылки write

Доступ к ресурсам проверяется на каждом запросе. Для подключения write нужны право записи и разрешение агенту изменять материал. У коллекции перед созданием разговора, добавлением ссылки или PATCH в write проверяется каждый текущий участник: его право записи и разрешение агентской записи. Сохранённый режим write требует обоих прав Памяти при запуске, даже если коллекция пуста или доступ позднее сузился до чтения.

Разговор, которому хотя бы раз открыли Память, сохраняет требование memory:read после снятия всех ссылок и workspace. Оно действует на native, OpenAI agent, async, загрузку/скачивание файлов, опрос результата и SSE. Удаление самого разговора остаётся доступно владельцу со scope chat:run. При активном ходе контекст заблокирован (409). Если контекст изменился между постановкой async в очередь и стартом, прогон получит failed / context_changed: отправьте новый запрос с актуальным контекстом.

Привязка к профилю

Ключ привязан к активному профилю пользователя, выбранному при создании (личному или организации). Переключение профиля меняет список ключей. Сам ключ не подключает проект или базу знаний: материалы выбираются явно через контекст разговора. iskra_exec.profile_id — отдельный идентификатор профиля модели, который не меняет владельца ключа или разговора.

Ключ организации с явно выданным run:delegate может действовать от имени сотрудника этой организации: X-Iskra-Run-As: <profile_id сотрудника>. Расход и доступ к материалам относятся к выбранному сотруднику. Передавайте одинаковый заголовок по всей цепочке загрузки, запуска, опроса, SSE, скачивания и отмены; без него запрос обращается к профилю владельца ключа и может получить 404. Публикация Apps выполняется только своим профилем и делегирование отклоняет.

Продолжение разговора

Для синхронного хода отправьте POST /api/v1/chat с JSON {"message":"Привет!"}. Ответ 200 содержит conversation_id, message_id, status, answer, usage, expires_at, а при наличии результатов — files. Созданный через POST /api/v1/conversations разговор используется тем же образом.

Передайте conversation_id из предыдущего ответа и новое message. Это ID отдельного API-разговора, а не настройка подключения ключа к проекту или базе знаний. Один разговор используется последовательно в native, async и OpenAI agent. Одновременный ход получает 409.

Заголовок Idempotency-Key в native и OpenAI agent дедуплицирует только создание разговора: повторный запрос способен выполнить ещё один ход. Для фонового POST /api/v1/runs повтор с тем же ключом и тем же телом возвращает прежний run_id и не запускает второе исполнение. Ключ закрепляется за телом первого запроса: другое тело с тем же ключом получает 409 idempotency_conflict и не запускается. Для каждой новой команды задавайте новый ключ, например случайный UUID.

Поля запроса

Поле native / async Смысл
message Обязательный текст сообщения
conversation_id Подготовленный или продолжаемый разговор; без него создаётся новый
instructions Дополнительные инструкции на этот ход
files Inline {name,mime,content_base64} либо {id} из multipart upload; async принимает только {id}
ttl_seconds Срок разговора: по умолчанию 3600 секунд, максимум 86400
policy {"inputs":{...}} — значения полей запрошенной формы
include_reasoning true добавляет доступные рассуждения в reasoning; по умолчанию выключено
response_format {"type":"json_schema","json_schema":{...}} для структурированного вывода
iskra_exec Поля выбора модели, сложности, навыков, двух специалистов и Антонима описаны выше; действуют один запрос

usage показывает расход токенов ориентировочно и не служит расчётом оплаты. completed означает готовый ответ. При interaction_required покажите человеку interaction.inputs (name, label, type, required) и отправьте новый ход с тем же conversation_id и значениями в policy.inputs. В ответе также есть interaction.tool_call_id. Пустая форма подтверждения выполняется в интерфейсе: policy.inputs передаёт значения полей, а согласие за человека не выражает.

Файлы в запросе API: содержимое или id, а не локальный путь

Путь к файлу на вашей машине (C:\Отчёты\report.pdf, /home/user/report.pdf) в запросе ничего не передаёт: Искра получает файл содержимым или ссылкой на предварительную загрузку.

В files каждый элемент задаёт ровно один вариант:

  • {name, mime, content_base64} — байты в base64 для native sync;
  • {id} — ID версии из ответа POST /api/v1/chat/files. Это единственный источник входного ID. Массив files результата хода содержит лишь {name, download_url} и такого ID не даёт.

Upload требует files:write: ключ с одним правом files:read загрузку не разрешает. Он принимает multipart-поля conversation_id, необязательное ttl_seconds и повторяемое поле file. Без conversation_id создаётся новый разговор. Ответ: conversation_id, expires_at, files: [{id, name, size}]. Для выбранного workspace также нужны оба права Памяти; после любого обращения разговора к Памяти требуется memory:read.

curl --fail-with-body https://your-iskra.example/api/v1/chat/files \
  -H "Authorization: Bearer $ISKRA_API_KEY" \
  --form-string "conversation_id=$CONVERSATION_ID" -F 'file=@report.pdf'

ID действует только в этом разговоре и один раз: повторная привязка к другому сообщению, чужая или несуществующая версия дают 404 invalid_file. Загрузите файл снова для нового использования. Оба варианта одновременно или ни одного — 400 invalid_request; async с inline — 400 use_file_upload. Отдельный лимит обработки Office может отклонить уже загруженный файл перед ходом (413 file_size_limit): уменьшите или разделите его.

Вложение передаёт конкретный файл в ход. Для работы с папкой Памяти или коллекцией подключите её через memory_refs.

Как скачать созданный файл через API

Созданные агентом файлы перечислены в files: [{name, download_url}]. Скачайте фактический download_url с Bearer-ключом и files:read, например GET /api/v1/chat/{id}/files/report.md. Для разговора с Памятью требуется также memory:read и текущий доступ к выбранной рабочей папке. Через Memory API постоянный файл скачивается по file.id из каталога, а не upload version ID.

Асинхронные прогоны API: runs, опрос, SSE и отмена

POST /api/v1/runs принимает поля native (вложения только по id) и сразу возвращает 202: run_id, conversation_id, status: "queued", expires_at. Полученный run_id означает принятую задачу, а не готовый ответ или файл. Здесь expires_at — фиксированный дедлайн прогона, а не TTL разговора.

GET /api/v1/runs/{run_id}?after=N возвращает status, result, error, events, next_after. Пока статус queued или running, продолжайте опрос; в следующий запрос передавайте next_after, а не число прочитанных событий. Итоговые состояния: completed, interaction_required, failed, cancelled. В result находятся ответ и файлы, а машинный код отказа — в error.code.

GET /api/v1/runs/{run_id}/events с заголовком Accept: text/event-stream отдаёт ту же ленту через SSE. Bearer-заголовок сохраняется: браузерный EventSource сам его установить не умеет — используйте клиент с поддержкой заголовков, например streaming fetch. Возобновляйте с ?after=<последний id + 1> или Last-Event-ID. События сообщают прогресс: content содержит длину текста, tool — имя инструмента; сам ответ забирается опросом результата. Терминальное событие закрывает поток.

DELETE /api/v1/runs/{run_id} отменяет ожидающий или активный прогон; для завершённого возвращается 409 already_finished. После перезапуска сервиса прерванный прогон может оставаться running до проверки дедлайна, затем завершится failed / interrupted; повторяйте по терминальному исходу.

OpenAI-совместимый API: agent и raw

Base URL клиента — https://your-iskra.example/api/openai/v1, API key — ваш isk_…, модель агента — iskra или iskra-agent. Доступные имена возвращает GET /api/openai/v1/models; поверхность включается администратором, иначе 404.

curl --fail-with-body https://your-iskra.example/api/openai/v1/chat/completions \
  -H "Authorization: Bearer $ISKRA_API_KEY" -H 'Content-Type: application/json' \
  -d '{"model":"iskra","messages":[{"role":"user","content":"Привет!"}]}'

В агентном режиме работают навыки, специалисты и подключённая Память. Передавайте conversation_id, iskra_exec и policy рядом с messages; в OpenAI SDK для дополнительных полей есть extra_body. С conversation_id сервер хранит историю, из нового messages использует последнее сообщение user и инструкции system/developer. Без ID каждый запрос самостоятельный. Поддерживается stream: true; ответ содержит conversation_id, а при наличии — files и interaction. Непустые клиентские tools в агентном режиме отклоняются: Искра использует свои инструменты.

Raw выбирается моделями iskra-llm, iskra-llm-fast, iskra-llm-balanced, iskra-llm-powerful и требует одновременно chat:run + явно выданное llm:raw. Он доступен, когда включён администратором. Это обращение к модели с историей и инструментами клиента: навыки, специалисты, контекст Памяти и серверный разговор Искры здесь не применяются; conversation_id, policy, iskra_exec относятся к агентному режиму. Модель возвращает tool_calls, исполняет их клиент. Raw поддерживает response_format со значением text или json_object; для JSON Schema используйте native или async.

Структурированный вывод API: response_format

В native и async можно задать "response_format":{"type":"json_schema","json_schema":{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"],"additionalProperties":false}}. При успехе исходный текст остаётся в answer, объект по схеме приходит в output. Невалидная схема отклоняется до запуска (400 invalid_schema). Если ответ не удалось привести к схеме, native возвращает 422 structured_output_failed с conversation_id и исходным answer: ход уже состоялся. В async — failed, error.code: structured_output_failed, result.answer без output. Для interaction_required и ошибок приведение к схеме не выполняется. В OpenAI agent разрешён только response_format: {"type":"text"}.

Сроки и ошибки API

Срок ключа относится к авторизации: по умолчанию 30 дней, максимум 365 дней. TTL API-разговора — отдельно: ttl_seconds, по умолчанию 1 час (3600 секунд), максимум 24 часа (86400 секунд); ход или upload продлевает срок. Завершение фонового прогона, в том числе по таймауту или отмене, продлевает TTL от момента завершения: по умолчанию ещё на час, либо на заданное ttl_seconds с тем же максимумом 24 часа. История разговора сохраняется независимо от состояния прогона. Эти разговоры отделены от обычных чатов интерфейса. Истечение или DELETE /api/v1/chat/{conversation_id} закрывает разговор для API: продолжение, контекст и URL его файлов отвечают 404. Забирайте файлы разговора до истечения TTL. Запись разговора — сообщения, ход и файлы — сохраняется бессрочно и видна владельцу ключа в Искре в разделе «API-запросы» меню «⋯» у «Чатов», только для просмотра (раздел «Чат с Искрой»). Истечение TTL не удаляет историю и файлы. С выпуска этого изменения DELETE по API закрывает разговор, а не уничтожает запись сразу; полностью стереть данные профиля можно удалением профиля. Постоянные файлы в выбранной папке и подключённые материалы остаются доступны через Память.

Синхронный ход ограничен 90 секундами, фоновый прогон — 60 минутами от создания. При достижении предела прогон получает статус failed и ошибку timeout; заберите исход через GET /api/v1/runs/{run_id}, даже если поток SSE был закрыт. Для явной отмены используйте DELETE /api/v1/runs/{run_id}. При повторении запроса учитывайте правила Idempotency-Key выше.

HTTP Как действовать
400 Исправьте тело, поля, ID или схему по машинному коду ошибки
401 Ключ невалиден, истёк или отозван: создайте действующий ключ
403 Проверьте scope, доступ и политику: недостающий scope бывает scope_not_granted либо insufficient_scope; наличие params.required_scope зависит от маршрута
404 Ресурс отсутствует, чужой, недоступен для чтения или разговор истёк; также возможен выключенный API
409 Разговор занят, выбранный контекст менять поздно, прогон уже завершён либо Idempotency-Key уже использован с другим телом (idempotency_conflict) — для новой команды задайте новый ключ
410 Ресурс запечатан и операция недоступна. Если это подключение разговора — папка в корзине или её источник в архиве, — удалите его DELETE …/memory-refs/{ref_id} и повторите запрос
413 Превышен лимит загрузки или обработки файла
422 structured_output_failed: сохраните исходный ответ и проверьте схему
429 Ограничена частота запросов или исчерпана квота
500 Внутренняя ошибка, empty_response либо llm_output_truncated; проверьте исход перед повтором
503 Временно недоступна зависимость/каталог/блокировка или идёт обслуживание; при platform_cooldown ждите Retry-After
504 Истёк тайм-аут хода

Формат ошибки зависит от маршрута: native возвращает error.code и error.message, операции контекста могут возвращать problem JSON с code, detail, params. Проверяйте HTTP-статус и машинный код, а не точный текст. В OpenAI SSE ошибка после начала потока приходит кадром error при уже отданном HTTP 200; async ошибки читаются из терминального результата.

Полный сценарий API

Пример для Bash, curl и jq: каталог → выбранный готовый навык → исходники и рабочая папка Памяти → разговор → задача → постоянный результат. Создайте ключ с chat:run, skills:run, files:read, files:write, memory:read, memory:write. Задайте адрес своего контура и токен через окружение.

set -euo pipefail
export BASE_URL='https://your-iskra.example'
export ISKRA_API_KEY='isk_...'
api() {
  local endpoint="$1"
  shift
  curl --fail-with-body -sS -H "Authorization: Bearer $ISKRA_API_KEY" \
    "$BASE_URL$endpoint" "$@"
}
api /api/v1/skills > skills.json
api /api/v1/specialists > specialists.json
api /api/v1/exec-plan/defaults > defaults.json
api /api/v1/memory/browse > roots.json
api /api/v1/memory/collections > collections.json
jq '.skills[] | {bundle,title,available,setup_state,mandatory}' skills.json
jq '.specialists[] | {id,title}' specialists.json

Выберите подходящие задаче bundle и id из напечатанных каталогов. Следующий блок запросит их явно и проверит доступность выбранного и всех обязательных навыков. Если проверка упала, завершите настройку в интерфейсе и получите каталог заново. Установка навыка через эти маршруты не выполняется.

read -r -p 'Bundle выбранного навыка: ' SKILL_BUNDLE
read -r -p 'ID основного специалиста: ' SPECIALIST_ID
jq -e --arg id "$SPECIALIST_ID" \
  'any(.specialists[]; .id == $id)' specialists.json >/dev/null
SKILLS_JSON=$(jq -ce --arg selected "$SKILL_BUNDLE" '
  if any(.skills[]; .bundle == $selected and .available == true and .setup_state == "ready")
     and all(.skills[] | select(.mandatory); .available == true and .setup_state == "ready")
  then [.skills[] | select(.mandatory or .bundle == $selected) | .bundle] | unique
  else error("Выбранный или обязательный навык недоступен либо требует настройки") end
' skills.json)
EXEC_JSON=$(jq -nc --arg specialist "$SPECIALIST_ID" --argjson skills "$SKILLS_JSON" \
  '{specialist_id:$specialist,skills:$skills}')
SOURCE_DIR=$(api /api/v1/memory/resources/roots -X POST \
  -H 'Content-Type: application/json' -d '{"name":"Исходники интеграции"}' | jq -er '.id')
WORK_DIR=$(api /api/v1/memory/resources/roots -X POST \
  -H 'Content-Type: application/json' -d '{"name":"Результаты интеграции"}' | jq -er '.id')
INPUT_FOLDER=$(api /api/v1/memory/resources/folders -X POST \
  -H 'Content-Type: application/json' \
  -d "$(jq -nc --arg dir "$SOURCE_DIR" '{directory_id:$dir,path:"input"}')" | jq -er '.id')
printf 'Подготовить план запуска проекта: цели, этапы и риски.\n' > brief.txt
api /api/v1/memory/resources/files -X POST \
  --form-string "directory_id=$SOURCE_DIR" --form-string 'path=input/brief.txt' \
  -F 'file=@brief.txt;type=text/plain' > uploaded.json
SOURCE_FILE=$(jq -er '.file.id' uploaded.json)
jq -n --arg workspace "$WORK_DIR" --arg source "$SOURCE_DIR" --arg folder "$INPUT_FOLDER" \
  '{ttl_seconds:3600,workspace_directory_id:$workspace,
    memory_refs:[{locator:{directory_id:$source,folder_id:$folder},access_mode:"read"}]}' \
  > context-request.json
api /api/v1/conversations -X POST -H 'Content-Type: application/json' \
  --data-binary @context-request.json > conversation.json
CONVERSATION_ID=$(jq -er '.conversation_id' conversation.json)
REF_ID=$(jq -er '.references[0].id' conversation.json)
api "/api/v1/chat/$CONVERSATION_ID/context"
jq -n --arg conversation "$CONVERSATION_ID" --argjson plan "$EXEC_JSON" \
  '{conversation_id:$conversation,iskra_exec:$plan,
    message:"Прочитай brief.txt из подключённых материалов, составь план запуска и сохрани его в рабочую папку как answer.md."}' \
  > turn.json
api /api/v1/chat -X POST -H 'Content-Type: application/json' \
  --data-binary @turn.json > result.json
jq '{status,answer,interaction,files}' result.json

Если нужен фоновый прогон, вместо последнего вызова отправьте turn.json в POST /api/v1/runs, дождитесь терминального статуса через GET и сохраните его .result в result.json. Для OpenAI agent преобразуйте запрос: jq '{model:"iskra",conversation_id,iskra_exec,messages:[{role:"user",content:.message}]}' turn.json и отправьте его в /api/openai/v1/chat/completions. Каждый отправленный вариант создаёт отдельный ход.

Скачивайте ссылку из фактического ответа: модель может выбрать другое имя или запросить уточнение. Если files нет, сначала разберите status, answer и interaction; само задание не гарантирует создание артефакта.

DOWNLOAD_URL=$(jq -er '.files[0].download_url' result.json)
api "$DOWNLOAD_URL" -o answer.md
api "/api/v1/chat/$CONVERSATION_ID/memory-refs/$REF_ID" -X DELETE
api "/api/v1/chat/$CONVERSATION_ID" -X DELETE
# Постоянные исходники и результаты пережили удаление разговора.
api "/api/v1/memory/resources/files/$SOURCE_FILE/content?directory_id=$SOURCE_DIR" \
  -o brief-after-delete.txt
api "/api/v1/memory/browse?directory_id=$WORK_DIR"

Для чтения Памяти выдайте memory:read без memory:write, подключите доступные материалы с access_mode: read и оставьте workspace_directory_id незаданным. Шаги создания папок и загрузки в Память из примера такому ключу недоступны. Результаты будут временными файлами разговора. Права файлов разговора выдаются отдельно: files:read позволяет скачать результат, но для upload нужно files:write.

Список и отзыв

В списке видны все ключи текущего профиля: название, префикс (isk_…), права, дата создания, дата последнего использования и срок действия. Сам токен не виден.

Чтобы отключить ключ, нажмите Отозвать и подтвердите. Действие необратимо — ключ перестаёт работать сразу. Отзывайте ключ при утечке токена или когда интеграция больше не нужна.

Управление ключами и публикация Apps

Маршруты GET/POST /api/v1/keys, DELETE /api/v1/keys/{id} и GET /api/v1/keys/scopes требуют пользовательскую сессию. Создание, список, каталог прав и отзыв ключей выполняются через интерфейс; Bearer-ключ ими не управляет. Токен показывается только один раз.

С явно выданным apps:publish CLI iskra-app создаёт приложение через POST /api/v1/apps, публикует версию через POST /api/v1/apps/{id}/versions и проверяет свою принятую публикацию через GET /api/v1/apps/{id}?version={version}. Оба POST требуют два ZIP в multipart-частях bundle и source, включая activate=false. По умолчанию activate=true: после проверки версия становится текущей. Для подготовки без активации передайте ?activate=false. Ответ 202 означает, что проверка ещё идёт; читайте результат именно принятой версии. В результате сверяйте publication.outcome и current_version: готовая версия может остаться неактивированной.

Тот же ключ меняет доступ через PATCH /api/v1/apps/{id}/access с JSON-телом {"access":"private"}, {"access":"org"} или {"access":"public"}. Все эти действия разрешены только владельцу приложения. Ключ администратора организации не управляет доступом чужого приложения через этот маршрут. Для org нужна организация, для public — активное приложение с текущей готовой версией и действующее право владельца на внешнюю публикацию. Публикация следующей версии доступ не меняет.

CLI 0.1.5 или новее отправляет готовую пару командой publish --bundle ./app.zip --source ./app-source.zip, прочитать результат через status --app-id UUID --version 1.0.0 и изменить доступ через access --app-id UUID --access public. Ключ передаётся через ISKRA_API_KEY. Если ожидание завершилось с probing, продолжите чтение статуса; если ответ на отправку потерян, сначала проверьте, принято ли приложение. Автоматической повторной отправки ZIP нет.

publish --path ./app автоматически готовит оба архива. Для ручной отправки создайте исходники командой source-pack --path ./app --output ./app-source.zip. Перед публикацией CLI и Node.js helper @iskra/apps/deploy проверяют GET /api/openapi.json именно настроенной установки: выбранный маршрут должен требовать бинарные bundle и source. Старый, недоступный или невалидный контракт даёт source_contract_unavailable без отправки публикации. Прямому HTTP-клиенту тоже следует проверить этот контракт перед POST на незнакомый сервер:

curl --fail-with-body "$ISKRA_API_URL/api/v1/apps?activate=true" \
  --header "Authorization: Bearer $ISKRA_API_KEY" \
  --form "bundle=@./app.zip" --form "source=@./app-source.zip"

Каждый ZIP через native HTTP/CLI ограничен 64 MiB. MCP ограничивает оба файла суммарными 8 MiB после декодирования и 12 MiB аргументов JSON, до 16 частей загрузки. Для большей пары используйте native HTTP/CLI. source_required означает отсутствие исходников, source_invalid — неверный архив, source_too_large — превышение его лимита.

Скачивание исходников доступно текущему профилю владельца через вход в Искру. Право apps:publish его не открывает; отдельного права ключа для скачивания исходников нет. Администратор организации, не владеющий приложением, также не получает этот доступ.

При ошибке бандла params.reason, а когда известны — path и field, помогают найти проблему; params.message содержит безопасную подсказку. Необязательный viewer_base_url — адрес открытия приложения, его наличие не подтверждает успешной активации. Доступ приложения от имени его зрителя описан отдельно: см. «Приложения».

С явно выданными skills:read и skills:write интеграция работает с навыками через /api/v1/skills/{bundle}/… — те же действия, что на странице навыка, с теми же правами и проверками. Чтение (skills:read): GET …/source, …/source/file?path=, …/source/archive, …/versions, …/source-diff?from=&to=, …/copy-preview, …/settings. Изменения (skills:write): POST …/copy, PUT …/source/files, POST …/versions/{version}/rollback, POST …/update-from-source, PUT …/auto-update, а для своей установки из каталога — POST …/install/update, POST …/install/revert, PUT …/install/auto-update. Эти маршруты работают только от имени профиля владельца ключа: заголовок X-Iskra-Run-As они отклоняют.

С явно выданным skills:admin интеграция владельца или администратора организации читает личные навыки сотрудников: GET /api/v1/org/team/skills — участники и их навыки (параметры member, status — auth_error, needs_setup или revoked, offset) и GET /api/v1/org/team/{profile_id}/skills/{bundle}/… — detail, source, source/file?path=, source/archive, versions, source-diff?version=&against=, settings. {profile_id} — идентификатор профиля сотрудника в организации из ответа списка. Значений ключей и паролей в ответах нет. По этому же праву работают маршруты чтения skills:read. Маршрутов изменения у skills:admin нет; заголовок X-Iskra-Run-As отклоняется.

Доски по API-ключу: чтение, публикация и подготовка размещения

С явно выданным boards:read ключ читает доски профиля, которому он принадлежит: GET /api/v1/boards — список досок под управлением этого профиля, GET /api/v1/boards/{id} — состав доски и показанная версия, GET /api/v1/boards/{id}/tabs/{tab_id}/content и тот же адрес с /download — содержимое и файл показанной версии. Доску, где профиль лишь получатель, ключ читает по её идентификатору, но в списке она не появляется. Само право чтения изменений не разрешает.

Адрес скачивания вкладки — не та ссылка, которую получает читатель доски: он работает только с вашим ключом и областью boards:read. Читателю доска открывается своей аудиторией — организацией, группой организации, адресным приглашением или доступом по ссылке, — и адрес API ему отдавать бессмысленно: без ключа он не открывается.

С явно выданным boards:write интеграция публикует выбранные файлы без дополнительного подтверждения в интерфейсе. Работает только собственный профиль ручного API-ключа; X-Iskra-Run-As для этих запросов не применяется. Для поиска существующей доски и чтения её состава отметьте также boards:read. Самой публикации и проверке её результата достаточно boards:write; доступ к исходным файлам проверяется отдельно по правам профиля.

POST /api/v1/board-publications принимает ваш UUID request_id и непустой список files. Новая доска требует board_title и явную аудиторию {"kind":"private"} или {"kind":"link"}. Для существующей доски передайте board_id и её текущую expected_revision: название, аудитория и остальные файлы сохраняются. В списке укажите нужные добавления и исправления; каждый файл встречается один раз. version_mode выбирает follow или pinned; закреплённую версию задаёт pinned_version_id.

Например, ключ с boards:read и boards:write может сначала найти доску через GET /api/v1/boards, прочитать её revision, затем отправить выбранные файлы:

{
  "request_id": "a63f07db-e225-4b2e-adac-f54479ac3456",
  "board_id": "<ID доски>",
  "expected_revision": 3,
  "files": [{"file_id": "<ID файла>", "version_mode": "follow"}]
}

Ответ 200 содержит принятую доску, её адрес board_url, ревизию и точные версии выбранных файлов в targets. Сохраните request_id: если ответ потерялся, повторите запрос с тем же UUID и получите первоначальный принятый результат. Для нового изменения используйте новый UUID. Отказ до принятия можно исправить и повторить с прежним UUID.

Далее опрашивайте GET /api/v1/board-publications/{request_id}. В accepted остаётся первый результат, а current_revision и status показывают текущее состояние именно выбранных версий: preparing — подготовка продолжается, ready — все готовы к показу своей аудитории, needs_attention — требуется действие по причине из reason. После изменения версий или доступа прежний результат может потребовать внимания. Сам опрос ничего не публикует и не продлевает срок доступа по ссылке; при наличии срок приходит в expires_at. Адрес доски имеет вид /boards/{id} и открывается по её аудитории.

С явно выданным boards:publish ключ только готовит размещение: POST /api/v1/board-publication-intents возвращает точную форму будущего действия — доску, её аудиторию, вкладки и версии, — а GET /api/v1/board-publication-intents/{id} показывает состояние подготовки и сохранённый результат. Подтверждения по ключу нет: подготовленное действие человек открывает в Искре на странице /boards/publication-intents/{id} и подтверждает своей сессией; подготовка ждёт его ограниченное время. Если ссылка открыта в другом профиле того же аккаунта, страница сама переходит в профиль ключа. Новой доске подготовка может сразу выбрать аудиторию «Адресно» (с адресами приглашений) или «По ссылке»: приглашения и секретную ссылку выдаёт то же подтверждение человека, и адрес ссылки видит только он. Область boards:read подготовку не создаёт, а boards:publish не открывает чтение досок: это разные права одного ключа.

Безопасность

  • Токен хранится в виде хэша — платформа не может его восстановить.
  • Храните токен в секрете (переменные окружения, секрет-менеджер), не коммитьте в репозиторий.
  • При утечке немедленно отзовите ключ и создайте новый.
  • Ключ действует строго в рамках своего профиля и выданных прав.

SDK для Node.js и Python

Для интеграции можно использовать API SDK Искры. Он поддерживает чат, фоновые задачи, файлы, навыки, специалистов и Память; Python-клиент доступен в синхронном и асинхронном вариантах. Инструкции установки из публичного исходника и примеры находятся в README соответствующего пакета. Передайте ключ и адрес своей установки явно. Для фотографий и длительных заданий используйте загрузку файла и асинхронный прогон.

Telegram-бот Искры

Облачный бот — @youriskrabot. Подключите свой API-ключ через защищённую форму /connect в личном чате: для общения нужно chat:run, для навыков — skills:run, для уведомлений — agenda:read.

Подключение, голосовые и файлы, группы и Reply, контекст, команды, ход выполнения и ошибки оплаты описаны в руководстве Telegram-бота.