РусскийПользовательский APICRM: команды и операторы

CRM: команды и операторы

Управление CRM на стороне рекламодателя: per-bot включение CRM, команды операторов с их правами, сами операторы, шаблоны ответов и наборы, кастомные события (постбэки операторов), статистика и надзор за диалогами. Это API владельца аккаунта (/api/crm/*). Рабочее место оператора живёт отдельно на crm.altercpa.top — его API (/op/*) в этот справочник не входит.

Все ответы — HTTP 200 с application/json; успех или ошибка указаны в теле, а не в HTTP-статусе. Время возвращается в unix-секундах (0 = не задано).

Авторизация и тарифные гейты

Все 23 эндпоинта используют авторизацию по API-ключу или сессии дашборда (?id={uid}-{key}) и не требуют активной платной подписки — так владелец с истёкшей подпиской всё ещё может управлять CRM и выключить её по ботам, чтобы аккуратно свернуться.

Наличие функции CRM на тарифе проверяется на сервере при каждом изменяющем действии, а также на «тяжёлых» GET — статистике и списке диалогов. Лёгкие списки (bot/list, team/list, operator/list, template/list, event/list) функции не требуют — только владения ресурсом. Включение CRM по боту (bot.json с crm=1) требует функции; выключение разрешено всегда.

Лимит мест операторов («ваш лимит мест операторов») проверяется при создании оператора и при его включении (status=0); лимит соблюдается атомарно, при нехватке — error: limit.

Параметры принимаются как query-строка, urlencoded-тело или JSON-тело (JSON приоритетнее); списки (bots, sets) — JSON-массив или строка через запятую.

Сквозные коды ошибок: key (нет/неверный токен — клиент разлогинивается), ban (пользователь заблокирован), access (ресурс не ваш / не найден), func (неверные аргументы), db (ошибка базы), limit (лимит мест). Коды этой страницы: crm (функция CRM не на тарифе — фронт предлагает апгрейд), inuse (в команде ещё есть операторы), media (неверный путь/тип медиа). Тарифы CRM описаны в разделе тарифы и оплата.


Боты с CRM

GET /api/crm/bot/list.json

Список ваших не удалённых ботов с их состоянием CRM (per-bot включение CRM). Порядок — по ID бота убыванию. Удалённые боты исключены. Функции CRM не требует.

ПараметрОписание
{
  "status": "ok",
  "data": [
    { "id": 42, "username": "myshopbot", "name": "My Shop", "crm": true },
    { "id": 37, "username": "leadsbot", "name": "Leads", "crm": false }
  ]
}
ОшибкаЗначение
dbОшибка базы данных

Включить/выключить CRM по боту

POST /api/crm/bot.json

Переключает per-bot включение CRM для одного вашего бота. Включение (crm=1) требует функции CRM; выключение (crm=0) разрешено всегда — это «аварийный выход» для владельца с истёкшей подпиской. Изменение сразу обновляет настройки бота на нашем бэкенде.

ПараметрОбязательныйОписание
botID бота; должен быть вашим и не удалён. 0/отсутствует → func
crmЖелаемое состояние; должен присутствовать. Истинно: 1/true/yes/on
{ "status": "ok", "bot": 42, "crm": true }
ОшибкаЗначение
funcbot не задан или crm отсутствует
accessБот не ваш или удалён
crmВключение без функции CRM на тарифе
dbОшибка базы данных

Список команд

GET /api/crm/team/list.json

Ваши команды с шестью флагами прав и списком разрешённых ботов (allowlist). Порядок — по ID команды. Функции CRM не требует.

Флаги прав: leads_view (видеть карточку лида), leads_edit (менять лид), confirm (подтверждать заявку на вступление, approveChatJoinRequest), events (запускать кастомные события), reply (отправлять сообщения), sticky (закрепление диалога за оператором).

ПараметрОписание
{
  "status": "ok",
  "data": [
    {
      "id": 3,
      "name": "Поддержка",
      "leads_view": true,
      "leads_edit": true,
      "confirm": true,
      "events": false,
      "reply": true,
      "sticky": false,
      "bots": [42, 37],
      "created": 1718900000
    }
  ]
}
ОшибкаЗначение
dbОшибка базы данных

Создать или изменить команду

POST /api/crm/team.json

Создаёт команду (при id=0) или меняет её имя и шесть флагов прав. При правке понижение прав применяется к операторам команды сразу.

ПараметрОбязательныйОписание
id0/отсутствует — создать; иначе — править (команда должна быть вашей)
nameИмя команды
leads_viewПраво: видеть лид
leads_editПраво: менять лид
confirmПраво: подтверждать заявку на вступление
eventsПраво: запускать кастомные события
replyПраво: отправлять сообщения
stickyПраво: закрепление диалога
{ "status": "ok", "id": 3 }

При создании id — новый идентификатор; при правке — переданный id.

ОшибкаЗначение
crmНет функции CRM на тарифе
accessПравка не вашей команды
dbОшибка базы данных

Удалить команду

POST /api/crm/team/del.json

Удаляет команду вместе с её allowlist ботов и шарами наборов шаблонов. Откажет, если в команде ещё есть операторы — сначала переназначьте или удалите их.

ПараметрОбязательныйОписание
teamID команды; должна быть вашей
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessКоманда не ваша
inuseВ команде ещё есть операторы — переназначьте/удалите их
dbОшибка базы данных

Заменить ботов команды

POST /api/crm/team/bots.json

Полностью заменяет allowlist ботов команды переданным набором. Чужие и удалённые боты молча отбрасываются; в ответе — проверенный сохранённый подмножество (порядок сохраняется). Пустой/отсутствующий список очищает allowlist.

ПараметрОбязательныйОписание
teamID команды; должна быть вашей
botsJSON-массив или строка через запятую с ID ботов
{ "status": "ok", "bots": [42, 37] }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessКоманда не ваша
dbОшибка базы данных

Заменить наборы команды

POST /api/crm/team/sets.json

Полностью заменяет наборы шаблонов, расшаренные команде. Чужие наборы молча отбрасываются; в ответе — проверенный сохранённый подмножество. Пустой/отсутствующий список снимает все шары.

ПараметрОбязательныйОписание
teamID команды; должна быть вашей
setsJSON-массив или строка через запятую с ID наборов
{ "status": "ok", "sets": [5, 8] }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessКоманда не ваша
dbОшибка базы данных

Список операторов

GET /api/crm/operator/list.json

Полный список операторов аккаунта плюс использование мест. Секрет никогда не возвращается — открытый токен показывается только один раз при создании или сбросе. used считает активных операторов (status=0), cap — ваш лимит мест операторов. Функции CRM не требует.

status: 0 активен, 1 отключён. lead — право работы с лидами, manage — право управления (подразумевает lead).

ПараметрОписание
{
  "status": "ok",
  "operators": [
    {
      "id": 11,
      "name": "Анна",
      "login": "anna",
      "team": 3,
      "status": 0,
      "lead": true,
      "manage": false,
      "seen": 1718950000,
      "created": 1718900000
    }
  ],
  "seats": { "used": 1, "cap": 15 }
}
ОшибкаЗначение
dbОшибка базы данных

Создать или изменить оператора

POST /api/crm/operator.json

Создаёт оператора (при id=0) или меняет его имя, логин, команду и флаги ролей. При создании возвращается одноразовый открытый token (64 символа) — он показывается один раз и хранится только в виде хэша; лимит мест соблюдается атомарно. При правке токен не возвращается. manage подразумевает lead.

ПараметрОбязательныйОписание
id0/отсутствует — создать; иначе — править (оператор должен быть вашим)
nameОтображаемое имя
loginЛогин-метка
teamID команды; если не 0, должна быть вашей. 0 — без команды
manageРоль: управление (подразумевает lead)
leadРоль: работа с лидами; принудительно true, если задан manage

Создание:

{ "status": "ok", "id": 11, "token": "9f3c…64-символьный-секрет…b2a1" }

Правка:

{ "status": "ok", "id": 11 }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessКоманда не ваша или правка не вашего оператора
limitЛимит мест исчерпан (при создании)
dbОшибка базы данных

Включить/отключить оператора

POST /api/crm/operator/status.json

Включает (status=0) или отключает (status=1) оператора. Отключение возвращает его диалоги в общий пул и удаляет его сессии. Включение заново занимает место (лимит соблюдается атомарно).

ПараметрОбязательныйОписание
operatorID оператора; должен быть вашим
status1 — отключить (вернуть диалоги в пул + удалить сессии); иначе (0) — включить
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessОператор не ваш
limitНет свободного места (при включении)
dbОшибка базы данных

Сбросить доступ оператора

POST /api/crm/operator/reset.json

Перевыпускает секрет оператора: возвращает новый одноразовый открытый token (64 символа, показывается один раз), старый доступ-линк аннулируется, все сессии оператора удаляются.

ПараметрОбязательныйОписание
operatorID оператора; должен быть вашим
{ "status": "ok", "token": "1a7e…новый-64-символьный-секрет…c4d9" }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessОператор не ваш
dbОшибка базы данных

Удалить оператора

POST /api/crm/operator/del.json

Удаляет оператора, возвращая его диалоги в общий пул и удаляя его сессии.

ПараметрОбязательныйОписание
operatorID оператора; должен быть вашим
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessОператор не ваш
dbОшибка базы данных

Список шаблонов и наборов

GET /api/crm/template/list.json

Возвращает и наборы (sets, с указанием команд, которым они расшарены), и плоский массив всех шаблонов (templates, каждый несёт свой set). Наборы — по ID набора; шаблоны — по набору, порядку и ID. Функции CRM не требует.

media_type: 0 нет, 1 фото, 2 видео, 3 документ.

ПараметрОписание
{
  "status": "ok",
  "sets": [
    { "id": 5, "name": "Приветствия", "teams": [3], "created": 1718900000 }
  ],
  "templates": [
    {
      "id": 21,
      "set": 5,
      "name": "Привет",
      "text": "Здравствуйте! Чем помочь?",
      "media": "",
      "media_type": 0,
      "sort": 0
    }
  ]
}
ОшибкаЗначение
dbОшибка базы данных

Создать или изменить шаблон

POST /api/crm/template.json

Создаёт (при id=0) или меняет один шаблон ответа: текст и опциональное медиа, по желанию привязанный к набору. Медиа проверяется на принадлежность вам; пустой media сбрасывает media_type в 0.

ПараметрОбязательныйОписание
id0/отсутствует — создать; иначе — править (шаблон должен быть вашим)
setID набора; если не 0, должен быть вашим. 0 — без набора
nameМетка шаблона
textТекст ответа
mediaПуть к вашему медиа из media/upload; "" если нет
media_type1 фото, 2 видео, 3 документ (при заданном media)
sortПорядок внутри набора
{ "status": "ok", "id": 21 }

При создании id — новый идентификатор; при правке — переданный id.

ОшибкаЗначение
crmНет функции CRM на тарифе
accessНабор не ваш или правка не вашего шаблона
mediaНеверный путь медиа или media_type
dbОшибка базы данных

Удалить шаблон

POST /api/crm/template/del.json

Удаляет один шаблон (удаляется только если принадлежит вам). Отдельной проверки владения нет: чужой или несуществующий id — молчаливый no-op, ответ всё равно ok.

ПараметрОбязательныйОписание
templateID шаблона (удалится только если принадлежит вам)
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
dbОшибка базы данных

Создать или переименовать набор

POST /api/crm/set.json

Создаёт набор шаблонов (при id=0) или переименовывает его.

ПараметрОбязательныйОписание
id0/отсутствует — создать; иначе — переименовать (набор должен быть вашим)
nameИмя набора
{ "status": "ok", "id": 5 }

При создании id — новый идентификатор; при переименовании — переданный id.

ОшибкаЗначение
crmНет функции CRM на тарифе
accessПереименование не вашего набора
dbОшибка базы данных

Удалить набор

POST /api/crm/set/del.json

Удаляет набор и его шары командам, разгруппировывая его шаблоны: они вынимаются из набора, само содержимое сохраняется.

ПараметрОбязательныйОписание
setID набора; должен быть вашим
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessНабор не ваш
dbОшибка базы данных

Список кастомных событий

GET /api/crm/event/list.json

Определения кастомных событий одного бота (постбэки, которые запускают операторы), активные и отключённые. Порядок — по порядку и ID события. Гейт — только владение ботом, функции CRM этот список не требует.

status: 0 активно, 1 отключено.

ПараметрОбязательныйОписание
botID бота; должен быть вашим. 0/отсутствует → func
{
  "status": "ok",
  "data": [
    {
      "id": 7,
      "bot": 42,
      "name": "Оплата получена",
      "desc": "Менеджер подтвердил оплату",
      "url": "https://track.example.com/postback?click={click}&goal=paid",
      "sort": 0,
      "status": 0,
      "created": 1718900000
    }
  ]
}
ОшибкаЗначение
funcbot не задан (0)
accessБот не ваш
dbОшибка базы данных

Создать или изменить событие

POST /api/crm/event.json

Создаёт (при id=0) или меняет определение кастомного события. Кастомное событие — это постбэк, поэтому url обязателен (иначе func). При создании проверяется владение ботом; bot неизменяем при правке. Отключить можно либо disabled, либо status=1.

ПараметрОбязательныйОписание
id0/отсутствует — создать; иначе — править (событие должно быть вашим)
botID бота (используется/проверяется только при создании; неизменяем при правке)
nameМетка события для операторов
descОписание
urlШаблон URL постбэка; пустой → func
sortПорядок
disabledЕсли истинно → status=1 (отключено)
statusАльтернатива: status=1 тоже отключает
{ "status": "ok", "id": 7 }

При создании id — новый идентификатор; при правке — переданный id.

ОшибкаЗначение
crmНет функции CRM на тарифе
funcПустой url
accessБот не ваш (при создании) или правка не вашего события
dbОшибка базы данных

Удалить событие

POST /api/crm/event/del.json

Удаляет определение события (удаляется только если принадлежит вам). История сработавших событий сохраняется. Отдельной проверки владения нет: чужой id — молчаливый no-op.

ПараметрОбязательныйОписание
eventID события (удалится только если принадлежит вам)
{ "status": "ok" }
ОшибкаЗначение
crmНет функции CRM на тарифе
dbОшибка базы данных

Статистика CRM

GET /api/crm/stats.json

Статистика CRM по всему аккаунту за период: объём, здоровье очереди, присутствие операторов и нагрузка по каждому оператору (по всем ботам, командам и операторам владельца). По умолчанию — последние 7 дней.

В volume системные заметки исключены (учитывается только обычная переписка). В queue: open — всего открытых диалогов; unclaimed — в пуле, без оператора; pending — открытые диалоги, ждущие ответа оператора (взятые или нет): это рабочий «хвост», на который интерфейс показывает предупреждение (а не unclaimed); oldest_unanswered — время самого старого неотвеченного входящего (по той же логике «ждёт ответа», а не по непрочитанным). presence.online — операторы, активные за последние 5 минут.

ПараметрОбязательныйОписание
fromНачало периода (unix); по умолчанию сейчас − 7 дней
toКонец периода (unix); по умолчанию сейчас
{
  "status": "ok",
  "from": 1718300000,
  "to": 1718900000,
  "volume": { "dialogs": 120, "messages_in": 540, "messages_out": 610 },
  "queue": { "open": 8, "unclaimed": 3, "pending": 5, "oldest_unanswered": 1718890000 },
  "presence": { "online": 2 },
  "operators": [
    {
      "id": 11,
      "name": "Анна",
      "messages_sent": 210,
      "dialogs_handled": 64,
      "confirms": 18,
      "leads_edited": 12,
      "events_fired": 9
    }
  ]
}
ОшибкаЗначение
crmНет функции CRM на тарифе
dbОшибка базы данных

Надзор за диалогами

GET /api/crm/dialog/list.json

Только для чтения: список открытых диалогов аккаунта, самые свежие сверху, постранично по курсору before (курсор диалога). Тела сообщений не возвращаются (надзор, не чат). Размер страницы — 50; more=true, когда страница заполнена.

operator: 0 — диалог в пуле (тогда operator_name пустой). pending: 1 — диалог ждёт ответа оператора. last_in/last_out — время последнего входящего (от подписчика) и последнего ответа оператора (0 — ещё ни разу не отвечали); created — время начала диалога.

ПараметрОбязательныйОписание
beforeКурсор диалога: вернёт диалоги с last_id меньше указанного. 0/отсутствует — первая страница
filterФильтр по статусу (применяется на стороне сервера ко всему аккаунту): pending — ждут ответа; unclaimed — в пуле, без оператора; assigned — взяты оператором
botОграничить одним ботом (его ID)
{
  "status": "ok",
  "dialogs": [
    {
      "id": 301,
      "bot": 42,
      "subscriber": 123456789,
      "lead": 5001,
      "name": "Иван",
      "username": "ivan",
      "operator": 11,
      "operator_name": "Анна",
      "unread": 2,
      "pending": 1,
      "last_id": 9870,
      "last_in": 1718895000,
      "last_out": 1718896000,
      "created": 1718800000
    }
  ],
  "more": false
}
ОшибкаЗначение
crmНет функции CRM на тарифе
dbОшибка базы данных

Переназначить диалог

POST /api/crm/dialog/assign.json

Переназначает диалог на одного из ваших операторов или принудительно возвращает его в общий пул (operator=0). Пишет системную заметку, и инбоксы операторов сразу обновляются.

ПараметрОбязательныйОписание
dialogID диалога; должен принадлежать вам
operatorЦелевой оператор (должен быть вашим); 0 или отсутствует — вернуть в пул
{ "status": "ok", "operator": 11 }
ОшибкаЗначение
crmНет функции CRM на тарифе
accessДиалог не ваш / не найден, либо целевой оператор не ваш
dbОшибка базы данных