Документация › Для разработчиков › Публичный API

Публичный API и ключи dos_sk_live_…

Обновлено 31 октября 2026 г.

[для разработчиков] Дёргай платформу из своего кода: API-ключ dos_sk_live_… авторизует запросы как тебя самого, с теми же правами на проекты, что и в браузере.

⏱ 8 мин · 👤 для разработчика · 🟢 live

За 30 секунд:
  • Ключ формата dos_sk_live_…, передаётся в заголовке Authorization: Bearer ….
  • Ключ работает от имени твоего аккаунта: действуют те же роли/доступы, что и в кабинете.
  • Ключи бывают read и read+write, на весь аккаунт или на один проект.
  • Хранится только SHA-256-хеш, сырой ключ показывается один раз при создании. Потерял, выпусти новый.
Раздел «Для разработчиков»: выпуск и управление API-ключами
Раздел «Для разработчиков»: выпуск и управление API-ключами

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

В кабинете → управление API-ключами → создать. При создании:

  • задаёшь права: только чтение (read) или чтение+запись (read+write);
  • задаёшь область: весь аккаунт (все твои проекты) или один проект;
  • опционально, срок жизни (1-365 дней).
🔑 Сырой ключ виден ОДИН раз. Платформа хранит только его SHA-256-хеш и не может показать ключ повторно. Скопируй сразу в надёжное место. Потерял, просто отзови и выпусти новый.

Лимиты: до 50 ключей на аккаунт; запросы по ключу до 120 в минуту (при превышении API вернёт 429 Too Many Requests, сделайте паузу и повторите). Управлять ключами можно только из браузера (залогиненная сессия), сам ключ не может создавать другие ключи (защита от эскалации прав).


Использование

Передавай ключ в заголовке:

Authorization: Bearer dos_sk_live_…

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

СвойствоПоведение
Праваread: только GET; write, позволяет POST/PUT/PATCH/DELETE. Ключ только для чтения на мутирующем запросе → отказ
Областьaccount-scoped (все проекты) или project-scoped (заблокирован на один)
RBACнаследует роли твоего аккаунта на проектах, не выше
Отзывотозванный ключ перестаёт работать сразу

Базовый адрес: https://dosai.pro. Пример запроса:

curl https://dosai.pro/api/projects \
  -H "Authorization: Bearer dos_sk_live_…"

Машиночитаемое описание

АдресЧто это
https://dosai.pro/api/openapi.jsonПолная спецификация OpenAPI 3.1: все эндпоинты, параметры, коды ошибок. Открыта без ключа, подходит для генераторов клиентов и Postman
https://dosai.pro/llms.txtКороткая памятка для ИИ-агентов: что за платформа, как авторизоваться, куда идти дальше
https://dosai.pro/api/mcpMCP-сервер: тот же каталог как готовые инструменты для Claude Code, Codex и Cursor. См. Подключить ИИ-агента

Каталог эндпоинтов

Все пути, относительно https://dosai.pro, авторизация, Authorization: Bearer dos_sk_live_… (мутирующие запросы требуют ключ с правом write).

Проекты

МетодПутьЧто делает
GET/api/projectsСписок всех проектов пользователя
POST/api/projectsСоздать новый проект: { name, company_name, industry, … }
GET/api/projects/:idПолучить проект по ID
PATCH/api/projects/:idОбновить проект
DELETE/api/projects/:idУдалить проект

Лиды

МетодПутьЧто делает
GET/api/projects/:id/leadsСписок лидов. Query: page, limit, status (none/potential/qualified/hot/converted/reserve/lost), before (курсор)
GET/api/projects/:id/leads/:leadIdПолучить лид по ID
PATCH/api/projects/:id/leads/:leadIdОбновить лид: { lead_status, client_name, phone, email }
DELETE/api/projects/:id/leadsМассовое удаление: { ids: string[] }
GET/api/projects/:id/leads/exportЭкспорт лидов в CSV
GET/api/projects/:id/lead-statusesСтатусы воронки проекта
GET/api/projects/:id/leads/:leadId/activityИстория лида
GET/api/projects/:id/leads/:leadId/remindersНапоминания по лиду
POST/api/projects/:id/leads/:leadId/remindersПоставить напоминание: { due_at, note? }
GET/api/projects/:id/tagsТеги проекта

Записи (подтверждение и напоминания)

Если клиент записывается у вас в CRM, на сайте или в сервисе записи, ваша система сообщает нам о записи одним запросом, а платформа сама подтверждает её клиенту в WhatsApp или Telegram и напоминает перед визитом. Тексты и сроки владелец задаёт в кабинете: Автоматизации → Записи (подробно).

