Сделки
CRM-слой AISAR: сделки, привязанные к воронкам и стадиям, задачи по сделкам (звонки, встречи, follow-up), справочники типов сделок и причин отказа. Владение сделкой/задачей всегда проверяется по company_id — обращение к чужой записи возвращает 404, а не 403. Все эндпоинты требуют активную подписку и фичу плана deals.
Список сделок: фильтры и отсутствие пагинации
GET /deals принимает необязательные query-параметры contact_id, funnel_id, responsible_user_id (целые числа ≥ 1), status (ровно одно из open, won, lost) и search (строка до 100 символов, регистронезависимое вхождение в название сделки либо в отображаемое имя её контакта). Фильтры комбинируются по «И»; пустая строка в любом из них равносильна отсутствию фильтра. Массив вместо скаляра (status[]=open) или значение вне перечисления дают 422 — тихого игнорирования параметров нет. Все фильтры применяются строго внутри компании вызывающего: contact_id чужой компании — это не 403 и не утечка, а просто пустой список.
GET /deals не постраничный: он возвращает все подходящие сделки компании одним плоским массивом {"data": [...]} (сортировка — по updated_at по убыванию, при равенстве — по id по убыванию), без блока pagination. Для сделок одного контакта используйте постраничную альтернативу GET /v1/contacts/{contact}/deals (параметр perPage, ответ в формате data.items + data.pagination) — она ходит по той же связи deals.contact_id, поэтому результаты обоих эндпоинтов согласованы.
С 2026-09-29 у GET /deals два новых необязательных параметра. perPage (целое 1–100) — не пагинация, а потолок: ответ остаётся тем же плоским массивом без pagination, просто в нём не больше perPage последних по updated_at сделок; без параметра список, как и раньше, полный. include_unsorted (boolean) — включить в список лиды из «Неразобранного» (см. ниже): по умолчанию они в GET /deals не попадают. Исключение — запрос с фильтром contact_id: сделки одного контакта отдаются вместе с его неразобранным лидом и без флага, так же как в GET /v1/contacts/{contact}/deals.
Согласованность воронки и стадии
Обновление сделки (POST /deals/{deal}) подчиняется правилам согласованности воронки и стадии: смена funnel_id требует явного funnel_stage_id в том же запросе (иначе 422 «A funnel_stage_id is required when changing funnel_id.» — прежний тихий переход на первую стадию убран), а сам funnel_stage_id должен принадлежать выбранной воронке (иначе 422 «Selected stage does not belong to the selected funnel.»). Если сменить стадию без явного status, статус выводится из типа стадии: success→won, failed→lost, прочее→open.
Закрытие сделки: won и lost
Перевод status в lost (в том числе неявный — при переходе в стадию типа failed) требует lost_reason_id из справочника причин либо свободного lost_reason (иначе 422 «A lost reason is required when marking a deal as lost.»); переход в won/lost фиксирует снимок closed_amount/closed_currency на момент закрытия, а возврат в open очищает closed_at, lost_reason, lost_reason_id и снимок сумм.
Удаление и восстановление
Удаление сделки — мягкое (deleted_at, ID и связи диалогов сохраняются), а POST /deals/{deal}/restore (право deal.delete) восстанавливает её идемпотентно.
Авто-лиды и «Неразобранное»
С 2026-09-29 сделку из диалога автоматически создаёт единая точка решения «авто-лид». Повод — только живое входящее обращение клиента: входящее сообщение, входящий звонок (в том числе пропущенный) или первое сообщение посетителя в виджете на сайте. Диалог, который открыла сама компания (оператор, API, рассылка, первое исходящее с телефона), лида не создаёт вовсе: ответ клиента в таком диалоге — это ответ, а не обращение. Не создают лид и групповые чаты, скрытые из inbox и заблокированные контакты, контакты с исключением auto_lead_excluded_at, импорт истории, входящие старше суток (переподключённый канал досылает накопленное), а также диалоги без сделки, начатые до включения авто-лидов. Как именно создаётся сделка, задаёт auto_lead_mode в настройках компании (см. «Справочники и настройки»).
В режиме unsorted авто-лид ложится в «Неразобранное» — виртуальную первую колонку своей воронки. У такой сделки заполнено unsorted_at (не null ⇔ лид ждёт разбора); lead_conversation_id у любого авто-лида (в обоих режимах) — id диалога, из которого он родился, у сделок, созданных человеком, API или автоматизацией, — null. Оба поля есть в полном объекте сделки (ответы /deals, /deals/{deal}, /contacts/{contact}/deals), а unsorted_at — ещё и во вложенной сделке диалога и треда. Лид из «Неразобранного» не входит в колонки доски, в их deals_count/total_amount и в постраничную загрузку стадии: его отдаёт только GET /v1/funnels/{funnel}/unsorted, а доска показывает лишь счётчик unsorted.count (см. группу «Воронки»). По контакту лид виден: GET /v1/contacts/{contact}/deals и GET /deals?contact_id= его включают.
Пока лид не принят, его нельзя закрыть или перенести обычной правкой: POST /deals/{deal} с любым из ключей status, funnel_id, funnel_stage_id отвечает 409 {"data": {"message": "The deal is in Unsorted: accept it first."}}. Остальные поля (название, сумма, ответственный и т. д.) меняются как обычно. MCP-инструменты update_deal/move_deal_stage на такой сделке возвращают ошибку инструмента, а узел автоматизации «Перевести сделку на этап» завершается как skipped с причиной deal_unsorted.
Разбирают «Неразобранное» три маршрута, все с правом deal.update (у оператора, который видит колонку через deal.view, — 403) и лимитом 30 запросов в минуту. Сделка другой компании — 404; лид, который уже разобрал кто-то другой (или он больше не в «Неразобранном», или закрыт), — 409 «The deal is not in Unsorted.». `POST /deals/{deal}/accept` — «Принять»: необязательные funnel_stage_id (открытый этап воронки лида — не success/failed, иначе 422 «The stage must be an open stage of the lead's funnel.»; по умолчанию первый открытый этап) и responsible_user_id (человек-участник компании, сервисный аккаунт не подходит — 422; по умолчанию вызывающий). unsorted_at очищается, в ленту пишется lead_accepted, ответ — объект сделки. `POST /deals/{deal}/decline` — «Отклонить»: мягкое удаление лида (восстановленный через restore лид возвращается в «Неразобранное»); с exclude_contact: true (нужно ещё право contact.update, иначе 403) контакту ставится исключение из авто-лидов с auto_lead_excluded_via: "decline". В ленту пишется lead_declined, ответ — {"data": {"declined": true}}. `POST /deals/{deal}/link` — «Привязать»: обязательный target_deal_id — открытая, не удалённая и уже разобранная сделка своей компании (иначе 422); все диалоги лида переходят в неё, сам лид мягко удаляется, у целевой сделки в ленте появляется lead_linked, ответ — объект целевой сделки. Привязать лид к самому себе нельзя (422 «A lead cannot be linked to itself.»).
Наружу лид из «Неразобранного» не уходит, пока его не приняли: ни вебхука deal.created, ни deal.updated при правках, ни триггера автоматизаций deal-created, ни синхронизации с Битрикс24. «Принять» и есть рождение сделки для интеграций: уходят вебхук deal.created и триггер deal-created, сделка и её дело уходят в Битрикс24, а назначенный ответственный (если это не тот, кто принял) получает уведомление deal_assigned. «Отклонить» и «Привязать» наружу не шлют ничего — в том числе deal.deleted. В вебхуках message.created и conversation.* поле conversation.deal_id пустое (null), пока сделка диалога — неразобранный или отклонённый лид.
Ответственный авто-лида — ответственный за контакт, если его нет — сотрудник, назначенный на диалог; если нет и его, ответственным открытой сделки диалога становится первый сотрудник, который подключится к диалогу (в ленте — responsible_changed без actor). Сотрудники с правом deal.update получают сгруппированное по воронке in-app уведомление lead_unsorted о новых лидах в «Неразобранном».
Таймлайн активности
GET /deals/{deal}/activities отдаёт append-only таймлайн со type из набора created|stage_changed|field_changed|note|task_created|task_completed|won|lost|responsible_changed|system; у системных записей (автоматизации, ИИ-инструменты, инбаунд Bitrix24) actor — null.
С 2026-09-29 к набору добавлены четыре типа авто-лидов: inbound_repeat — живое обращение клиента прикреплено к уже открытой сделке вместо новой (metadata: conversation_id, channel_type, trigger — message, call или widget); lead_accepted — лид принят из «Неразобранного» (metadata: funnel_stage_id, responsible_user_id); lead_declined — лид отклонён, запись делается перед мягким удалением (metadata.exclude_contact); lead_linked — пишется у целевой сделки, к которой привязали лид (metadata: source_deal_id, conversation_ids). Правки сделки ИИ-агентом помечаются в metadata строк stage_changed/field_changed/responsible_changed ключами actor: "ai_agent" и ai_agent_instance_id.
Поле source сделки — откуда она появилась: manual, api, whatsapp, telegram, instagram, bitrix24, voice (голосовой ИИ-агент во время звонка), а с 2026-09-29 ещё messenger, live_chat, phone и other. Источник авто-лида выводится из типа канала: whatsapp/whatsapp_business → whatsapp, telegram/telegram_bot → telegram, instagram/instagram_business → instagram, facebook_messenger → messenger, live_chat → live_chat, sip_telephony → phone, любой другой → other.
Задачи по сделкам
Задачи по сделкам обновляются методом PATCH /deal-tasks/{task} (легаси /deals/{deal} осознанно остаётся на POST): поле overdue — производное (due_at < now() при status=open; «сейчас» и границы дня считаются в часовом поясе компании), закрытие (done/cancelled) фиксирует completed_at, а назначение задачи на другого человека шлёт ему in-app уведомление task_assigned (прежний тип deal_task_assigned больше не отправляется).
GET /deal-tasks (с 2026-09-26) принимает: scope — visible (по умолчанию: всё, что вызывающему разрешено видеть), mine (назначенные на меня), unassigned (ничьи) или all (требует права deal_task.view_all, без него — 403); bucket — overdue, today, tomorrow, week, later, no_date (открытые задачи в соответствующем окне по сроку) или done (закрытые как done за последние 7 дней); status (open|done|cancelled), type (call|meeting|follow_up|todo), assigned_user_id, contact_id, deal_id, search (до 100 символов, регистронезависимое вхождение в название задачи, имя контакта или название сделки), sort (due_at|created_at), а также прежние overdue, due_before, due_after и mine=1 (равносильно scope=mine). Пагинация — page/perPage (5–100, по умолчанию 20). Любой фильтр только сужает видимую область и никогда её не расширяет. Запрос с непустым search ограничен 30 в минуту на пользователя.
Видимость задач: держатель права deal_task.view_all (администратор, менеджер) видит все задачи компании; без него (оператор) — задачи, назначенные на него, созданные им, и ничьи. Если правила доступа к каналам (channel_access команд) закрывают пользователю часть каналов, чужие и ничьи задачи по контакту видны ему, только если у контакта нет диалогов или хотя бы один его тред лежит в доступном канале; свои задачи видны всегда. Задачи сделок в корзине не видны никому. Задача вне видимой области отвечает 404 и на чтение, и на запись — существование чужой задачи не раскрывается.
Построчные права оператора (без deal_task.view_all): при создании и изменении assigned_user_id может быть только он сам или null — иначе 403 «You may only assign a task to yourself or leave it unassigned.»; менять и удалять можно только свои задачи (назначенные на него или созданные им); ничью задачу, созданную другим, можно лишь «взять себе» — PATCH с телом ровно {"assigned_user_id": <мой id>}, любое другое тело по такой задаче даёт 404. Держатель deal_task.view_all назначает на любого участника компании. Для удобства клиента каждая задача несёт готовые флаги can_update и can_delete.
Поля POST/PATCH /deal-tasks: помимо прежних (deal_id, contact_id — только своей компании, type, title до 255 символов, description — теперь до 10 000 символов, due_at, remind_at, assigned_user_id, status для PATCH) добавлены is_all_day (boolean), reminder_disabled (boolean) и remind_offset_minutes (0, 15, 60 или 1440, либо null). remind_at позже срока (due_at из тела, а в PATCH без него — текущего срока задачи) отклоняется с 422 «The reminder may not be later than the deadline.». Успешное создание отвечает 201.
Объект задачи (DealTaskResource) сохраняет все прежние ключи и дополнительно отдаёт: is_all_day, reminder_disabled, remind_offset_minutes, duration_minutes (длительность в минутах, 5–720, или null; задаётся в POST/PATCH, ставится ИИ-записью на приём), reminded_at, snoozed_until, is_overdue (то же, что overdue), created_by и created_by_user ({id, name} или null), source (human — создана человеком через API, automation — узлом автоматизации, ai — ИИ-агентом, null — источник неизвестен), conversation_id (последний активный диалог контакта, но только если вызывающий может его открыть, иначе null), can_update, can_delete, а также вложенные deal ({id, title, deleted}), contact ({id, display_name}) и assigned_user ({id, name}).
GET /deal-tasks/counters (и часть tasks_counters в GET /bootstrap) дополнительно отдаёт done_today — число задач видимой области, закрытых сегодня (по часовому поясу компании), и mine.done_today — то же по исполнителю-вам. В отличие от остальных счётчиков, считаются закрытые, а не открытые задачи.
Новые маршруты: GET /deal-tasks/{task} — одна задача (вне видимой области — 404); GET /deal-tasks/counters — без параметров, отдаёт {overdue, today, upcoming_7d, unassigned, mine: {overdue, today}} по открытым задачам видимой области (60 запросов в минуту на пользователя); GET /deal-tasks/calendar?from&to — компактные элементы задач со сроком в окне [from, to) (окно не больше 42 дней, иначе 422; фильтры scope, type, status, assigned_user_id, contact_id), не более 1000 штук, при превышении truncated: true; POST /deal-tasks/{task}/snooze — «напомнить позже»: тело {"minutes": 15|60} либо {"until": "<ISO-время>"} (в будущем, не дальше 31 дня); сдвигает только snoozed_until, срок и remind_at не трогает; права — как у PATCH (чужая — 404), закрытая задача — 409 с error: task_not_open.
Уведомления и realtime: назначение шлёт task_assigned, наступление времени напоминания — task_reminder одному получателю — первому подходящему по цепочке «исполнитель → ответственный сделки → ответственный контакта → автор задачи» (подходящий = участник компании с правами deal_task.view и deal_task.update, которому задача видна); если подходящих нет, каждый держатель deal_task.view_all получает одну сгруппированную за день строку task_reminder_unassigned. Любое изменение задачи (любым источником) публикуется событием deal_task.changed в private-company.{companyId} с намеренно бедным payload {task_id, action, assigned_user_id} (action — created, updated или deleted) — клиент перечитывает свои запросы со своими правами (см. «Realtime-события»). Узел автоматизации «Создать задачу» (create-task) теперь создаёт настоящую задачу (раньше — приватную заметку в диалоге): task_type (по умолчанию follow_up), assignee — id пользователя своей компании (иначе задача остаётся ничьей), due_in_hours, привязка к открытой сделке диалога; поле priority больше не используется.
GET /deals/{deal}/tasks по-прежнему отдаёт все задачи сделки любому, кто видит сделку, без сужения «мои/ничьи», но пользователю, которому правила доступа к каналам закрывают часть каналов, не показываются задачи по контактам, у которых есть диалоги и ни один тред не лежит в доступном ему канале.
Справочники и настройки
Причины отказа (/lost-reasons; изменение — право lost_reason.manage) уникальны по имени в рамках компании. Настройки авто-создания (/company/deal-settings) отдают уже приведённое default_currency (дефолт KZT, если в БД null); включить auto_create_deal_enabled без единой воронки в компании нельзя (422).
С 2026-09-29 настройки авто-лидов (GET /company/deal-settings — право deal.view, POST — deal_settings.manage) дополнены полями, которые всегда отдаются уже приведёнными значениями: auto_lead_mode — off (сделки только вручную, автоматизацией или ИИ-агентом), unsorted (авто-лид в «Неразобранное») или direct (сразу в первый этап воронки); repeat_contact_policy — что делать с обращением клиента, у которого уже есть открытая сделка: attach_open (по умолчанию — прикрепить к последней обновлённой открытой сделке контакта, в том числе к неразобранному лиду) или always_new (новый диалог — новая сделка; блокирует только открытая сделка самого диалога); repeat_cooldown_hours — пауза по контакту после закрытия его сделки или отклонения его лида, целое от 0 до 720, по умолчанию 24, 0 — без паузы. Только для чтения — crm_lead_integrations: активные интеграции Битрикс24 и amoCRM вида {type, instance_id, creates_leads}, где creates_leads: true значит, что интеграция сама создаёт лид на новое обращение (риск двойного лида). Воронка авто-лида: воронка канала из его CRM-настроек, иначе default_funnel_id, иначе первая воронка компании.
auto_lead_mode — источник истины, а auto_create_deal_enabled остаётся его зеркалом (false ⇔ off) для старых клиентов: запрос только с auto_create_deal_enabled: false выключает авто-лиды, с true — сохраняет текущий режим, если он уже включён, иначе включает direct. Перевод из off в любой другой режим фиксирует момент включения: диалоги без сделки, начатые раньше, лида не получат. Новые компании создаются в режиме unsorted; у компаний, существовавших до 2026-09-29, режим следует прежнему переключателю: direct, если авто-сделка была включена, иначе off. Включить режим, отличный от off, без единой воронки нельзя — 422 {"data": {"message": "Cannot enable auto-create deal without at least one funnel."}}.
Массовые действия над сделками
POST /deals/bulk применяет одно действие к списку сделок. Тело: action — move_stage, assign или delete; deal_ids — от 1 до 100 уникальных id; для move_stage обязателен funnel_stage_id (стадия вашей компании), а при переводе на стадию типа «проиграно» — lost_reason_id или lost_reason; для assign обязателен ключ responsible_user_id (id участника компании; null снимает ответственного). Права: deal.update для move_stage и assign, deal.delete для delete (без права отказ целиком — 403); токен встраиваемого виджета (embed) получает 403. Лимиты: 20 запросов в минуту на пользователя и 30 в минуту на компанию (429).
До 25 сделок включительно обрабатываются прямо в запросе: ответ 200 с data.operation_id, data.status (completed), data.results[] ({deal_id, result}, у validation_error есть ещё message), data.summary ({ok, failed}; unchanged считается успехом) и data.undo_available. Больше 25 — 202 с {operation_id, status: "queued"}; итог придёт realtime-событием deal.bulk.completed на пользовательский канал автора (см. гайд про realtime-события). Коды результата по каждой сделке: ok, unchanged (уже в нужном состоянии), not_found (нет такой сделки в компании), unsorted_locked (лид в «Неразобранном» — его сначала принимают), stage_mismatch (стадия не подходит сделке), validation_error, error. Каждая сделка проходит через обычную логику обновления/удаления, поэтому по ней срабатывают вебхуки deal.updated / deal.deleted с data.meta.bulk_operation_id и автоматизации.
POST /deals/bulk/{operation}/undo откатывает завершённое массовое move_stage или assign (для delete отмены нет — используйте POST /deals/{deal}/restore). Окно — 10 минут с момента операции, отменить может только её автор, повторно — нельзя; нужно право deal.update. Неизвестная, просроченная, чужая или уже отменённая операция — 404. Ответ: data.operation_id (id самой отмены), data.undo_of, data.status, data.results[] с кодами ok, changed_since (сделку уже меняли после операции — её не трогаем), not_found, validation_error, error и data.summary. Вебхуки отмены тоже несут meta.bulk_operation_id — id операции-отмены.
Эндпоинты
| Метод | Путь | Описание |
|---|---|---|
| GET | /v1/dealsСписок сделок без пагинации (фильтры: contact_id, funnel_id, responsible_user_id, status, search; include_unsorted — вместе с «Неразобранным»; perPage 1–100 — потолок числа записей) | Список сделок без пагинации (фильтры: contact_id, funnel_id, responsible_user_id, status, search; include_unsorted — вместе с «Неразобранным»; perPage 1–100 — потолок числа записей) |
| POST | /v1/dealsСоздание сделки | Создание сделки |
| POST | /v1/deals/bulkМассовое действие над сделками: move_stage | assign | delete (до 100 сделок; до 25 — сразу, больше — в очередь) | Массовое действие над сделками: move_stage | assign | delete (до 100 сделок; до 25 — сразу, больше — в очередь) |
| POST | /v1/deals/bulk/{operation}/undoОтмена массового move_stage/assign в течение 10 минут (только автор операции) | Отмена массового move_stage/assign в течение 10 минут (только автор операции) |
| GET | /v1/deals/{deal}Получение сделки | Получение сделки |
| POST | /v1/deals/{deal}Обновление сделки | Обновление сделки |
| DELETE | /v1/deals/{deal}Удаление сделки (soft delete) | Удаление сделки (soft delete) |
| POST | /v1/deals/{deal}/restoreВосстановление мягко удалённой сделки | Восстановление мягко удалённой сделки |
| GET | /v1/deals/{deal}/activitiesЛента активности сделки (таймлайн) | Лента активности сделки (таймлайн) |
| POST | /v1/deals/{deal}/notesДобавить заметку в таймлайн сделки | Добавить заметку в таймлайн сделки |
| GET | /v1/deals/{deal}/tasksЗадачи, привязанные к сделке | Задачи, привязанные к сделке |
| POST | /v1/deals/{deal}/acceptПринять лид из «Неразобранного» (funnel_stage_id?, responsible_user_id?) — для интеграций сделка рождается в этот момент | Принять лид из «Неразобранного» (funnel_stage_id?, responsible_user_id?) — для интеграций сделка рождается в этот момент |
| POST | /v1/deals/{deal}/declineОтклонить лид из «Неразобранного» (exclude_contact? — больше не создавать лиды по контакту) | Отклонить лид из «Неразобранного» (exclude_contact? — больше не создавать лиды по контакту) |
| POST | /v1/deals/{deal}/linkПривязать лид из «Неразобранного» к открытой сделке (target_deal_id) — диалоги переходят в неё, лид удаляется | Привязать лид из «Неразобранного» к открытой сделке (target_deal_id) — диалоги переходят в неё, лид удаляется |
| GET | /v1/company/deal-settingsНастройки авто-создания сделок компании (в т. ч. auto_lead_mode, repeat_contact_policy, repeat_cooldown_hours, crm_lead_integrations) | Настройки авто-создания сделок компании (в т. ч. auto_lead_mode, repeat_contact_policy, repeat_cooldown_hours, crm_lead_integrations) |
| POST | /v1/company/deal-settingsСохранение настроек авто-создания сделок и авто-лидов | Сохранение настроек авто-создания сделок и авто-лидов |
| GET | /v1/deal-tasksСписок видимых задач (scope: visible|mine|unassigned|all; фильтры: bucket, status, type, assigned_user_id, contact_id, deal_id, search, sort, overdue, mine) | Список видимых задач (scope: visible|mine|unassigned|all; фильтры: bucket, status, type, assigned_user_id, contact_id, deal_id, search, sort, overdue, mine) |
| POST | /v1/deal-tasksСоздание задачи | Создание задачи |
| PATCH | /v1/deal-tasks/{task}Обновление/закрытие задачи | Обновление/закрытие задачи |
| DELETE | /v1/deal-tasks/{task}Удаление задачи | Удаление задачи |
| GET | /v1/deal-tasks/countersСчётчики открытых задач: просрочено, сегодня, 7 дней, ничьи и свои, плюс закрытые сегодня | Счётчики открытых задач: просрочено, сегодня, 7 дней, ничьи и свои, плюс закрытые сегодня |
| GET | /v1/deal-tasks/calendarЗадачи со сроком в окне from–to (до 42 дней, до 1000 элементов) | Задачи со сроком в окне from–to (до 42 дней, до 1000 элементов) |
| GET | /v1/deal-tasks/{task}Получение одной задачи | Получение одной задачи |
| POST | /v1/deal-tasks/{task}/snoozeОтложить напоминание (minutes: 15|60 или until) | Отложить напоминание (minutes: 15|60 или until) |
| GET | /v1/deal-typesСписок типов сделок | Список типов сделок |
| POST | /v1/deal-typesСоздание типа сделки | Создание типа сделки |
| PATCH | /v1/deal-types/{dealType}Обновление типа сделки | Обновление типа сделки |
| DELETE | /v1/deal-types/{dealType}Удаление типа сделки | Удаление типа сделки |
| GET | /v1/lost-reasonsСписок причин отказа | Список причин отказа |
| POST | /v1/lost-reasonsСоздание причины отказа | Создание причины отказа |
| PATCH | /v1/lost-reasons/{lostReason}Обновление причины отказа | Обновление причины отказа |
| DELETE | /v1/lost-reasons/{lostReason}Удаление причины отказа | Удаление причины отказа |
Примеры
Массовый перевод сделок на другую стадию
Запрос
curl -X POST https://api.aisar.app/v1/deals/bulk \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"action": "move_stage",
"deal_ids": [501, 502, 503],
"funnel_stage_id": 12
}'Ответ
{
"data": {
"operation_id": "0b6f5e1c-3a52-4d0e-9d0a-8f3f2c6a1b77",
"status": "completed",
"results": [
{ "deal_id": 501, "result": "ok" },
{ "deal_id": 502, "result": "unchanged" },
{ "deal_id": 503, "result": "not_found" }
],
"summary": { "ok": 2, "failed": 1 },
"undo_available": true
}
}Список сделок контакта (фильтр contact_id)
Запрос
curl -X GET "https://api.aisar.app/v1/deals?contact_id=123&status=open" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 501,
"company_id": 1,
"contact_id": 123,
"funnel_id": 1,
"funnel_stage_id": 3,
"title": "Office renovation",
"amount": "5000.00",
"currency": "KZT",
"status": "open",
"type_id": null,
"source": "api",
"utm_source": null,
"utm_medium": null,
"utm_campaign": null,
"probability": null,
"comments": null,
"begin_date": null,
"responsible_user_id": 5,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"lost_reason_id": null,
"closed_amount": null,
"closed_currency": null,
"stage_changed_at": "2026-03-15T10:00:00.000000Z",
"unsorted_at": null,
"lead_conversation_id": null,
"channel": null,
"custom_fields": null,
"created_at": "2026-03-15T10:00:00.000000Z",
"updated_at": "2026-03-16T12:00:00.000000Z",
"contact": { "id": 123, "display_name": "Aigerim K.", "avatar": null },
"responsible_user": { "id": 5, "name": "Ivan" },
"conversations_count": 2
}
]
}Поиск сделок по названию или контакту
Запрос
curl -X GET "https://api.aisar.app/v1/deals?search=renovation&responsible_user_id=5" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": [
{
"id": 501,
"company_id": 1,
"contact_id": 123,
"funnel_id": 1,
"funnel_stage_id": 3,
"title": "Office renovation",
"amount": "5000.00",
"currency": "KZT",
"status": "open",
"responsible_user_id": 5,
"channel": null,
"created_at": "2026-03-15T10:00:00.000000Z",
"updated_at": "2026-03-16T12:00:00.000000Z",
"contact": { "id": 123, "display_name": "Aigerim K.", "avatar": null },
"responsible_user": { "id": 5, "name": "Ivan" },
"conversations_count": 2
}
]
}Создание сделки
Запрос
curl -X POST https://api.aisar.app/v1/deals \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"contact_id": 123,
"funnel_id": 1,
"funnel_stage_id": 3,
"title": "Office renovation",
"amount": "5000.00",
"currency": "KZT",
"source": "api",
"responsible_user_id": 5
}'Ответ
{
"data": {
"id": 501,
"company_id": 1,
"contact_id": 123,
"funnel_id": 1,
"funnel_stage_id": 3,
"title": "Office renovation",
"amount": "5000.00",
"currency": "KZT",
"status": "open",
"type_id": null,
"source": "api",
"utm_source": null,
"utm_medium": null,
"utm_campaign": null,
"probability": null,
"comments": null,
"begin_date": null,
"responsible_user_id": 5,
"expected_close_date": null,
"closed_at": null,
"lost_reason": null,
"lost_reason_id": null,
"closed_amount": null,
"closed_currency": null,
"stage_changed_at": "2026-03-15T10:00:00.000000Z",
"unsorted_at": null,
"lead_conversation_id": null,
"channel": null,
"custom_fields": null,
"created_at": "2026-03-15T10:00:00.000000Z",
"updated_at": "2026-03-15T10:00:00.000000Z"
}
}Перевод сделки в статус lost
Запрос
curl -X POST https://api.aisar.app/v1/deals/501 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "lost",
"lost_reason_id": 3
}'Ответ
{
"data": {
"id": 501,
"status": "lost",
"lost_reason_id": 3,
"lost_reason": null,
"closed_amount": "5000.00",
"closed_currency": "KZT",
"closed_at": "2026-03-17T09:00:00.000000Z",
"stage_changed_at": "2026-03-17T09:00:00.000000Z",
"updated_at": "2026-03-17T09:00:00.000000Z"
}
}Перевод сделки в lost (свободная причина)
Запрос
curl -X POST https://api.aisar.app/v1/deals/501 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "lost",
"lost_reason": "Ушли к конкуренту"
}'Ответ
{
"data": {
"id": 501,
"status": "lost",
"lost_reason_id": null,
"lost_reason": "Ушли к конкуренту",
"closed_amount": "5000.00",
"closed_currency": "KZT",
"closed_at": "2026-03-17T09:00:00.000000Z",
"stage_changed_at": "2026-03-15T10:00:00.000000Z",
"updated_at": "2026-03-17T09:00:00.000000Z"
}
}Смена воронки сделки (со стадией)
Запрос
curl -X POST https://api.aisar.app/v1/deals/501 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"funnel_id": 2,
"funnel_stage_id": 8,
"responsible_user_id": 5
}'Ответ
{
"data": {
"id": 501,
"funnel_id": 2,
"funnel_stage_id": 8,
"status": "open",
"responsible_user_id": 5,
"stage_changed_at": "2026-03-16T12:00:00.000000Z",
"updated_at": "2026-03-16T12:00:00.000000Z"
}
}Лента активности сделки
Запрос
curl -X GET "https://api.aisar.app/v1/deals/501/activities?perPage=20" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"items": [
{
"id": 1,
"deal_id": 501,
"type": "stage_changed",
"actor_user_id": 5,
"body": null,
"metadata": { "from": 1, "to": 3 },
"created_at": "2026-03-15T10:05:00.000000Z",
"actor": { "id": 5, "name": "Ivan", "lastname": "Petrov" }
}
],
"pagination": { "page": 1, "perPage": 20, "total": 4, "lastPage": 1 }
}
}Заметка в таймлайн сделки
Запрос
curl -X POST https://api.aisar.app/v1/deals/501/notes \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"body": "Клиент просит счёт на юрлицо"
}'Ответ
{
"data": {
"message": "Note added.",
"item": {
"id": 902,
"deal_id": 501,
"type": "note",
"actor_user_id": 5,
"body": "Клиент просит счёт на юрлицо",
"metadata": null,
"created_at": "2026-03-16T09:00:00.000000Z"
}
}
}Настройки авто-создания сделок
Запрос
curl -X GET https://api.aisar.app/v1/company/deal-settings \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"auto_create_deal_enabled": true,
"default_funnel_id": 1,
"default_deal_title_template": "{contact_displayName}",
"default_currency": "KZT",
"default_stale_after_days": null,
"auto_lead_mode": "unsorted",
"repeat_contact_policy": "attach_open",
"repeat_cooldown_hours": 24,
"crm_lead_integrations": [
{ "type": "bitrix24", "instance_id": 12, "creates_leads": true }
],
"has_funnels": true
}
}Сохранение настроек сделок и авто-лидов
Запрос
curl -X POST https://api.aisar.app/v1/company/deal-settings \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auto_lead_mode": "unsorted",
"repeat_contact_policy": "attach_open",
"repeat_cooldown_hours": 48,
"default_funnel_id": 1,
"default_deal_title_template": "{contact_displayName}",
"default_currency": "KZT"
}'Ответ
{
"data": {
"auto_create_deal_enabled": true,
"default_funnel_id": 1,
"default_deal_title_template": "{contact_displayName}",
"default_currency": "KZT",
"default_stale_after_days": null,
"auto_lead_mode": "unsorted",
"repeat_contact_policy": "attach_open",
"repeat_cooldown_hours": 48,
"crm_lead_integrations": [],
"has_funnels": true
}
}Принять лид из «Неразобранного»
Запрос
curl -X POST https://api.aisar.app/v1/deals/640/accept \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"funnel_stage_id": 2,
"responsible_user_id": 5
}'Ответ
{
"data": {
"id": 640,
"company_id": 1,
"contact_id": 318,
"funnel_id": 1,
"funnel_stage_id": 2,
"title": "Dana S.",
"amount": null,
"currency": "KZT",
"status": "open",
"source": "whatsapp",
"responsible_user_id": 5,
"stage_changed_at": "2026-09-29T16:05:00.000000Z",
"unsorted_at": null,
"lead_conversation_id": 9120,
"channel": "whatsapp",
"created_at": "2026-09-29T15:40:00.000000Z",
"updated_at": "2026-09-29T16:05:00.000000Z",
"contact": { "id": 318, "display_name": "Dana S.", "avatar": null },
"responsible_user": { "id": 5, "name": "Ivan" },
"conversations_count": null
}
}Отклонить лид и исключить контакт из авто-лидов
Запрос
curl -X POST https://api.aisar.app/v1/deals/641/decline \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"exclude_contact": true
}'Ответ
{
"data": {
"declined": true
}
}Привязать лид к открытой сделке клиента
Запрос
curl -X POST https://api.aisar.app/v1/deals/642/link \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target_deal_id": 501
}'Ответ
{
"data": {
"id": 501,
"company_id": 1,
"contact_id": 123,
"funnel_id": 1,
"funnel_stage_id": 3,
"title": "Office renovation",
"status": "open",
"responsible_user_id": 5,
"unsorted_at": null,
"lead_conversation_id": null,
"updated_at": "2026-09-29T16:10:00.000000Z",
"contact": { "id": 123, "display_name": "Aigerim K.", "avatar": null },
"responsible_user": { "id": 5, "name": "Ivan" }
}
}Смена этапа неразобранного лида — 409
Запрос
curl -X POST https://api.aisar.app/v1/deals/640 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"funnel_stage_id": 3
}'Ответ
{
"data": {
"message": "The deal is in Unsorted: accept it first."
}
}Список задач (свои, просроченные)
Запрос
curl -X GET "https://api.aisar.app/v1/deal-tasks?scope=mine&bucket=overdue&perPage=20" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"items": [
{
"id": 1,
"company_id": 1,
"deal_id": 501,
"contact_id": null,
"type": "call",
"title": "Перезвонить клиенту",
"description": null,
"due_at": "2026-07-08T09:00:00.000000Z",
"remind_at": "2026-07-08T08:45:00.000000Z",
"status": "open",
"assigned_user_id": 5,
"completed_at": null,
"overdue": true,
"created_at": "2026-07-07T10:00:00.000000Z",
"updated_at": "2026-07-07T10:00:00.000000Z",
"is_all_day": false,
"reminder_disabled": false,
"remind_offset_minutes": 15,
"reminded_at": "2026-07-08T08:45:05.000000Z",
"snoozed_until": null,
"is_overdue": true,
"created_by": 5,
"source": "human",
"conversation_id": null,
"can_update": true,
"can_delete": true,
"deal": { "id": 501, "title": "Поставка оборудования", "deleted": false },
"contact": null,
"assigned_user": { "id": 5, "name": "Айгерим" },
"created_by_user": { "id": 5, "name": "Айгерим" }
}
],
"pagination": { "page": 1, "perPage": 20, "total": 7, "lastPage": 1 }
}
}Создание задачи по сделке
Запрос
curl -X POST https://api.aisar.app/v1/deal-tasks \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"deal_id": 501,
"type": "call",
"title": "Перезвонить клиенту",
"due_at": "2026-07-08T09:00:00Z",
"remind_at": "2026-07-08T08:45:00Z",
"remind_offset_minutes": 15,
"assigned_user_id": 5
}'Ответ
{
"data": {
"id": 1,
"company_id": 1,
"deal_id": 501,
"contact_id": null,
"type": "call",
"title": "Перезвонить клиенту",
"description": null,
"due_at": "2026-07-08T09:00:00.000000Z",
"remind_at": "2026-07-08T08:45:00.000000Z",
"status": "open",
"assigned_user_id": 5,
"completed_at": null,
"overdue": false,
"created_at": "2026-07-07T10:00:00.000000Z",
"updated_at": "2026-07-07T10:00:00.000000Z",
"is_all_day": false,
"reminder_disabled": false,
"remind_offset_minutes": 15,
"reminded_at": null,
"snoozed_until": null,
"is_overdue": false,
"created_by": 3,
"source": "human",
"conversation_id": null,
"can_update": true,
"can_delete": true,
"deal": { "id": 501, "title": "Поставка оборудования", "deleted": false },
"contact": null,
"assigned_user": { "id": 5, "name": "Айгерим" },
"created_by_user": { "id": 3, "name": "Данияр" }
}
}Счётчики задач
Запрос
curl -X GET https://api.aisar.app/v1/deal-tasks/counters \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"overdue": 4,
"today": 6,
"upcoming_7d": 11,
"unassigned": 2,
"done_today": 9,
"mine": { "overdue": 1, "today": 3, "done_today": 4 }
}
}Календарь задач на неделю
Запрос
curl -X GET "https://api.aisar.app/v1/deal-tasks/calendar?from=2026-07-06T00:00:00Z&to=2026-07-13T00:00:00Z&scope=mine" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"Ответ
{
"data": {
"items": [
{
"id": 1,
"title": "Перезвонить клиенту",
"type": "call",
"due_at": "2026-07-08T09:00:00.000000Z",
"is_all_day": false,
"status": "open",
"assigned_user_id": 5,
"deal_id": 501,
"contact_id": null,
"can_update": true
}
],
"truncated": false
}
}Отложить напоминание на час
Запрос
curl -X POST https://api.aisar.app/v1/deal-tasks/1/snooze \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"minutes": 60
}'Ответ
{
"data": {
"id": 1,
"deal_id": 501,
"type": "call",
"status": "open",
"due_at": "2026-07-08T09:00:00.000000Z",
"remind_at": "2026-07-08T08:45:00.000000Z",
"snoozed_until": "2026-07-08T09:45:00.000000Z",
"assigned_user_id": 5,
"can_update": true
}
}Закрытие задачи (PATCH)
Запрос
curl -X PATCH https://api.aisar.app/v1/deal-tasks/1 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "done"
}'Ответ
{
"data": {
"id": 1,
"deal_id": 501,
"type": "call",
"status": "done",
"assigned_user_id": 5,
"completed_at": "2026-07-08T09:30:00.000000Z",
"updated_at": "2026-07-08T09:30:00.000000Z"
}
}Создание причины отказа
Запрос
curl -X POST https://api.aisar.app/v1/lost-reasons \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Дорого",
"is_active": true,
"order": 0
}'Ответ
{
"data": {
"id": 1,
"company_id": 1,
"name": "Дорого",
"is_active": true,
"order": 0,
"created_at": "2026-07-07T10:00:00.000000Z",
"updated_at": "2026-07-07T10:00:00.000000Z"
}
}