API и вебхуки Numline
Редакция от 22 октября 2026 г.
API позволяет подключить WhatsApp, Telegram, MAX, Авито и SMS к своей CRM, сайту или сервисам автоматизации (Make, Albato, n8n): получать сообщения клиентов и отвечать им. API доступно на всех тарифах.
1. Ключ и запросы
Ключ создаёт владелец компании в личном кабинете: «Настройки» → «API и вебхуки» → «Создать ключ». Ключ показывается один раз, храните его как пароль. Отозвать ключ можно там же.
Адрес API: https://app.numline.ru/api/v1. Ключ передаётся в заголовке:
Authorization: Bearer nl_ваш_ключ
Ответы - JSON в UTF-8, даты - ISO 8601 в UTC. Ошибка - код HTTP и тело {"code": "...", "error": "текст"}:
| Код | Когда |
|---|---|
| 400 | неверные параметры |
| 401 | нет ключа, ключ неверный или отозван |
| 403 | нет доступа (например, личный номер сотрудника) |
| 404 | номер, чат или сообщение не найдены |
| 422 | сообщение нельзя отправить сейчас (номер не подключён, подписка не оплачена, контакт заблокирован) |
| 429 | превышен лимит запросов |
Лимиты: 120 запросов в минуту на ключ, 30 отправок в минуту с одного номера, не больше одного нового собеседника в минуту с одного номера.
Ключ действует от имени компании и видит все её номера. На личных номерах сотрудников видны только переписки с собеседниками, которых одобрил владелец телефона, и новым собеседникам с личных номеров через API писать нельзя.
2. Номера
GET /channels - номера компании.
{"channels": [{"id": 12, "kind": "whatsapp", "phone": "79991234567", "title": "Отдел продаж",
"state": "connected", "enabled": true, "private": false}]}
kind: whatsapp, telegram, max, sms, avito. state: connected - работает; qr, logged_out, disconnected, stopped - не работает, нужно подключить в кабинете.
3. Чаты
GET /chats - чаты, у которых было хотя бы одно сообщение, по времени последнего сообщения (новые сверху).
| Параметр | Значение |
|---|---|
| channel_id | только чаты этого номера |
| updated_after | только чаты с сообщениями позже этой даты - для синхронизации |
| before | листание: значение next_before из предыдущего ответа |
| limit | от 1 до 200, по умолчанию 50 |
{"chats": [{"id": 345, "channel_id": 12, "kind": "whatsapp", "phone": "79990001122", "peer_id": "79990001122@s.whatsapp.net",
"name": "Анна", "username": "", "is_group": false, "closed": false, "assignee_id": null,
"last_message_at": "2026-10-17T09:15:02+00:00"}],
"has_more": true, "next_before": "2026-10-17T08:01:44+00:00"}
GET /chats/{id} - один чат.
4. Сообщения
GET /chats/{id}/messages - сообщения чата. По умолчанию - последние, новые сверху; before_id - старше указанного; after_id - новее указанного, по порядку. limit - до 200.
GET /messages/{id} - одно сообщение вместе с чатом.
{"id": 9876, "chat_id": 345, "direction": "in", "origin": "client", "type": "text", "text": "Здравствуйте",
"status": "new", "error": "", "file_name": "", "mime": "", "file_url": "", "transcript": "",
"author": "", "sender_name": "", "sender_phone": "", "ts": "2026-10-17T09:15:02+00:00"}
direction: in - от клиента, out - клиенту.origin: client - клиент; panel - из Numline или через API; amo - из CRM; phone - с самого телефона; auto - автоответ.type: text, picture, video, file, voice, audio, sticker.statusисходящего: sending, new, sent, delivered, read, failed (тогда причина вerror).file_url- временная ссылка на файл; скачайте файл, если он нужен надолго.transcript- расшифровка голосового, если она включена.
5. Отправка
POST /messages - отправить текст и (или) файл.
В существующий чат:
{"chat_id": 345, "text": "Добрый день! Заказ готов"}
Новому собеседнику (или по номеру телефона):
{"channel_id": 12, "phone": "79990001122", "text": "Добрый день! Это магазин «Ромашка»"}
Кто пишет: "author": "Мария Петрова" - имя сотрудника вашей CRM, оно будет в «Чатах» и в CRM вместо имени ключа.
Файл по ссылке: "file_url": "https://..." и при желании "file_name". Или запрос multipart/form-data с полем file (до 64 МБ) и теми же полями.
Ответ 201 - созданное сообщение (как в разделе 4) с чатом. Окончательный статус приходит вебхуком message.status.
Писать первым можно не во всех мессенджерах: Авито не позволяет начинать переписку, SMS через SMSGate передаёт только текст. Мессенджеры блокируют номера за массовые сообщения незнакомым людям - не используйте API для рассылок.
Пример:
curl -X POST https://app.numline.ru/api/v1/messages \
-H "Authorization: Bearer nl_ваш_ключ" -H "Content-Type: application/json" \
-d '{"chat_id": 345, "text": "Добрый день!"}'
6. Окно чатов в вашей CRM
POST /iframe - одноразовая ссылка на «Чаты» Numline, чтобы показать их внутри вашей CRM в iframe. Ссылка действует 2 минуты, получайте её при каждом открытии окна.
{"parent": "https://crm.example.ru", "user": {"id": "17", "name": "Мария Петрова"}, "scope": "global"}
parent- адрес сайта CRM, где откроется окно; показывать «Чаты» в рамке разрешено только ему.user.id- id сотрудника в CRM. Если вы передали сотрудников в/users(раздел 8), окно показывает то, что положено этому сотруднику по его ролям; неизвестный сотрудник - 404user_not_found, сотрудник без ролей - 403no_channels.user.name- имя сотрудника: так будут подписаны его ответы (если не передано - имя из/users).scope:global- все переписки компании,card- только переписки одного клиента, тогда нужен"phone": "79990001122"(окно в карточке клиента, сразу открывается его последняя переписка).- Личные номера сотрудников в окне не показываются.
- В переписке клиента - ссылки «Контакт в CRM» и открытые сделки (раздел 8). При нажатии окно сообщает странице CRM
postMessage({type: "numline:open_entity", entity: {type: "contact" | "deal", id, uri}})- CRM может открыть карточку у себя.
Ответ: {"url": "https://app.numline.ru/embed/enter?k=...", "expires_in": 120}. Подставьте url в iframe:
<iframe src="URL" allow="microphone; clipboard-write" style="width:100%;height:700px;border:0"></iframe>
7. Счётчик неотвеченных
GET /unanswered - чаты, которые ждут ответа: не завершены, последнее сообщение - от клиента. Параметры channel_id и phone - только по номеру компании или по клиенту, user_id - только чаты, которые видит этот сотрудник (раздел 8).
{"count": 3, "chat_ids": [345, 341, 330]}
8. Сотрудники, контакты и сделки
Если CRM уже подключена к Wazzup, переход почти без переделок: те же сущности и поля. Пока сотрудников в /users нет, окно чатов показывает все рабочие номера компании.
Сотрудники. POST /users - массив до 100 сотрудников, повторная загрузка обновляет: {"id": "17", "name": "Мария Петрова", "phone": "79990001122"} (phone необязателен). GET /users, GET /users/{id}, DELETE /users/{id}, PATCH /users/bulk_delete (массив id). До 1000 сотрудников на компанию.
Роли на номерах. PATCH /user-roles - массив {"user_id": "17", "channel_id": 12, "role": "seller", "allow_new_clients": true}; GET /user-roles?user_id=17.
- seller - менеджер: видит и пишет только своим клиентам (он ответственный в контакте или в открытой сделке). С allow_new_clients видит и ещё ничьих клиентов.
- manager - руководитель: видит всех клиентов номера и пишет любому.
- auditor - контроль качества: видит всех, писать не может.
- none - убрать доступ к номеру. Номер без роли сотрудник не видит. Личные номера сотрудников в роли не назначаются.
Контакты. POST /contacts - массив до 100:
{"id": "c-501", "name": "Иван Соколов", "responsibleUserId": "17", "uri": "https://crm.example.ru/contacts/501",
"contactData": [{"chatType": "whatsapp", "chatId": "79991234567"}, {"chatType": "telegram", "chatId": "ivan_sokolov"}]}
chatType: whatsapp, max, sms - chatId номер телефона; telegram - числовой id, username или телефон с «+» (можно и поле phone); vk, avito - id собеседника. uri - ссылка на карточку (http/https). GET /contacts, GET /contacts/{id}, DELETE /contacts/{id}, PATCH /contacts/bulk_delete.
Сделки. POST /deals - массив до 100: {"id": "d-77", "name": "Ипотека", "responsibleUserId": "17", "uri": "https://crm.example.ru/deals/77", "closed": false, "contacts": ["c-501"]} (до 10 контактов). Ответственный открытой сделки видит переписки её контактов. GET /deals, GET /deals/{id}, DELETE /deals/{id}, PATCH /deals/bulk_delete.
Списки: ?offset=0&limit=100, ответ {"count": 250, "data": [...]}. Массовое удаление возвращает {"not_found": [...]}.
9. Вебхуки
Адрес для событий добавляется там же: «Настройки» → «API и вебхуки». Только https и публичный сервер; до 3 адресов на компанию; для каждого можно выбрать события.
Numline отправляет POST с JSON:
{"event": "message.incoming", "id": "evt_1024", "ts": "2026-10-17T09:15:03+00:00", "company_id": 7,
"data": { ...сообщение с полем "chat"... }}
| Событие | Данные |
|---|---|
| message.incoming | новое сообщение клиента (с чатом) |
| message.outgoing | исходящее: из Numline, CRM, с телефона, автоответ, через API (с чатом) |
| message.status | {"id", "chat_id", "status", "error"} |
| channel.state | номер (как в разделе 2) и previous, detail |
| webhook.test | проверка из настроек |
Заголовки: X-Numline-Event - событие, X-Numline-Delivery - id события (для защиты от повторов), X-Numline-Attempt - номер попытки, X-Numline-Signature - подпись sha256= + HMAC-SHA256 сырого тела с секретом вебхука.
Проверка подписи на Python:
import hmac, hashlib
expected = "sha256=" + hmac.new(SECRET.encode(), body, hashlib.sha256).hexdigest()
ok = hmac.compare_digest(expected, request.headers["X-Numline-Signature"])
Ответьте любым кодом 2xx в течение 10 секунд. Иначе повторим через 1, 5 и 30 минут, 2, 6 и 12 часов. Одно событие может прийти дважды - сверяйте id. После 50 неудачных доставок подряд вебхук выключается, владельцу приходит письмо.
10. Поддержка
Вопросы по API - support@numline.ru или чат в личном кабинете.