МетодПутьЧто делает
POST/api/projects/:id/bookingsСоздать или обновить запись: { external_id, phone, client_name, service, start_at, end_at?, status?, confirm? }. Повтор того же external_id обновляет, новое start_at переносит, status: "cancelled" отменяет
GET/api/projects/:id/bookingsСписок записей с планом сообщений. Query: status (upcoming/past/cancelled/all), from, to, q, page, limit
GET/api/projects/:id/bookings/:externalIdОдна запись по вашему номеру и её сообщения
DELETE/api/projects/:id/bookings/:externalIdОтменить запись: ожидающие сообщения снимаются
GET/api/projects/:id/booking-settingsНастройки подтверждения и напоминаний
PATCH/api/projects/:id/booking-settingsИзменить настройки: { enabled, confirmation: { enabled, text }, reminders: [{ offset_minutes, text? }], template }

Пример: ваша CRM создала запись.

curl -X POST https://dosai.pro/api/projects/<id проекта>/bookings \
  -H "Authorization: Bearer dos_sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"A-1024","phone":"+77011234567","client_name":"Анна","service":"Маникюр","start_at":"2026-09-23 15:00"}'

Что важно знать программисту:

  • Время без смещения (2026-09-23 15:00) читается по часовому поясу проекта. В ответе есть start_at_local: сверьте, так ли мы поняли время.
  • Писать первыми можно только знакомым. Поле contact в ответе это подсказка на момент записи, перед каждой отправкой проверка повторяется:
  • known: сообщения уйдут;
  • unknown: человек ни разу не писал на номер WhatsApp проекта. Запись сохранена, но первыми мы ему не пишем, так номер не заблокируют. Такие записи видны в кабинете с кнопкой «Написать со своего телефона»;
  • unverified: проверить не удалось прямо сейчас (например, канал проекта в этот момент офлайн), платформа попробует позже;
  • instagram: у Instagram окно ответа 24 часа, напоминание за сутки туда не пролезет.
  • Ночью не пишем: сообщения уходят с 9:00 до 21:00 по часам проекта. Ночное напоминание уходит накануне в 20:30.
  • Подтверждение не уходит, если в этом чате за последние 30 минут был разговор (клиент только что записался через бота). confirm: false выключает его явно, если ваша система подтверждает сама.
  • Ключ нужен со скоупом write. Лимит 120 запросов в минуту.

Диалоги

МетодПутьЧто делает
GET/api/projects/:id/conversationsСписок диалогов. Query: page, limit, status (open/resolved/closed), include_archived, kind (direct человек / group группа WhatsApp), before (курсор: pagination.next_before прошлой страницы)
POST/api/projects/:id/conversationsОткрыть диалог WhatsApp по номеру: { phone, name? }. Ничего не отправляет, только заводит диалог и отдаёт его; бот в нём выключен причиной «чат начал оператор». Уже существующий диалог возвращается как есть (created: false)
GET/api/projects/:id/conversations/:convIdДетали диалога
PATCH/api/projects/:id/conversations/:convIdИзменить диалог: { client_name, phone, tags[], status, archived_at, pinned_at }
GET/api/projects/:id/conversations/:convId/messagesСообщения диалога. В группе WhatsApp у входящих есть автор: author_name, author_phone, author_is_admin
POST/api/projects/:id/conversations/:convId/sendОтправить сообщение от оператора: { text: string }, опционально заголовок Idempotency-Key (повтор того же ключа 5 минут = 409; если канал отказал и сообщение точно не ушло, ключ сразу свободен и повтор пройдёт). Ответ 200 ещё не значит «доставлено»: смотрите поле ok. Ночью (с 21:00 до 9:00 по часам проекта) программа не пишет незнакомым: в группу и тому, кто сам писал в этот диалог за последние 90 дней, можно; остальным ответ 409 NIGHT_WINDOW с полем retry_at, сообщение не отправлено (из кабинета человек пишет когда угодно)
POST/api/projects/:id/conversations/:convId/send-mediaОтправить клиенту файл из медиатеки проекта: { media_id, caption? }, id файлов даёт /api/projects/:id/media. Тот же Idempotency-Key и то же правило про ok, что у текста
POST/api/projects/:id/messages/:messageId/transcribeРасшифровать голосовое и сохранить текст в диалоге (content станет 🎤Распознано: …). Платно, с баланса проекта
GET/api/projects/:id/conversations/ai-pausedСколько диалогов бот сейчас не ведёт: { count }
POST/api/projects/:id/conversations/:convId/toggle-aiПереключить бота в одном диалоге (вкл ↔ выкл), ответ { ai_on } после переключения
GET/api/projects/:id/conversations/:convId/notesВнутренние заметки к диалогу
POST/api/projects/:id/conversations/:convId/notesДобавить заметку: { body }
GET/api/projects/:id/conversations/:convId/scheduledОтложенные сообщения клиенту
POST/api/projects/:id/conversations/:convId/scheduledЗапланировать сообщение клиенту: { text, send_at } (от минуты до 31 дня). send_at ночью по часам проекта (21:00-9:00) по ключу API принимается только для группы и того, кто сам писал за последние 90 дней, иначе 409 NIGHT_WINDOW, ближайшее дневное время в retry_at
GET/api/projects/:id/conversations/:convId/searchПоиск по сообщениям одного диалога. Query: q
GET/api/projects/:id/broadcastsРассылки и их итоги. С count=1 это предпросмотр: сколько человек получат, кто пропущен и почему, сколько займёт отправка. Query: count, channel, window_days, lead_status, tag, campaign
POST/api/projects/:id/broadcastsЗапустить рассылку по своей базе: { body, title?, channel?, consent_confirmed?, body_variants?, paraphrase?, media?, buttons?, scheduled_at?, segment? }. Для WhatsApp обязателен consent_confirmed: true. Пишет живым людям, отменить отправленное нельзя
PATCH/api/projects/:id/broadcastsОстановить или продолжить рассылку: `{ id, action: "cancel" \"resume" }`
GET/api/projects/:id/broadcasts/settingsТемп и потолки рассылок проекта: дневной потолок, прогрев, пауза между сообщениями, окно давности, предохранители
PATCH/api/projects/:id/broadcasts/settingsПоменять темп и потолки. Значения выше платформенного потолка обрезаются, а не отклоняются

