Перейти к содержимому
AISARAISAR
REST API

Сделки

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 — потолок числа записей)

POST/v1/deals

Создание сделки

POST/v1/deals/bulk

Массовое действие над сделками: move_stage | assign | delete (до 100 сделок; до 25 — сразу, больше — в очередь)

POST/v1/deals/bulk/{operation}/undo

Отмена массового move_stage/assign в течение 10 минут (только автор операции)

GET/v1/deals/{deal}

Получение сделки

POST/v1/deals/{deal}

Обновление сделки

DELETE/v1/deals/{deal}

Удаление сделки (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?) — для интеграций сделка рождается в этот момент

POST/v1/deals/{deal}/decline

Отклонить лид из «Неразобранного» (exclude_contact? — больше не создавать лиды по контакту)

POST/v1/deals/{deal}/link

Привязать лид из «Неразобранного» к открытой сделке (target_deal_id) — диалоги переходят в неё, лид удаляется

GET/v1/company/deal-settings

Настройки авто-создания сделок компании (в т. ч. 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)

POST/v1/deal-tasks

Создание задачи

PATCH/v1/deal-tasks/{task}

Обновление/закрытие задачи

DELETE/v1/deal-tasks/{task}

Удаление задачи

GET/v1/deal-tasks/counters

Счётчики открытых задач: просрочено, сегодня, 7 дней, ничьи и свои, плюс закрытые сегодня

GET/v1/deal-tasks/calendar

Задачи со сроком в окне from–to (до 42 дней, до 1000 элементов)

GET/v1/deal-tasks/{task}

Получение одной задачи

POST/v1/deal-tasks/{task}/snooze

Отложить напоминание (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}

Удаление причины отказа

Примеры

Массовый перевод сделок на другую стадию

Запрос

bash
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
  }'

Ответ

json
{
  "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)

Запрос

bash
curl -X GET "https://api.aisar.app/v1/deals?contact_id=123&status=open" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Ответ

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
    }
  ]
}

Поиск сделок по названию или контакту

Запрос

bash
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"

Ответ

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
    }
  ]
}

Создание сделки

Запрос

bash
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
  }'

Ответ

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-15T10:00:00.000000Z"
  }
}

Перевод сделки в статус lost

Запрос

bash
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
  }'

Ответ

json
{
  "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 (свободная причина)

Запрос

bash
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": "Ушли к конкуренту"
  }'

Ответ

json
{
  "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"
  }
}

Смена воронки сделки (со стадией)

Запрос

bash
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
  }'

Ответ

json
{
  "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"
  }
}

Лента активности сделки

Запрос

bash
curl -X GET "https://api.aisar.app/v1/deals/501/activities?perPage=20" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Ответ

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 }
  }
}

Заметка в таймлайн сделки

Запрос

bash
curl -X POST https://api.aisar.app/v1/deals/501/notes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Клиент просит счёт на юрлицо"
  }'

Ответ

json
{
  "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"
    }
  }
}

Настройки авто-создания сделок

Запрос

bash
curl -X GET https://api.aisar.app/v1/company/deal-settings \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Ответ

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
  }
}

Сохранение настроек сделок и авто-лидов

Запрос

bash
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"
  }'

Ответ

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": 48,
    "crm_lead_integrations": [],
    "has_funnels": true
  }
}

Принять лид из «Неразобранного»

Запрос

bash
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
  }'

Ответ

json
{
  "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
  }
}

Отклонить лид и исключить контакт из авто-лидов

Запрос

bash
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
  }'

Ответ

json
{
  "data": {
    "declined": true
  }
}

Привязать лид к открытой сделке клиента

Запрос

bash
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
  }'

Ответ

json
{
  "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

Запрос

bash
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
  }'

Ответ

json
{
  "data": {
    "message": "The deal is in Unsorted: accept it first."
  }
}

Список задач (свои, просроченные)

Запрос

bash
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"

Ответ

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 }
  }
}

Создание задачи по сделке

Запрос

bash
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
  }'

Ответ

json
{
  "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": "Данияр" }
  }
}

Счётчики задач

Запрос

bash
curl -X GET https://api.aisar.app/v1/deal-tasks/counters \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Ответ

json
{
  "data": {
    "overdue": 4,
    "today": 6,
    "upcoming_7d": 11,
    "unassigned": 2,
    "done_today": 9,
    "mine": { "overdue": 1, "today": 3, "done_today": 4 }
  }
}

Календарь задач на неделю

Запрос

bash
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"

Ответ

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
  }
}

Отложить напоминание на час

Запрос

bash
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
  }'

Ответ

json
{
  "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)

Запрос

bash
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"
  }'

Ответ

json
{
  "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"
  }
}

Создание причины отказа

Запрос

bash
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
  }'

Ответ

json
{
  "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"
  }
}