Группа WhatsApp это такой же диалог. У группы, в которой включён бот, есть своя строка в том же списке: kind: "group", chat_id вида wg_<id группы>, название группы в chat_name, телефона нет. Читается через /conversations/:convId/messages (у каждого входящего есть автор), пишется через /conversations/:convId/send - сообщение уйдёт в группу от номера проекта, его увидят все участники. Найти диалог по адресу группы можно в /api/projects/:id/baileys/groups?live=1: у включённой группы есть поле conversationId. Бот видит только группы, включённые в кабинете (Каналы → WhatsApp → «Группы»), и из остальных сообщения не сохраняются.

Голосовые, когда бот выключен. Пока бот в диалоге выключен, голосовые клиента не расшифровываются: это решение, а не сбой, иначе владелец платил бы за текст, который может никто не прочитать. В сообщении лежит заглушка «[Голосовое сообщение]» и media_url - постоянная подписанная ссылка на сам файл, она открывается без ключа. Нужны слова, а не файл: POST /api/projects/:id/messages/:messageId/transcribe расшифрует одно сообщение и сохранит текст в диалоге. Когда бот включён, он расшифровывает голосовые сам перед своим ответом, включая те, что накопились за время паузы.

Чата с человеком может ещё не быть. Диалог появляется на первом сообщении (от клиента или от владельца с телефона), поэтому у свежеподключённого номера старых переписок в кабинете нет: WhatsApp на привязке отдаёт список чатов, а тексты только по свежим. Чтобы написать такому человеку, откройте диалог по номеру (POST /api/projects/:id/conversations) и отправьте сообщение обычным способом; прежняя переписка подтянется с телефона сама на первом сообщении в чате.

Функции ассистента

МетодПутьЧто делает
GET/api/projects/:id/functionsСписок функций бота. Значения секретов (токены, ключи) маскируются сервером

Интеграции

МетодПутьЧто делает
GET/api/projects/:id/integrationsСписок интеграций
POST/api/projects/:id/integrationsСоздать интеграцию (webhook): { name, type, url, events[], headers? }
PUT/api/projects/:id/integrations/:intIdИзменить интеграцию: те же поля, что при создании
DELETE/api/projects/:id/integrations/:intIdУдалить интеграцию

Какие значения принимает events[], перечислено в статье про вебхуки и в самом описании API (поле events у подписки): неизвестное событие отклоняется с ошибкой 400. Самое частое для своего сервера это message_inbound: уходит на каждое входящее сообщение сразу, не дожидаясь ответа бота, в личных чатах и в группах.

Аналитика и отчёты

МетодПутьЧто делает
GET/api/projects/:id/analyticsСтатистика проекта это query from, to (YYYY-MM-DD)
GET/api/projects/:id/reportsСкачать PDF-отчёт за месяц, query period=2026-03
GET/api/projects/:id/analytics/funnelВоронка, источники и когорты за период (по умолчанию 30 дней). Query: from, to
GET/api/projects/:id/logsЖурнал событий. Query: category, search, dateFrom, dateTo, event_type, before, limit, page
GET/api/projects/:id/report-configОтчёты по расписанию (владелец)

Биллинг

МетодПутьЧто делает
GET/api/projects/:id/tokensБаланс токенов проекта
GET/api/projects/:id/tokens/historyИстория транзакций
GET/api/projects/:id/payments/invoicesСчета клиентам бизнеса (только просмотр). Query: page, per_page, status

Бот, база знаний, функции и автоматизации

Эти же маршруты зовут кнопки кабинета и ИИ-ассистенты (ChatGPT, Claude по кнопке «Разрешить»), поэтому ответы приходят в том виде, в каком их получает экран кабинета.

МетодПутьЧто делает
GET/api/projects/:id/overview-insightsНеделя против прошлой (диалоги, лиды, % изменения), лиды по статусам, минуты с последнего диалога и лида
GET/api/projects/:id/baileys/statusСостояние WhatsApp-номера проекта
GET/api/projects/:id/telegram/statusСостояние Telegram-бота
GET/api/projects/:id/agent-configНастройки бота: кому отвечает, расписание, буфер, пауза оператора, дожимы, память
PUT/api/projects/:id/agent-configИзменить настройки: только нужные ключи, ответ это настройки целиком
GET/api/projects/:id/prompt-versionsСохранённые версии системного промпта
POST/api/projects/:id/test-chatСпросить бота в тест-чате как клиент: { message, history? }, списывает с баланса как обычный ответ
GET/api/projects/:id/knowledgeДокументы базы знаний. Query: limit, offset
POST/api/projects/:id/knowledgeДобавить документ: { name, file_type, content?, file_url? }
PATCH/api/projects/:id/knowledge/:kbIdВключить или выключить документ, переименовать, прикреплять к каждому ответу: { is_active?, always_include?, name? }
GET/api/projects/:id/knowledge/:kbId/chunksТекст документа кусками, как его видит бот
GET/api/projects/:id/mediaМедиатека, которую бот отправляет клиентам
GET/api/projects/:id/functions/:funcIdОдна функция, секреты замаскированы
PATCH/api/projects/:id/functions/:funcIdИзменить функцию: { name, description, parameters[], is_active, silent_after_call, read_only }. description это то, по чему модель решает, когда звать функцию; parameters заменяют прежний список целиком; silent_after_call: true значит «после вызова клиенту не отвечать» (ничего не отправляется, диалог помечается «ответьте руками»); read_only: true значит «только ищет, ничего не меняет» (после такой функции бот дожидается дописки клиента и отвечает одним сообщением; только у функции-запроса, не вместе с «Это заявка», «не отвечать», «завершать диалог» и «создаёт запись»)
GET/api/projects/:id/functions/:funcId/executionsПоследние вызовы функции. Query: limit
GET/api/projects/:id/functions/healthВызовы, ошибки и доля успешных по каждой функции. Query: range (24h/7d/30d)
GET/api/projects/:id/dripКлиенты в дожимах. Query: page, limit
GET/api/projects/:id/drip/statsРезультаты дожимов по статусам и касаниям
GET/api/projects/:id/automationsПравила «когда, если, то»
PATCH/api/projects/:id/automationsВключить или выключить правило: { ruleId, is_active }
GET/api/projects/:id/automations/runsКогда правила сработали. Query: limit, kind
GET/api/help/articlesОглавление этого руководства: название, ссылка, выжимка (для ИИ-ассистентов, отвечающих «как сделать»)

Лимиты запросов

  • API-ключ: до 120 запросов/мин на ключ; сверх: 429 Too Many Requests.
  • Ориентиры по типам: GET ≈ 30-60/мин, POST/PATCH ≈ 10-30/мин, PDF-отчёты ≈ 5/мин (точные значения у каждого роута свои).
  • В каждом ответе, заголовки X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset; при 429 ещё и Retry-After (секунды до сброса).

Безопасность ключа

  • Это пароль доступа к твоим проектам: храни как секрет, не коммить в репозиторий, не клади в открытый фронтенд.
  • Светанул ключ, немедленно отзови и выпусти новый.
  • Для интеграции, которой нужно только читать, выдавай read-only ключ.
  • Нужен доступ только к одному проекту это делай project-scoped ключ, не account-wide.

Простыми словами

Если ты разработчик и хочешь дёргать платформу из своего кода, заводишь API-ключ. Это длинная строка вида dos_sk_live_…, которую ты прикладываешь к запросам в заголовке Authorization. Важная идея: ключ это «ты в виде кода». Он видит ровно те проекты и умеет ровно то, что и ты сам в кабинете, не больше. Хочешь дать интеграции только читать, выпусти ключ «только чтение». Хочешь ограничить одним проектом: выпусти ключ на этот проект.

Главное правило безопасности: ключ показывается один-единственный раз при создании, мы храним только его «отпечаток» и заново показать не сможем. Скопировал, сохранил надёжно. Потерял или засветил, не страшно, заходишь и отзываешь, выпускаешь новый. И никогда не клади такой ключ в открытый код или фронтенд: это как пароль.


Дальше: → Кастомные вебхуки
Связано: Роли и права · Формат данных
Не получилось? → напиши в саппорт