Pager API · v2
Документація API
Отримуйте розмови, повідомлення й клієнтів у свої системи, дізнавайтеся про нові повідомлення й коментарі через вебхуки, надсилайте клієнтам повідомлення й файли, відповідайте на коментарі та керуйте розмовами, доступом менеджерів і довідниками Pager.
Pager API дає вашим системам доступ до даних організації. Через нього можна читати розмови, повідомлення й клієнтів, надсилати клієнтам повідомлення й файли, відповідати на коментарі в Instagram, змінювати статус, відповідального й групу розмови, заповнювати картку клієнта, керувати доступом менеджерів до каналів, а також довідниками, якими користуються менеджери в кабінеті: статусами, групами клієнтів, папками й шаблонами відповідей. Про нові повідомлення й коментарі Pager може повідомляти ваш сервер сам — через вебхуки.
https://api.pager.co.ua/v2- Запити й відповіді — JSON у кодуванні UTF-8, дати — ISO 8601 в UTC.
- Усі списки повертаються в однаковій обгортці
{ data, hasMore, nextCursor }, тож цикл обходу сторінок пишеться один раз — див. Пагінація. - Невідомі поля в тілі чи в query не ігноруються, а повертають
400 unknown_parameter, щоб друкарська помилка в назві поля не загубилася непомітно. - Машиночитний опис API — специфікація OpenAPI: для Postman, генерації клієнтів і AI-асистентів.
- Кожна відповідь містить заголовок
X-Request-Id. Вкажіть його, коли звертаєтеся в підтримку. - Кожен запит підписується API-ключем — див. Автентифікація.
Передавайте API-ключ організації в заголовку Authorization у форматі Bearer <ключ>. Ключ прив'язаний до організації: API читає й змінює дані лише тієї організації, якій він належить.
Ключ має вигляд pgr_live_ і 40 символів після нього. Якщо ключ не передано, він недійсний, відкликаний або прострочений, API відповідає однаково: 401 invalid_api_key.
Почніть інтеграцію із запиту GET /me: він підтверджує, що ключ робочий, і повертає організацію, тариф і ліміти запитів.
curl "https://api.pager.co.ua/v2/me" \
-H "Authorization: Bearer $PAGER_API_KEY"Розмови, повідомлення, клієнти та історія розмови повертаються сторінками. Кожна сторінка — обгортка { data, hasMore, nextCursor }.
limit— розмір сторінки, від1до100, за замовчуванням50.- Якщо
hasMoreдорівнюєtrue, передайтеnextCursorу параметріcursor, щоб отримати наступну сторінку. Решту параметрів залиште без змін. - Записи йдуть від нових до старих. Сторінки не дублюються й нічого не пропускають, навіть коли в кількох записів однаковий час.
- Курсор непрозорий: не розбирайте й не складайте його самі. Пошкоджений курсор повертає
400 invalid_cursor. - Довідники (статуси, групи, папки, шаблони) і замовлення розмови віддаються цілком:
hasMoreу них завждиfalse.
# Перша сторінка
curl "https://api.pager.co.ua/v2/conversations?limit=100" \
-H "Authorization: Bearer $PAGER_API_KEY"
# Наступна: nextCursor із попередньої відповіді
curl "https://api.pager.co.ua/v2/conversations?limit=100&cursor=WyIyMDI2LTA5LTIzVDE2OjAyOjExLjg0MFoiLCIyYjljNGQ2ZS04ZjBhLTRjMmUtOWI0ZC02ZjhhMGMyZTRiNmQiXQ" \
-H "Authorization: Bearer $PAGER_API_KEY"Синхронізація
updatedSince, а не повний обхід. Список розмов відсортовано за lastMessageAt: розмова з новим повідомленням переміщується на початок, тож під час обходу сторінками її можна пропустити. Запам'ятовуйте найбільший updatedAt з отриманих об'єктів і наступного разу передавайте його в updatedSince. Межа включна, тож останні об'єкти прийдуть ще раз — оновлюйте записи за id, а не додавайте нові.Списки приймають фільтри в рядку запиту. Різні фільтри поєднуються через «і»: запис має відповідати кожному з них.
- Кілька значень одного фільтра:
?statusId=a,bабо?statusId=a&statusId=b. Підходить будь-яке зі значень. nullозначає порожнє поле, як у кабінеті:?responsibleUserId=null— розмови без відповідального,?statusId=a,null— зі статусомaабо без статусу. Працює дляstatusId,responsibleUserIdіclientGroupId.qшукає без урахування регістру по тих самих полях, що й пошук у кабінеті. Поля для кожного ресурсу вказано в описі параметра.- Ідентифікатор іншої організації у фільтрі не дає помилки — список просто буде порожнім.
- Невідомий параметр повертає
400 unknown_parameter.
expand
Без expand розмова містить лише ідентифікатори пов'язаних об'єктів (clientId, statusId тощо), тож список не тягне зайвих даних. Параметр expand додає самі об'єкти: client, channel, status, clientGroup, responsibleUser — через кому. Невідоме значення повертає 400 з param: "expand". Токени й ключі каналів у відповідь не потрапляють ніколи.
curl "https://api.pager.co.ua/v2/conversations?statusId=5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e,null&responsibleUserId=null&expand=client,status" \
-H "Authorization: Bearer $PAGER_API_KEY"Помилка повертається з відповідним HTTP-кодом і об'єктом error. Обробляйте її за полем type — широкою категорією; code уточнює причину, param вказує на поле запиту, а requestId збігається із заголовком X-Request-Id.
{
"error": {
"type": "invalid_request",
"code": "invalid_parameter",
"message": "Color must be #rrggbb",
"param": "color",
"requestId": "req_4f1c9a2e7b3d4c6e9a0f1d2e3f4a5b6c"
}
}| HTTP | type | Коли виникає |
|---|---|---|
400 | invalid_request | Поле не пройшло перевірку (invalid_parameter), передано невідоме поле (unknown_parameter), тіло не є валідним JSON (invalid_body) або ідентифікатор із тіла не належить організації. Для вебхуків також invalid_webhook_url і webhook_limit_reached — див. Обмеження. |
401 | authentication_error | Ключ не передано, він недійсний, відкликаний або прострочений (invalid_api_key). |
402 | quota_exceeded | План закінчився або вичерпано баланс повідомлень (message_limit_reached). Повертається під час відправки повідомлення. |
403 | permission_error | Ключу бракує прав на цю дію. |
404 | not_found | Об'єкта немає у вашій організації (status_not_found тощо) або такого маршруту не існує (route_not_found). |
409 | conflict | Запит конфліктує з поточним станом: externalId уже зайнятий іншим клієнтом (external_id_taken), ключ ідемпотентності вже використано (idempotency_key_reused, idempotency_request_in_progress), на коментар уже є приватна відповідь (private_reply_exists) або доставку вимкненого вебхука не можна повторити (webhook_disabled). |
422 | channel_error | Повідомлення не вдалося надіслати в канал: месенджер відмовив (channel_rejected), канал не підтримує відправку (channel_unsupported) або не налаштований — див. Надіслати повідомлення. |
429 | rate_limit_exceeded | Перевищено ліміт запитів — див. Ліміти запитів. |
500 | api_error | Внутрішня помилка Pager. Повторіть запит пізніше, а звертаючись у підтримку, вкажіть requestId. |
Об'єкт іншої організації дає ту саму відповідь 404, що й неіснуючий, — API не підтверджує, що він існує.
Тип permission_error поки зарезервований на майбутнє. Орієнтуйтеся на type і code, а не на текст message: він може змінюватися.
Ліміти рахуються окремо для кожного ключа за принципом «дірявого відра». Кожен запит додає у відро свою вагу, а відро рівномірно спорожнюється. Поки вага вміщається, запит проходить; коли ні — API відповідає 429 rate_limit_exceeded.
| Відро | Місткість | Спорожнюється | |
|---|---|---|---|
general | 60 | 10 за секунду | Усі запити. |
outbound | 30 | 1 за секунду | Запити, що йдуть у месенджери: кожне надіслане повідомлення, відповідь на коментар і видалення коментаря додатково займають 1. Тобто до 30 таких запитів поспіль, далі — один на секунду. |
Вага запиту: 1 — отримання, створення, зміна й видалення об'єкта, 2 — сторінка списку, 5 — пошук повідомлень по всій організації й підрахунок розмов. Вагу кожної операції вказано поруч із нею. Тобто можна зробити до 60 одиничних запитів поспіль, а далі — стабільно 10 на секунду.
Поточні ліміти ключа повертає GET /me у полі rateLimits.
| Заголовок | Коли виникає |
|---|---|
RateLimit-Limit | Місткість відра. |
RateLimit-Remaining | Скільки одиниць ще вміщається у відро. |
RateLimit-Reset | Через скільки секунд відро повністю спорожніє. |
RateLimit-Policy | Політика у форматі 60;w=6: місткість і за скільки секунд спорожнюється повне відро. |
Retry-After | Лише у відповіді 429: через скільки секунд повторити запит. |
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 60
RateLimit-Remaining: 0
RateLimit-Reset: 6
RateLimit-Policy: 60;w=6
Retry-After: 1429, зачекайте стільки секунд, скільки вказано в Retry-After, і повторіть запит. Повтор без паузи знову впреться в ліміт.Запити з побічним ефектом приймають заголовок Idempotency-Key. Якщо з'єднання обірвалося й ви не знаєте, чи дійшов запит, повторіть його з тим самим ключем — Pager не виконає дію вдруге, а поверне збережену відповідь.
curl -X POST "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/messages" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Idempotency-Key: a3f1c9e2-5b7d-4e8a-9c0b-1d2e3f4a5b6c" \
-H "Content-Type: application/json" \
-d '{"text":"Дякуємо за замовлення! Номер ТТН: 20450000012345"}'- Зараз заголовок приймають відправка повідомлення, відповідь на коментар і створення підписки на вебхуки, для інших запитів він ігнорується. Заголовок необов'язковий: без нього запит виконується як звичайно.
- Ключ — будь-який рядок до 255 символів, свій для кожної нової дії. Найпростіше — UUID. Порожній чи задовгий ключ повертає
400 invalid_idempotency_key. - Ключ діє в межах організації 24 години. Повтор із тим самим ключем і тим самим тілом отримує збережену відповідь із заголовком
Idempotent-Replayed: true. - Зберігаються лише успішні відповіді (
2xx). Після помилки ключ звільняється, тож виправлений запит можна надіслати з тим самим ключем. - Той самий ключ з іншим тілом чи шляхом повертає
409 idempotency_key_reused. Поки перший запит ще виконується —409 idempotency_request_in_progress: зачекайте й повторіть.
Файл надсилається клієнту у три кроки: отримайте посилання на завантаження, завантажте файл у сховище Pager і надішліть повідомлення з готовим вкладенням. Файл іде у сховище напряму, повз API, тож ліміти запитів на його розмір не впливають.
- 1
POST /files з
conversationId, назвою, MIME-типом і розміром файлу. У відповіді —uploadUrl, заголовкиheadersі готовий об'єктattachment. - 2
Протягом 5 хвилин завантажте файл запитом
PUTнаuploadUrlіз заголовками зheaders.Authorizationтут не потрібен: доступ дає підпис у посиланні. - 3
Надішліть повідомлення з
attachments: [attachment]— об'єктом із першого кроку без змін.
# 1. Посилання на завантаження
curl -X POST "https://api.pager.co.ua/v2/files" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d", "name": "invoice-184502.pdf", "mime": "application/pdf", "size": 248193}'
# 2. Файл — напряму у сховище, без Authorization
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/pdf" \
--data-binary @invoice-184502.pdf
# 3. Повідомлення з вкладенням
curl -X POST "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/messages" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"attachments": [ATTACHMENT]}'В одному повідомленні — або текст, або один файл: більшість месенджерів губить текст поруч із файлом. Щоб надіслати файл із підписом, надішліть два повідомлення.
До 20 МБ. Дозволені зображення, відео, аудіо, PDF, ZIP, документи Office, TXT і CSV — див. Файли. Якщо файл не завантажено, API поверне 400 attachment_not_uploaded; якщо завантажено більший, ніж дозволено, — 400 attachment_too_large.
Повний опис API доступний у форматі OpenAPI 3.1. Специфікація генерується з тих самих схем, якими API перевіряє запити, тож завжди відповідає поточній версії. Її можна імпортувати в Postman чи Insomnia або згенерувати з неї клієнт для своєї мови.
https://api.pager.co.ua/v2/openapi.json
https://api.pager.co.ua/v2/docsGET /v2/openapi.json— специфікація: усі ендпоінти, параметри, схеми об'єктів і помилок, вага кожного запиту, а також формати подій вебхуків у розділіwebhooks.GET /v2/docs— інтерактивна документація на основі специфікації: там можна переглянути схеми й надіслати запит зі своїм ключем просто з браузера.- Обидві адреси відкриті: API-ключ не потрібен, і запити до них не враховуються в лімітах. Відповідь кешується на 5 хвилин.
- Описи в специфікації — англійською.
# Завантажити специфікацію
curl -o pager-openapi.json https://api.pager.co.ua/v2/openapi.jsonКлюч створює адміністратор організації в кабінеті Pager. В організації може бути лише один активний ключ.
- 1
Відкрийте Налаштування → API.
- 2
Натисніть Створити ключ і дайте йому назву, наприклад «Інтеграція з CRM». Назва потрібна лише вам, щоб згадати, де використовується ключ.
- 3
Скопіюйте ключ і збережіть його в надійному місці. Повністю ключ показується лише один раз: Pager зберігає тільки його хеш, тому відновити ключ неможливо — лише перевипустити.
Перевипустіть ключ, якщо він міг потрапити до сторонніх, або якщо з команди пішла людина, яка мала до нього доступ.
- 1
У Налаштування → API натисніть Перевипустити.
- 2
За потреби змініть назву й підтвердьте.
- 3
Збережіть новий ключ і замініть його в усіх інтеграціях.
401, тож оновіть ключ в інтеграціях одразу після перевипуску.Якщо двоє адміністраторів перевипускають ключ одночасно, один із запитів буде відхилено. Оновіть сторінку й перевірте, який ключ зараз активний.
Відкличте ключ, якщо інтеграція більше не потрібна. Після цього в організації не лишається активного ключа, доки ви не створите новий.
- 1
У Налаштування → API натисніть кнопку з кошиком поруч із ключем.
- 2
Підтвердьте відкликання.
401 invalid_api_key.Вебхуки повідомляють вашу систему про події в Pager, щойно вони стаються: Pager надсилає POST-запит із подією на ваш URL. Опитувати API, щоб дізнатися про нові повідомлення, не потрібно.
- Підписка — це URL і список подій, які на нього надсилати. В організації може бути до 10 підписок, наприклад окремо для CRM і для аналітики.
- Кожен запит підписано секретом підписки, тож ваш сервер може переконатися, що подію надіслав саме Pager, — див. Перевірка підпису.
- Якщо ваш сервер недоступний, Pager повторює доставку протягом приблизно 10 годин — див. Доставка й повтори.
- Підписками можна керувати в кабінеті або через API — див. ресурс Підписки на вебхуки. Підписка, створена в кабінеті, видна через API, і навпаки.
Спершу підготуйте на своєму сервері публічний HTTPS-ендпоінт, який приймає POST-запити з JSON. Далі підписку створює адміністратор організації в кабінеті.
- 1
Відкрийте Налаштування → API → Вебхуки й натисніть Додати вебхук.
- 2
Вкажіть URL ендпоінта й позначте події, на які підписуєтеся. Опис необов'язковий: він потрібен лише вам, щоб згадати, куди йдуть події.
- 3
Скопіюйте секрет підпису (
whsec_…) і збережіть його на сервері, наприклад у змінній оточенняPAGER_WEBHOOK_SECRET. Секрет показується лише один раз: відновити його не вийде, лише перевипустити. - 4
У меню підписки відкрийте Доставки й тест і натисніть Надіслати тест. Pager одразу надішле подію
webhook.testі покаже, що відповів ваш сервер.
Через API підписку створює POST /webhooks: секрет приходить у полі secret відповіді. Перевірити ендпоінт можна запитом POST /webhooks/{id}/test.
Нова підписка отримує лише події, що стаються після її створення. Історію повідомлень вона не отримує: щоб завантажити наявні дані, пройдіться по списках API — див. Пагінація.
Кожна подія приходить окремим запитом. Тіло запиту — JSON-конверт однакової форми для всіх типів подій, а самі дані події лежать у полі data.
| Подія | Коли виникає |
|---|---|
message.received | Клієнт надіслав повідомлення в будь-який канал організації. |
message.sent | Організація надіслала повідомлення клієнту: менеджер у кабінеті, ваша система через API, розсилка чи автоматика. |
comment.received | Клієнт залишив коментар під постом в Instagram — новий або відповідь у гілці. Відповіді від імені сторінки подією не є. |
webhook.test | Тестова подія з кнопки Надіслати тест або з POST /webhooks/{id}/test. Підписатися на неї не можна: вона приходить лише на запит. У data.message — рядок. |
Конверт події
| Поле | Коли виникає |
|---|---|
id | Ідентифікатор події, evt_…. Не змінюється між повторами й збігається із заголовком Pager-Event-Id, тож за ним зручно відкидати дублікати. |
type | Тип події — див. таблицю вище. |
createdAt | Коли подія сталася, ISO 8601 в UTC. |
organizationId | Організація, у якій сталася подія. |
data | Дані події. Для подій про повідомлення — message, conversation, client і channel; для comment.received — comment замість message. |
{
"id": "evt_6c1f0e9d8b7a45c3a2e1f0d9c8b7a6e5",
"type": "message.received",
"createdAt": "2026-09-24T08:31:40.582Z",
"organizationId": "org_2rRfXLYNflNpMgzPBX1MU18z39C",
"data": {
"message": {
"id": "d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "incoming",
"text": "А доставка у Львів скільки йде?",
"attachments": [],
"authorId": null,
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": false,
"isEdited": false,
"isDelivered": null,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-24T08:31:40.117Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
},
"conversation": {
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "unread",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
},
"client": {
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
},
"channel": {
"id": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"name": "Instagram магазину",
"channelSource": "Instagram",
"username": "kvitka.shop",
"imageUrl": "https://files.pager.co.ua/…/channel.jpg"
}
}
}{
"id": "evt_3e2d1c0b9a8f47e6d5c4b3a2f1e0d9c8",
"type": "comment.received",
"createdAt": "2026-09-24T10:02:16.204Z",
"organizationId": "org_2rRfXLYNflNpMgzPBX1MU18z39C",
"data": {
"comment": {
"id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"parentId": null,
"direction": "incoming",
"text": "Скільки коштує доставка у Львів?",
"username": "olena.koval",
"authorId": null,
"media": {
"id": "18045678901234567",
"url": "https://www.instagram.com/p/C9xYz1AbCdE/"
},
"hasPrivateReply": false,
"createdAt": "2026-09-24T10:02:15.000Z",
"updatedAt": "2026-09-24T10:02:15.000Z"
},
"conversation": {
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "unread",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
},
"client": {
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
},
"channel": {
"id": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"name": "Instagram магазину",
"channelSource": "Instagram",
"username": "kvitka.shop",
"imageUrl": "https://files.pager.co.ua/…/channel.jpg"
}
}
}У подіях message.* об'єкти мають ті самі формати, що й у REST: повідомлення, розмова без expand і клієнт. channel — канал: id, name, channelSource, username, imageUrl. Об'єкти — знімок на момент події.
У comment.received data.comment — коментар без replies. Для відповіді клієнта в гілці parentId вказує на корінь гілки. Відповісти можна через POST /conversations/{id}/comments.
Посилання у message.attachments[].url тимчасові: вони підписуються в момент кожної спроби доставки, термін дії — у expiresAt. Якщо файл вам потрібен, завантажте його одразу.
Порядок доставки не гарантований: події надсилаються паралельно, а повтори зсувають їх у часі. Щоб упорядкувати повідомлення, використовуйте message.createdAt.
Закладайте, що в об'єктах можуть з'явитися нові поля: не відкидайте подію через невідоме поле.
Кожен запит Pager підписує секретом підписки. Перевіряйте підпис, перш ніж довіряти події: URL вебхука не є секретом, і надіслати на нього запит може будь-хто.
POST /pager/webhook HTTP/1.1
Host: crm.example.com
Content-Type: application/json
User-Agent: Pager-Webhooks/1.0
Pager-Event-Id: evt_6c1f0e9d8b7a45c3a2e1f0d9c8b7a6e5
Pager-Event-Type: message.received
Pager-Delivery: dlv_4b7e1f0a-9c2d-4e8b-a6f3-5d1c0b9e8a72
Pager-Attempt: 1
Pager-Signature: t=1758702700,v1=5f0c8a1e2b7d4c9f3a6e1b8d0c7f2a5e9b4d1c8f7a2e6b3d0c9f5a8e1b4d7c2a| Заголовок | Коли виникає |
|---|---|
Pager-Signature | t=<unix-час>,v1=<підпис>, де v1 — HMAC-SHA256 у hex від рядка <t>.<тіло запиту>, а ключ — секрет підписки. t — час конкретної спроби, тож у повторі він новий. |
Pager-Event-Id | id події. Однаковий у всіх повторах. |
Pager-Event-Type | Тип події, як type у тілі. |
Pager-Delivery | Ідентифікатор доставки, dlv_…, — той самий id, що в журналі доставок. |
Pager-Attempt | Номер спроби, від 1. |
- 1
Візьміть із заголовка
Pager-Signatureзначенняtіv1. - 2
Обчисліть HMAC-SHA256 від рядка
<t>.<тіло>своїм секретом. Тіло беріть сирим, байт у байт як воно прийшло: після розбору й повторної серіалізації JSON підпис не зійдеться. - 3
Порівняйте результат із
v1функцією порівняння за сталий час (crypto.timingSafeEqual,hmac.compare_digest). - 4
Відкидайте запити, у яких
tвідрізняється від поточного часу більш ніж на 5 хвилин: так перехоплений запит не вийде відтворити пізніше.
import crypto from "node:crypto"
import express from "express"
const app = express()
const seen = new Set()
// Підпис рахується від сирого тіла: не розбирайте JSON до перевірки
app.post("/pager/webhook", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("Pager-Signature") ?? ""
const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")))
// 1. Очікуваний підпис: HMAC-SHA256 від «t.тіло»
const expected = crypto
.createHmac("sha256", process.env.PAGER_WEBHOOK_SECRET)
.update(`${t}.${req.body}`)
.digest("hex")
// 2. Порівняння за сталий час
const valid =
typeof v1 === "string" &&
v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))
// 3. Не старіше 5 хвилин
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 5 * 60
if (!valid || !fresh) return res.status(400).end()
const event = JSON.parse(req.body)
// 4. Повтори мають той самий event.id: обробляйте подію один раз
if (!seen.has(event.id)) {
seen.add(event.id)
queue.push(event)
}
// 5. Відповідайте 2xx одразу, а обробляйте подію у фоні
res.status(200).send("ok")
})Доставка успішна, якщо ваш сервер відповів будь-яким кодом 2xx протягом 10 секунд. Тіло відповіді Pager не аналізує, лише зберігає його початок у журналі.
- Будь-що інше — невдача: інший код,
3xx(редиректи не виконуються), таймаут чи помилка з'єднання. Pager повторить запит за розкладом нижче. - Відповідайте якнайшвидше: збережіть подію в чергу, поверніть
200, а обробляйте потім. Довга обробка всередині запиту веде до таймаутів і зайвих повторів. - Подія доставляється щонайменше один раз: та сама подія може прийти двічі, наприклад якщо ваша відповідь загубилася в мережі. Відкидайте дублікати за
idподії (Pager-Event-Id). - Після останньої невдалої спроби доставка отримує статус
deadі більше не повторюється автоматично. Її можна повторити вручну — у кабінеті або через API.
Розклад повторів
| Спроба | Коли |
|---|---|
| 1 | одразу після події |
| 2 | +10 с |
| 3 | +30 с |
| 4 | +1 хв |
| 5 | +5 хв |
| 6 | +15 хв |
| 7 | +1 год |
| 8 | +3 год |
| 9 | +6 год |
Пауза відраховується від попередньої спроби й має розкид ±20%, щоб підписки, які впали разом, не поверталися однією хвилею. Разом — до 9 спроб протягом приблизно 10 годин.
Автоматичне вимкнення
Якщо на URL підписки 7 діб поспіль не проходить жодна доставка, Pager вимикає підписку: enabled стає false, а disabledReason — delivery_failures. Листа про це Pager не надсилає: стан видно в кабінеті й через GET /webhooks/{id}.
Поки серія невдач триває, failingSince показує її початок, а consecutiveFailures — кількість невдалих спроб поспіль. Перша успішна доставка обнуляє обидва поля. Тестові події в серію не рахуються.
Щоб увімкнути підписку знову, натисніть Увімкнути в кабінеті або передайте enabled: true у PATCH /webhooks/{id}. Серія невдач обнуляється, а доставки, що лишилися в черзі, продовжаться.
Обмеження захищають і ваш сервер, і Pager: від зайвого навантаження та від запитів у внутрішню мережу.
- До 10 підписок на організацію. Спроба створити ще одну повертає
400 webhook_limit_reached. - Лише
https://. URL до 2000 символів, без логіна й пароля в адресі. - URL має вести на публічну адресу. Локальні й приватні адреси (
localhost,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16тощо) відхиляються з400 invalid_webhook_url. Адреса перевіряється під час збереження й ще раз перед кожною доставкою, тож підмінити DNS-запис після створення підписки не вийде. - Редиректи не виконуються: відповідь
3xxвважається невдачею. Вказуйте кінцевий URL. - Таймаут — 10 секунд на весь запит, включно з читанням відповіді.
- У журнал потрапляють лише перші 2 КБ тіла відповіді.
- Опис підписки — до 500 символів.
- Доступні події:
message.received,message.sentіcomment.received.
Дані про організацію й ключ, яким підписано запит: тариф, залишок повідомлень, маска ключа й ліміти запитів.
Поля відповіді
organizationobjectid,nameіtimezoneорганізації. Часовий пояс за замовчуванням —Europe/Kyiv.planobject | nullПоточний тариф:
name,maxUsers,maxChannelsіendDate— дата, до якої його оплачено.null, якщо тарифу немає.messagesobject | nullЗалишок повідомлень:
included— із тарифу,extra— докуплених;resetAt— коли оновиться пакет тарифу.apiKeyobjectКлюч запиту:
name, маска (prefix+last4),scopes,createdAtіexpiresAt. Повністю ключ ніколи не повертається.rateLimitsobjectМісткість і швидкість спорожнення кожного відра — див. Ліміти запитів.
Отримати дані організації
/v2/meвага 1Найкращий перший запит інтеграції: якщо він повернув 200, ключ робочий.
curl "https://api.pager.co.ua/v2/me" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"organization": {
"id": "org_2rRfXLYNflNpMgzPBX1MU18z39C",
"name": "Магазин «Квітка»",
"timezone": "Europe/Kyiv"
},
"plan": {
"id": "b1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f",
"name": "Business",
"maxUsers": 10,
"maxChannels": 5,
"endDate": "2026-10-24T00:00:00.000Z"
},
"messages": {
"included": 18240,
"extra": 1500,
"resetAt": "2026-10-01T00:00:00.000Z"
},
"apiKey": {
"name": "Інтеграція з CRM",
"prefix": "pgr_live_",
"last4": "1JgQ",
"scopes": [
"*"
],
"createdAt": "2026-09-12T09:03:44.000Z",
"expiresAt": null
},
"rateLimits": {
"general": {
"capacity": 60,
"ratePerSecond": 10
},
"outbound": {
"capacity": 30,
"ratePerSecond": 1
}
}
}Розмова — листування з одним клієнтом в одному каналі. Список відсортовано за lastMessageAt, від нових до старих. Розмову можна не лише читати, а й змінювати її статус, відповідального, групу й прочитаність, а також надсилати в неї повідомлення.
- Розмови зі статусом
SPAMне приховуються, на відміну від кабінету. Якщо вони вам не потрібні, передайте вstatusIdпотрібні статуси (іnullдля розмов без статусу). - Розмова з новим повідомленням переміщується на початок списку. Для синхронізації використовуйте
updatedSince— див. Пагінація.
Об'єкт розмови
idstringІдентифікатор розмови.
channelIdstringКанал, у якому йде розмова.
clientIdstringКлієнт розмови — див. Клієнти.
statusIdstring | nullСтатус або
null, якщо його не задано.responsibleUserIdstring | nullВідповідальний менеджер або
null.clientGroupIdstring | nullГрупа клієнта або
null.stateenumunread— є непрочитані вхідні повідомлення,read— усе прочитано.lastMessageDirectionenum | nullХто написав останнім:
incoming— клієнт,outgoing— організація.lastMessageAtISO 8601Час останнього повідомлення.
snippetstringТекст останнього повідомлення для прев'ю.
createdAtISO 8601Коли розмову створено.
updatedAtISO 8601Коли розмову востаннє змінено.
clientobject · expandОб'єкт клієнта. Лише з
expand=client.channelobject · expandКанал:
id,name,channelSource,username,imageUrl. Лише зexpand=channel.statusobject · expandОб'єкт статусу. Лише з
expand=status.clientGroupobject · expandОб'єкт групи. Лише з
expand=clientGroup.responsibleUserobject · expandМенеджер:
id,firstName,lastName,imageUrl. Лише зexpand=responsibleUser.
{
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "unread",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
}Список розмов
/v2/conversationsвага 2Повертає розмови сторінками. Приклад нижче — непрочитані розмови без відповідального, разом із клієнтом.
Параметри
channelIdstring[]queryнеобов'язковийЛише розмови з цих каналів.
statusIdstring[]queryнеобов'язковийЛише розмови з цими статусами.
null— розмови без статусу.responsibleUserIdstring[]queryнеобов'язковийЛише розмови цих менеджерів.
null— розмови без відповідального.clientGroupIdstring[]queryнеобов'язковийЛише розмови цих груп.
null— розмови без групи.stateenumqueryнеобов'язковийreadабоunread.directionenumqueryнеобов'язковийХто написав останнім:
incoming— клієнт (чекає на відповідь),outgoing— організація.updatedSinceISO 8601queryнеобов'язковийЛише розмови, змінені від цього моменту. ISO 8601 з часовим поясом.
qstringqueryнеобов'язковийПошук за ідентифікатором розмови, текстом останнього повідомлення, іменем, username, телефоном, email і нотаткою клієнта, а також Zoho ID.
limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.expandstringqueryнеобов'язковийПов'язані об'єкти через кому:
client,channel,status,clientGroup,responsibleUser.
curl "https://api.pager.co.ua/v2/conversations?state=unread&responsibleUserId=null&limit=20&expand=client" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "unread",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T08:31:40.117Z",
"client": {
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
}
}
],
"hasMore": true,
"nextCursor": "WyIyMDI2LTA5LTIzVDE2OjAyOjExLjg0MFoiLCIyYjljNGQ2ZS04ZjBhLTRjMmUtOWI0ZC02ZjhhMGMyZTRiNmQiXQ"
}Кількість розмов
/v2/conversations/countвага 5Приймає ті самі фільтри, що й список, і повертає лише { count } — наприклад, для лічильника непрочитаних на дашборді.
Параметри
channelIdstring[]queryнеобов'язковийЛише розмови з цих каналів.
statusIdstring[]queryнеобов'язковийЛише розмови з цими статусами.
null— розмови без статусу.responsibleUserIdstring[]queryнеобов'язковийЛише розмови цих менеджерів.
null— розмови без відповідального.clientGroupIdstring[]queryнеобов'язковийЛише розмови цих груп.
null— розмови без групи.stateenumqueryнеобов'язковийreadабоunread.directionenumqueryнеобов'язковийХто написав останнім:
incoming— клієнт (чекає на відповідь),outgoing— організація.updatedSinceISO 8601queryнеобов'язковийЛише розмови, змінені від цього моменту. ISO 8601 з часовим поясом.
qstringqueryнеобов'язковийПошук за ідентифікатором розмови, текстом останнього повідомлення, іменем, username, телефоном, email і нотаткою клієнта, а також Zoho ID.
curl "https://api.pager.co.ua/v2/conversations/count?state=unread&responsibleUserId=null" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"count": 17
}Отримати розмову
/v2/conversations/{id}вага 1Повертає одну розмову. Приймає expand.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
expandstringqueryнеобов'язковийПов'язані об'єкти через кому:
client,channel,status,clientGroup,responsibleUser.
curl "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d?expand=client,status,responsibleUser" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "unread",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T08:31:40.117Z",
"client": {
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
},
"status": {
"id": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"name": "В роботі",
"sortIndex": 0,
"systemStatus": "IN_PROGRESS"
},
"responsibleUser": {
"id": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"firstName": "Ірина",
"lastName": "Шевчук",
"imageUrl": null
}
}Оновити розмову
/v2/conversations/{id}вага 1Змінює статус, відповідального, групу чи прочитаність розмови. Змінюються лише передані поля; null очищає поле. Приймає expand, як і отримання розмови.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
expandstringqueryнеобов'язковийПов'язані об'єкти через кому:
client,channel,status,clientGroup,responsibleUser.statusIdstring | nullтілонеобов'язковийНовий статус або
null, щоб прибрати статус.responsibleUserIdstring | nullтілонеобов'язковийНовий відповідальний — учасник організації — або
null, щоб зняти відповідального. Ідентифікатори менеджерів є вresponsibleUserIdрозмов і вexpand=responsibleUser.clientGroupIdstring | nullтілонеобов'язковийНова група або
null, щоб прибрати групу.stateenumтілонеобов'язковийread— позначити прочитаною,unread— непрочитаною.
- Ідентифікатори статусу, групи й менеджера мають належати вашій організації, інакше API поверне
400з відповіднимparam. - Зміни статусу й відповідального потрапляють в історію розмови з
userId: null. - Тіло без жодного поля повертає
400.
curl -X PATCH "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d?expand=status" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"statusId":"7c9e1a3b-5d7f-4a2c-8e6b-0d2f4a6c8e1b","state":"read"}'{
"id": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"clientId": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"statusId": "7c9e1a3b-5d7f-4a2c-8e6b-0d2f4a6c8e1b",
"responsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"clientGroupId": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"state": "read",
"lastMessageDirection": "incoming",
"lastMessageAt": "2026-09-24T08:31:40.117Z",
"snippet": "А доставка у Львів скільки йде?",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T09:02:17.408Z",
"status": {
"id": "7c9e1a3b-5d7f-4a2c-8e6b-0d2f4a6c8e1b",
"name": "Оплачено",
"sortIndex": 3,
"systemStatus": "COMPLETED"
}
}Історія розмови
/v2/conversations/{id}/historyвага 2Зміни статусу й відповідального однією стрічкою, від нових до старих, сторінками.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.
type—status_changed(поляoldStatusId,newStatusId) абоresponsible_changed(поляoldResponsibleUserId,newResponsibleUserId).userId— хто зробив зміну.nullозначає, що зміну зроблено через API або автоматикою (наприклад, розсилкою), а не менеджером у кабінеті.
curl "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/history" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "f0e1d2c3-b4a5-4968-8776-655443322110",
"type": "status_changed",
"userId": null,
"oldStatusId": "7c9e1a3b-5d7f-4a2c-8e6b-0d2f4a6c8e1b",
"newStatusId": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"createdAt": "2026-09-24T08:40:03.221Z"
},
{
"id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
"type": "responsible_changed",
"userId": "user_2rRfXLYNflNpMgzPBX1MU18z39C",
"oldResponsibleUserId": null,
"newResponsibleUserId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"createdAt": "2026-09-23T16:01:12.650Z"
}
],
"hasMore": false,
"nextCursor": null
}Замовлення розмови
/v2/conversations/{id}/ordersвага 2Замовлення, створені з цієї розмови, від нових до старих. Повертаються цілком, без пагінації.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
amount— сума замовлення, ціле число.crm— куди передано замовлення:LP_CRM,ZOHOабоnull;externalId— номер замовлення в цій CRM.userId— менеджер, який оформив замовлення.
curl "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/orders" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "0c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"userId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"amount": 1450,
"externalId": "184502",
"crm": "LP_CRM",
"createdAt": "2026-09-23T16:20:31.000Z",
"updatedAt": "2026-09-23T16:20:31.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Повідомлення розмови
/v2/conversations/{id}/messagesвага 2Повідомлення однієї розмови сторінками, від нових до старих. Формат — об'єкт повідомлення.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.updatedSinceISO 8601queryнеобов'язковийЛише повідомлення, змінені від цього моменту (нові, відредаговані, зі зміненим статусом доставки чи реакцією).
curl "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/messages?limit=2" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "incoming",
"text": "А доставка у Львів скільки йде?",
"attachments": [],
"authorId": null,
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": false,
"isEdited": false,
"isDelivered": null,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-24T08:31:40.117Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
},
{
"id": "c9d8e7f6-a5b4-4c3d-9e2f-1a0b9c8d7e6f",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "outgoing",
"text": "Відправляємо Новою поштою по всій Україні, доставка 1–2 дні.",
"attachments": [],
"authorId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": true,
"isEdited": false,
"isDelivered": true,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-23T16:05:02.004Z",
"updatedAt": "2026-09-23T16:05:02.004Z"
}
],
"hasMore": true,
"nextCursor": "WyIyMDI2LTA5LTI0VDA4OjMxOjQwLjExN1oiLCJkMWUyZjNhNC1iNWM2LTRkN2UtOGY5YS0wYjFjMmQzZTRmNWEiXQ"
}Надіслати повідомлення
/v2/conversations/{id}/messagesвага 1outbound 1Надсилає клієнту текст або файл від імені організації — через канал розмови, так само як менеджер із кабінету. Повертає збережене повідомлення з кодом 201.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
Idempotency-Keystringзаголовокнеобов'язковийКлюч, з яким повтор запиту не надішле повідомлення вдруге — див. Ідемпотентність.
textstringтілонеобов'язковийТекст повідомлення, від 1 до 4096 символів. Не передається разом з
attachments.attachmentsobject[]тілонеобов'язковийМасив з одним вкладенням — об'єкт
attachmentз POST /files без змін. Вкладення іншої розмови чи власний URL файлу повертають400 invalid_attachment.replyToMessageIdstringтілонеобов'язковийПовідомлення цієї розмови, на яке ви відповідаєте. Повідомлення з іншої розмови повертає
400.
- Передайте або
text, абоattachmentsз одним файлом — не обидва разом, інакше400. Як завантажити файл — див. Надсилання файлів. - Текст — до 4096 символів. У деяких месенджерів ліміт менший — тоді відмова прийде як
422. authorIdу відповіді —null: повідомлення надіслано через API, а не менеджером.- Передавайте
Idempotency-Key: якщо відповідь не дійшла через таймаут, повтор із тим самим ключем не надішле клієнту повідомлення вдруге. - Перед відправкою перевіряється тариф: якщо план закінчився або вичерпано баланс повідомлень —
402 message_limit_reached. Надіслане повідомлення враховується в ліміті. - Відправка працює для Instagram, Facebook Messenger, Telegram-бота, особистого Telegram, Viber і WhatsApp через e-chat, вебчату й кастомних каналів. Для інших каналів —
422 channel_unsupported. - Якщо месенджер відмовив (наприклад, з останнього повідомлення клієнта в Instagram чи Facebook минуло забагато часу), API поверне
422 channel_rejected. Повідомлення при цьому збережене як недоставлене — менеджер побачить його в кабінеті, а йогоidє в тексті помилки. - Після відправки розмова стає прочитаною й піднімається вгору списку.
- Окрім ваги
1у відріgeneral, займає1у відріoutbound— див. Ліміти запитів.
curl -X POST "https://api.pager.co.ua/v2/conversations/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/messages" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Idempotency-Key: a3f1c9e2-5b7d-4e8a-9c0b-1d2e3f4a5b6c" \
-H "Content-Type: application/json" \
-d '{"text":"Доставка у Львів — 1–2 дні, від 80 грн. Оформити замовлення?","replyToMessageId":"d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a"}'{
"id": "e5f6a7b8-c9d0-4e1f-a2b3-c4d5e6f7a8b9",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "outgoing",
"text": "Доставка у Львів — 1–2 дні, від 80 грн. Оформити замовлення?",
"attachments": [],
"authorId": null,
"replyToMessageId": "d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a",
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": false,
"isEdited": false,
"isDelivered": true,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-24T08:34:02.771Z",
"updatedAt": "2026-09-24T08:34:02.771Z"
}Повідомлення розмов. Щоб прочитати листування, використовуйте повідомлення розмови; цей ресурс — для пошуку по всій організації й отримання одного повідомлення.
- Пошук по всій організації важчий за читання однієї розмови, тому його вага —
5. Якщо знаєте розмову, читайте її повідомлення. - Посилання у
attachments[].urlтимчасові, термін дії — уexpiresAt.
Об'єкт повідомлення
idstringІдентифікатор повідомлення.
conversationIdstringРозмова, до якої належить повідомлення.
directionenumincoming— від клієнта,outgoing— від організації.textstring | nullТекст або
null, якщо в повідомленні лише вкладення.attachmentsobject[]Вкладення:
type(image,video,audioабоdocument),url,name,mime,sizeу байтах іexpiresAt.authorIdstring | nullМенеджер, який надіслав повідомлення.
nullу вхідних, а також у вихідних, надісланих через API, розсилкою чи автоматикою.replyToMessageIdstring | nullПовідомлення, на яке це є відповіддю, або
null.externalIdstring | nullІдентифікатор повідомлення в месенджері.
reactionstring | nullРеакція на повідомлення, наприклад емодзі, або
null.isReadbooleanЧи прочитано повідомлення.
isEditedbooleanЧи редагувалося повідомлення.
isDeliveredboolean | nulltrue/false— відповідь месенджера про доставку.null— месенджер статусу не повертає (Viber і WhatsApp через e-chat) або повідомлення вхідне.errorMessagestring | nullЧому повідомлення не доставлено, або
null.adobject | nullРеклама, з якої клієнт написав:
id,url,text.null, якщо повідомлення не з реклами.storyReplyUrlstring | nullСторіз, на яку відповів клієнт, або
null.createdAtISO 8601Коли повідомлення надіслано.
updatedAtISO 8601Коли повідомлення востаннє змінено.
{
"id": "c9d8e7f6-a5b4-4c3d-9e2f-1a0b9c8d7e6f",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "outgoing",
"text": "Відправляємо Новою поштою по всій Україні, доставка 1–2 дні.",
"attachments": [],
"authorId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": true,
"isEdited": false,
"isDelivered": true,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-23T16:05:02.004Z",
"updatedAt": "2026-09-23T16:05:02.004Z"
}Пошук повідомлень
/v2/messagesвага 5Шукає повідомлення по всіх розмовах організації, від нових до старих. Приклад нижче — вхідні повідомлення з вересня, де згадується «розмір».
Параметри
qstringqueryнеобов'язковийПошук за текстом повідомлення, без урахування регістру.
channelIdstring[]queryнеобов'язковийЛише повідомлення з розмов цих каналів.
directionenumqueryнеобов'язковийincoming— від клієнтів,outgoing— від організації.fromISO 8601queryнеобов'язковийПочаток періоду за
createdAt, включно. ISO 8601.toISO 8601queryнеобов'язковийКінець періоду за
createdAt, включно. ISO 8601.updatedSinceISO 8601queryнеобов'язковийЛише повідомлення, змінені від цього моменту.
limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.
curl "https://api.pager.co.ua/v2/messages?q=розмір&direction=incoming&from=2026-09-01T00:00:00Z" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "7a6b5c4d-3e2f-4a1b-8c9d-0e1f2a3b4c5d",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "incoming",
"text": "Доброго дня! Чи є в наявності розмір M?",
"attachments": [],
"authorId": null,
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": false,
"isEdited": false,
"isDelivered": null,
"errorMessage": null,
"ad": {
"id": "120214567890123456",
"url": "https://fb.me/…",
"text": "Осіння колекція −20%"
},
"storyReplyUrl": null,
"createdAt": "2026-09-23T15:58:44.910Z",
"updatedAt": "2026-09-23T15:58:44.910Z"
}
],
"hasMore": false,
"nextCursor": null
}Отримати повідомлення
/v2/messages/{id}вага 1Повертає одне повідомлення.
Параметри
idstringшляхобов'язковийІдентифікатор повідомлення.
curl "https://api.pager.co.ua/v2/messages/d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"direction": "incoming",
"text": "А доставка у Львів скільки йде?",
"attachments": [],
"authorId": null,
"replyToMessageId": null,
"externalId": "aWdfZAG1faXRlbTo…",
"reaction": null,
"isRead": false,
"isEdited": false,
"isDelivered": null,
"errorMessage": null,
"ad": null,
"storyReplyUrl": null,
"createdAt": "2026-09-24T08:31:40.117Z",
"updatedAt": "2026-09-24T08:31:40.117Z"
}Завантаження файлу в сховище Pager, щоб надіслати його клієнту. API не приймає файл напряму: POST /files видає тимчасове посилання, на яке ви завантажуєте файл, і готовий об'єкт вкладення для повідомлення. Покроково — див. Надсилання файлів.
- До 20 МБ. Дозволені зображення, відео, аудіо (крім SVG), а також PDF, ZIP, DOC/DOCX, XLS/XLSX, PPT/PPTX, TXT і CSV. Інший тип повертає
400зparam: "mime". - Файл прив'язаний до розмови з
conversationId: надіслати його можна лише в цю розмову.
Поля відповіді
uploadUrlstringТимчасове посилання для завантаження файлу.
methodstringHTTP-метод завантаження —
PUT.headersobjectЗаголовки, які треба передати під час завантаження, дослівно.
Content-Typeвходить у підпис посилання.expiresInintegerСкільки секунд діє посилання —
300.expiresAtISO 8601До якого моменту треба почати завантаження.
maxBytesintegerМаксимальний розмір файлу в байтах.
attachmentobjectГотове вкладення: після завантаження передайте цей об'єкт без змін у
attachmentsвідправки повідомлення.
Отримати посилання для завантаження
/v2/filesвага 1Повертає посилання для завантаження й готовий об'єкт вкладення з кодом 201.
Параметри
conversationIdstringтілообов'язковийРозмова, у яку ви надішлете файл.
namestringтілообов'язковийНазва файлу, до 255 символів. Клієнт побачить її в месенджері.
mimestringтілообов'язковийMIME-тип файлу, наприклад
application/pdfчиimage/jpeg.sizeintegerтілообов'язковийРозмір файлу в байтах, до 20 МБ.
- Посилання діє 5 хвилин — стільки є, щоб почати завантаження. Повільне завантаження великого файлу не перерветься.
- Завантажуйте запитом
PUTнаuploadUrlіз заголовками зheaders, безAuthorization. Тіло запиту — сам файл. - Розмір і тип перевіряються ще раз під час відправки повідомлення — за фактично завантаженим файлом.
curl -X POST "https://api.pager.co.ua/v2/files" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"conversationId":"2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d","name":"invoice-184502.pdf","mime":"application/pdf","size":248193}'{
"uploadUrl": "https://files.pager.co.ua/…/7f3e2d1c-0b9a-4c8d-9e7f-6a5b4c3d2e1f?X-Amz-Expires=300&X-Amz-Signature=…",
"method": "PUT",
"headers": {
"Content-Type": "application/pdf"
},
"expiresIn": 300,
"maxBytes": 20971520,
"attachment": {
"type": "document",
"payload": {
"key": "org_2rRfXLYNflNpMgzPBX1MU18z39C/2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d/7f3e2d1c-0b9a-4c8d-9e7f-6a5b4c3d2e1f",
"name": "invoice-184502.pdf",
"mime": "application/pdf",
"size": 248193
}
},
"expiresAt": "2026-09-24T08:44:12.000Z"
}Клієнт — людина, яка написала в один із каналів організації. У кожного клієнта одна розмова. Список відсортовано за датою створення, від нових до старих. Картку клієнта можна заповнювати через API.
phone— номер клієнта в месенджері (Telegram, Viber, WhatsApp). Поляinfo*— картка клієнта, яку заповнює менеджер або CRM.- Внутрішні ідентифікатори платформ (PSID, Telegram ID) не повертаються.
Об'єкт клієнта
idstringІдентифікатор клієнта.
channelIdstringКанал, у який написав клієнт.
conversationIdstring | nullРозмова з клієнтом.
externalIdstring | nullІдентифікатор клієнта у зовнішній системі, або
null.namestring | nullІм'я з профілю месенджера.
usernamestring | nullUsername у месенджері.
imageUrlstring | nullАватар.
phonestring | nullНомер у месенджері, якщо він відомий.
infoNamestring | nullІм'я в картці клієнта.
infoLastNamestring | nullПрізвище в картці клієнта.
infoPhonestring | nullТелефон у картці клієнта.
infoEmailstring | nullEmail у картці клієнта.
infoAddressstring | nullАдреса в картці клієнта.
infoNotestring | nullНотатка менеджера.
createdAtISO 8601Коли клієнт уперше написав.
updatedAtISO 8601Коли дані клієнта востаннє змінено.
{
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
}Список клієнтів
/v2/clientsвага 2Повертає клієнтів сторінками. Приклад нижче — пошук за номером телефону.
Параметри
channelIdstring[]queryнеобов'язковийЛише клієнти з цих каналів.
clientGroupIdstring[]queryнеобов'язковийЛише клієнти, чия розмова в цих групах.
null— клієнти без групи.updatedSinceISO 8601queryнеобов'язковийЛише клієнти, змінені від цього моменту.
qstringqueryнеобов'язковийПошук за іменем, username, зовнішнім ID, телефонами в месенджерах і полями картки: ім'ям, прізвищем, телефоном, email.
limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.
curl "https://api.pager.co.ua/v2/clients?q=0671234567" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
}
],
"hasMore": false,
"nextCursor": null
}Отримати клієнта
/v2/clients/{id}вага 1Повертає одного клієнта.
Параметри
idstringшляхобов'язковийІдентифікатор клієнта.
curl "https://api.pager.co.ua/v2/clients/3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": null,
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Київ, НП №52",
"infoNote": "Цікавиться оптовими цінами",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-23T15:02:11.840Z"
}Оновити клієнта
/v2/clients/{id}вага 1Заповнює картку клієнта. Змінюються лише передані поля; null очищає поле, пробіли на краях обрізаються.
Параметри
idstringшляхобов'язковийІдентифікатор клієнта.
infoNamestring | nullтілонеобов'язковийІм'я в картці, до 255 символів.
infoLastNamestring | nullтілонеобов'язковийПрізвище в картці, до 255 символів.
infoPhonestring | nullтілонеобов'язковийТелефон у картці, до 50 символів.
infoEmailstring | nullтілонеобов'язковийEmail у картці. Має бути коректною адресою, інакше
400.infoAddressstring | nullтілонеобов'язковийАдреса в картці, до 500 символів.
infoNotestring | nullтілонеобов'язковийНотатка, до 8000 символів.
externalIdstring | nullтілонеобов'язковийІдентифікатор клієнта у вашій системі, до 255 символів, унікальний у межах каналу.
- Якщо підключено інтеграцію з Zoho CRM і змінено ім'я, прізвище, телефон чи email, картка синхронізується в Zoho — так само, як після зміни в кабінеті.
externalId, зайнятий іншим клієнтом цього каналу, повертає409 external_id_taken.- Для клієнтів кастомного каналу
externalId— це ідентифікатор, за яким Pager знаходить клієнта й надсилає йому відповіді. Змінюйте його, лише якщо змінився ідентифікатор на вашій платформі. - Тіло без жодного поля повертає
400.
curl -X PATCH "https://api.pager.co.ua/v2/clients/3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"infoAddress":"Львів, НП №12","infoNote":"Оптовий клієнт, знижка 10%","externalId":"crm-10482"}'{
"id": "3b0f6c1e-5d2a-4f7e-9c41-2a8e7d9b1f03",
"channelId": "e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"conversationId": "2b9c4d6e-8f0a-4c2e-9b4d-6f8a0c2e4b6d",
"externalId": "crm-10482",
"name": "Олена Коваль",
"username": "olena.koval",
"imageUrl": "https://files.pager.co.ua/…/avatar.jpg",
"phone": null,
"infoName": "Олена",
"infoLastName": "Коваль",
"infoPhone": "+380671234567",
"infoEmail": "olena@example.com",
"infoAddress": "Львів, НП №12",
"infoNote": "Оптовий клієнт, знижка 10%",
"createdAt": "2026-08-14T09:21:37.512Z",
"updatedAt": "2026-09-24T09:05:41.132Z"
}Менеджери й адміністратори організації. userId — той самий ідентифікатор, що в responsibleUserId розмов, authorId повідомлень і userId історії. Через API можна читати учасників і змінювати, які канали вони бачать.
- Запросити чи видалити учасника й змінити його роль можна лише в кабінеті. Поле
roleуPATCHповертає400 unknown_parameter. - Повертаються цілком, без пагінації, у порядку приєднання до організації.
Об'єкт учасника
userIdstringІдентифікатор користувача,
user_….firstNamestring | nullІм'я або
null.lastNamestring | nullПрізвище або
null.emailsstring[]Email-адреси користувача.
imageUrlstring | nullАватар або
null.rolestringРоль в організації:
org:admin— адміністратор,org:member— менеджер.accessibleChannelsstring[]Канали, розмови яких учасник бачить у кабінеті. Розмови інших каналів для нього приховані.
createdAtISO 8601Коли користувач зареєструвався в Pager.
{
"userId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"firstName": "Ірина",
"lastName": "Шевчук",
"emails": [
"iryna@kvitka.shop"
],
"imageUrl": null,
"role": "org:member",
"accessibleChannels": [
"e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a"
],
"createdAt": "2026-08-02T09:40:11.000Z"
}Список учасників
/v2/membersвага 2Повертає всіх учасників організації.
curl "https://api.pager.co.ua/v2/members" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"userId": "user_2rRfXLYNflNpMgzPBX1MU18z39C",
"firstName": "Андрій",
"lastName": "Мельник",
"emails": [
"owner@kvitka.shop"
],
"imageUrl": "https://img.clerk.com/…",
"role": "org:admin",
"accessibleChannels": [
"e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d"
],
"createdAt": "2026-07-18T12:03:27.000Z"
},
{
"userId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"firstName": "Ірина",
"lastName": "Шевчук",
"emails": [
"iryna@kvitka.shop"
],
"imageUrl": null,
"role": "org:member",
"accessibleChannels": [
"e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a"
],
"createdAt": "2026-08-02T09:40:11.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Отримати учасника
/v2/members/{userId}вага 1Повертає одного учасника.
Параметри
userIdstringшляхобов'язковийІдентифікатор користувача,
user_….
curl "https://api.pager.co.ua/v2/members/user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"userId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"firstName": "Ірина",
"lastName": "Шевчук",
"emails": [
"iryna@kvitka.shop"
],
"imageUrl": null,
"role": "org:member",
"accessibleChannels": [
"e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a"
],
"createdAt": "2026-08-02T09:40:11.000Z"
}Змінити доступ до каналів
/v2/members/{userId}вага 1Замінює список каналів, які бачить учасник, і повертає оновленого учасника.
Параметри
userIdstringшляхобов'язковийІдентифікатор користувача,
user_….accessibleChannelsstring[]тілообов'язковийПовний новий список каналів, до 500. Канали, яких немає в списку, учасник бачити перестане; порожній масив приховує всі канали.
- Це повна заміна, а не додавання: щоб відкрити ще один канал, передайте поточний список разом із ним.
- Кожен канал має належати вашій організації, інакше
400 channel_not_foundзparam: "accessibleChannels". Повтори в масиві прибираються. - Ідентифікатори каналів є в
channelIdрозмов і клієнтів.
curl -X PATCH "https://api.pager.co.ua/v2/members/user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"accessibleChannels":["e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a","a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d"]}'{
"userId": "user_2sKq8vB3nT1mZ7wYcR4dF6hJ9pL",
"firstName": "Ірина",
"lastName": "Шевчук",
"emails": [
"iryna@kvitka.shop"
],
"imageUrl": null,
"role": "org:member",
"accessibleChannels": [
"e4b2a1c9-6d8f-4e3a-b7c5-0f9e8d7c6b5a",
"a7b8c9d0-e1f2-4a3b-8c4d-5e6f7a8b9c0d"
],
"createdAt": "2026-08-02T09:40:11.000Z"
}Статуси розмов — етапи, якими менеджери позначають розмови в кабінеті. Повертаються в порядку sortIndex, як у кабінеті.
- Видалення статусу не видаляє розмови: вони лишаються без статусу, як і після видалення в кабінеті.
Об'єкт статусу
idstringІдентифікатор статусу.
namestringНазва, до 100 символів.
sortIndexintegerПозиція в списку, від
0.systemStatusenum | nullСистемна категорія:
IN_PROGRESS,CONSIDERING,COMPLETED,DECLINED,SPAMабоnullдля звичайного статусу.
{
"id": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"name": "В роботі",
"sortIndex": 0,
"systemStatus": "IN_PROGRESS"
}Список статусів
/v2/statusesвага 2Повертає всі статуси організації.
curl "https://api.pager.co.ua/v2/statuses" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"name": "В роботі",
"sortIndex": 0,
"systemStatus": "IN_PROGRESS"
}
],
"hasMore": false,
"nextCursor": null
}Створити статус
/v2/statusesвага 1Створює статус і повертає його з кодом 201.
Параметри
namestringтілообов'язковийНазва статусу, від 1 до 100 символів.
sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, статус стане останнім.systemStatusenum | nullтілонеобов'язковийСистемна категорія (
IN_PROGRESS,CONSIDERING,COMPLETED,DECLINED,SPAM) абоnull.
curl -X POST "https://api.pager.co.ua/v2/statuses" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Чекає на оплату","systemStatus":"CONSIDERING"}'{
"id": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"name": "Чекає на оплату",
"sortIndex": 0,
"systemStatus": "CONSIDERING"
}Оновити статус
/v2/statuses/{id}вага 1Змінює лише передані поля. Тіло без жодного поля повертає 400.
Параметри
idstringшляхобов'язковийІдентифікатор статусу.
namestringтілонеобов'язковийНазва статусу, від 1 до 100 символів.
sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, статус стане останнім.systemStatusenum | nullтілонеобов'язковийСистемна категорія (
IN_PROGRESS,CONSIDERING,COMPLETED,DECLINED,SPAM) абоnull.
curl -X PATCH "https://api.pager.co.ua/v2/statuses/5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Оплачено","systemStatus":"COMPLETED"}'{
"id": "5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e",
"name": "Оплачено",
"sortIndex": 0,
"systemStatus": "COMPLETED"
}Видалити статус
/v2/statuses/{id}вага 1Видаляє статус і відповідає 204. Розмови з цим статусом лишаються без статусу.
Параметри
idstringшляхобов'язковийІдентифікатор статусу.
curl -X DELETE "https://api.pager.co.ua/v2/statuses/5a7e9c1d-3f2b-4d8a-b6e0-9c1f2a3b4d5e" \
-H "Authorization: Bearer $PAGER_API_KEY"Групи, якими менеджери позначають клієнтів у кабінеті, — наприклад, «Опт» чи «VIP». Повертаються в порядку sortIndex.
- Видалення групи не видаляє розмови: вони лишаються без групи, як і після видалення в кабінеті.
Об'єкт групи
idstringІдентифікатор групи.
namestringНазва, до 100 символів.
colorstringКолір у форматі
#rrggbb— саме так його зберігає кабінет.sortIndexintegerПозиція в списку, від
0.
{
"id": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"name": "Опт",
"color": "#7c5cff",
"sortIndex": 0
}Список груп
/v2/client-groupsвага 2Повертає всі групи клієнтів організації.
curl "https://api.pager.co.ua/v2/client-groups" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"name": "Опт",
"color": "#7c5cff",
"sortIndex": 0
}
],
"hasMore": false,
"nextCursor": null
}Створити групу
/v2/client-groupsвага 1Створює групу й повертає її з кодом 201.
Параметри
namestringтілообов'язковийНазва групи, від 1 до 100 символів.
colorstringтілообов'язковийКолір у форматі
#rrggbb, наприклад#7c5cff. Інші формати (red,#fff,rgb(…)) повертають400.sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, група стане останньою.
curl -X POST "https://api.pager.co.ua/v2/client-groups" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"VIP","color":"#f59e0b"}'{
"id": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"name": "VIP",
"color": "#f59e0b",
"sortIndex": 0
}Оновити групу
/v2/client-groups/{id}вага 1Змінює лише передані поля. Тіло без жодного поля повертає 400.
Параметри
idstringшляхобов'язковийІдентифікатор групи.
namestringтілонеобов'язковийНазва групи, від 1 до 100 символів.
colorstringтілонеобов'язковийКолір у форматі
#rrggbb, наприклад#7c5cff. Інші формати (red,#fff,rgb(…)) повертають400.sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, група стане останньою.
curl -X PATCH "https://api.pager.co.ua/v2/client-groups/1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"color":"#16a34a"}'{
"id": "1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e",
"name": "Опт",
"color": "#16a34a",
"sortIndex": 0
}Видалити групу
/v2/client-groups/{id}вага 1Видаляє групу й відповідає 204. Розмови цієї групи лишаються без групи.
Параметри
idstringшляхобов'язковийІдентифікатор групи.
curl -X DELETE "https://api.pager.co.ua/v2/client-groups/1c3e5a7b-9d2f-4b6c-8e0a-2f4d6b8a0c1e" \
-H "Authorization: Bearer $PAGER_API_KEY"Папки, у яких згруповано шаблони відповідей. Повертаються в порядку sortIndex.
- Видалення папки видаляє й усі її шаблони, як у кабінеті. Відновити їх не вийде.
updatedSinceповертає лише папки, змінені від указаного моменту, — зручно для синхронізації. Видалених папок у відповіді немає: звіряйте повний список, щоб їх помітити.
Об'єкт папки
idstringІдентифікатор папки.
namestringНазва, до 100 символів.
sortIndexintegerПозиція в списку, від
0.createdAtISO 8601Коли папку створено.
updatedAtISO 8601Коли папку востаннє змінено.
{
"id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"name": "Доставка",
"sortIndex": 0,
"createdAt": "2026-08-02T10:15:00.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Список папок
/v2/saved-reply-foldersвага 2Повертає папки шаблонів організації.
Параметри
updatedSinceISO 8601queryнеобов'язковийПовернути лише папки, оновлені від цього моменту. ISO 8601 з часовим поясом, наприклад
2026-09-01T00:00:00Z.
curl "https://api.pager.co.ua/v2/saved-reply-folders?updatedSince=2026-09-01T00:00:00Z" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"name": "Доставка",
"sortIndex": 0,
"createdAt": "2026-08-02T10:15:00.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Створити папку
/v2/saved-reply-foldersвага 1Створює порожню папку й повертає її з кодом 201.
Параметри
namestringтілообов'язковийНазва папки, від 1 до 100 символів.
sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, папка стане останньою.
curl -X POST "https://api.pager.co.ua/v2/saved-reply-folders" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Оплата"}'{
"id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"name": "Оплата",
"sortIndex": 0,
"createdAt": "2026-08-02T10:15:00.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Оновити папку
/v2/saved-reply-folders/{id}вага 1Змінює лише передані поля. Тіло без жодного поля повертає 400.
Параметри
idstringшляхобов'язковийІдентифікатор папки.
namestringтілонеобов'язковийНазва папки, від 1 до 100 символів.
sortIndexintegerтілонеобов'язковийПозиція в списку, від
0. Якщо не передати під час створення, папка стане останньою.
curl -X PATCH "https://api.pager.co.ua/v2/saved-reply-folders/9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Доставка й оплата"}'{
"id": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"name": "Доставка й оплата",
"sortIndex": 0,
"createdAt": "2026-08-02T10:15:00.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Видалити папку
/v2/saved-reply-folders/{id}вага 1Видаляє папку разом з усіма її шаблонами й відповідає 204.
Параметри
idstringшляхобов'язковийІдентифікатор папки.
curl -X DELETE "https://api.pager.co.ua/v2/saved-reply-folders/9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b" \
-H "Authorization: Bearer $PAGER_API_KEY"Готові відповіді, які менеджери вставляють у розмову в один клік. Повертаються згруповані за папками, у порядку sortIndex.
folderIdмає належати вашій організації, інакше API поверне400зparam: "folderId".- Вкладення шаблонів поки доступні лише для читання: додати чи змінити їх через API не можна.
- Посилання
attachments[].urlтимчасові, термін дії — уexpiresAt. Не зберігайте їх, а запитуйте шаблон повторно.
Об'єкт шаблону
idstringІдентифікатор шаблону.
folderIdstringПапка, у якій лежить шаблон.
textstringТекст шаблону, до 8000 символів.
sortIndexintegerПозиція в папці, від
0.attachmentsobject[]Вкладення:
type(image,video,audioабоdocument),url,name,mime,sizeу байтах іexpiresAt.createdAtISO 8601Коли шаблон створено.
updatedAtISO 8601Коли шаблон востаннє змінено.
{
"id": "3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9",
"folderId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"text": "Відправляємо Новою поштою по всій Україні, доставка 1–2 дні.",
"sortIndex": 0,
"attachments": [
{
"type": "image",
"url": "https://files.pager.co.ua/…/tariffs.png?X-Amz-Expires=3600&…",
"name": "tariffs.png",
"mime": "image/png",
"size": 184320,
"expiresAt": "2026-09-24T13:00:00.000Z"
}
],
"createdAt": "2026-08-02T10:16:12.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Список шаблонів
/v2/saved-repliesвага 2Повертає шаблони відповідей організації.
Параметри
folderIdstringqueryнеобов'язковийПовернути шаблони лише з цієї папки.
updatedSinceISO 8601queryнеобов'язковийПовернути лише шаблони, оновлені від цього моменту. ISO 8601 з часовим поясом.
curl "https://api.pager.co.ua/v2/saved-replies?folderId=9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9",
"folderId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"text": "Відправляємо Новою поштою по всій Україні, доставка 1–2 дні.",
"sortIndex": 0,
"attachments": [
{
"type": "image",
"url": "https://files.pager.co.ua/…/tariffs.png?X-Amz-Expires=3600&…",
"name": "tariffs.png",
"mime": "image/png",
"size": 184320,
"expiresAt": "2026-09-24T13:00:00.000Z"
}
],
"createdAt": "2026-08-02T10:16:12.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}
],
"hasMore": false,
"nextCursor": null
}Створити шаблон
/v2/saved-repliesвага 1Створює шаблон у папці й повертає його з кодом 201.
Параметри
folderIdstringтілообов'язковийПапка шаблону. Під час оновлення переносить шаблон в іншу папку.
textstringтілообов'язковийТекст шаблону, від 1 до 8000 символів.
sortIndexintegerтілонеобов'язковийПозиція в папці, від
0. Якщо не передати під час створення, шаблон стане останнім у папці.
curl -X POST "https://api.pager.co.ua/v2/saved-replies" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"folderId":"9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b","text":"Оплата при отриманні або на картку ФОП."}'{
"id": "3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9",
"folderId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"text": "Оплата при отриманні або на картку ФОП.",
"sortIndex": 0,
"attachments": [],
"createdAt": "2026-08-02T10:16:12.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Оновити шаблон
/v2/saved-replies/{id}вага 1Змінює лише передані поля. Щоб перенести шаблон в іншу папку, передайте новий folderId.
Параметри
idstringшляхобов'язковийІдентифікатор шаблону.
folderIdstringтілонеобов'язковийПапка шаблону. Під час оновлення переносить шаблон в іншу папку.
textstringтілонеобов'язковийТекст шаблону, від 1 до 8000 символів.
sortIndexintegerтілонеобов'язковийПозиція в папці, від
0. Якщо не передати під час створення, шаблон стане останнім у папці.
curl -X PATCH "https://api.pager.co.ua/v2/saved-replies/3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Оплата при отриманні, на картку ФОП або через Apple Pay."}'{
"id": "3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9",
"folderId": "9e8d7c6b-5a4f-4e3d-8c2b-1a0f9e8d7c6b",
"text": "Оплата при отриманні, на картку ФОП або через Apple Pay.",
"sortIndex": 0,
"attachments": [
{
"type": "image",
"url": "https://files.pager.co.ua/…/tariffs.png?X-Amz-Expires=3600&…",
"name": "tariffs.png",
"mime": "image/png",
"size": 184320,
"expiresAt": "2026-09-24T13:00:00.000Z"
}
],
"createdAt": "2026-08-02T10:16:12.000Z",
"updatedAt": "2026-09-20T08:41:27.000Z"
}Видалити шаблон
/v2/saved-replies/{id}вага 1Видаляє шаблон і відповідає 204.
Параметри
idstringшляхобов'язковийІдентифікатор шаблону.
curl -X DELETE "https://api.pager.co.ua/v2/saved-replies/3f2e1d0c-9b8a-4f7e-a6d5-c4b3a2f1e0d9" \
-H "Authorization: Bearer $PAGER_API_KEY"Підписки, на які Pager надсилає події, і журнал їхніх доставок. Це той самий список, що й у Налаштування → API → Вебхуки в кабінеті. Як приймати й перевіряти події — див. Вебхуки.
- Секрет підпису повертається лише у відповідях на створення й перевипуск секрету. В інших відповідях його немає.
- Підписка іншої організації дає
404 webhook_not_found, як і неіснуюча.
Об'єкт підписки
idstringІдентифікатор підписки.
urlstringАдреса, на яку надсилаються події.
eventsenum[]Події, на які оформлено підписку:
message.received,message.sent,comment.received.descriptionstring | nullОпис для себе або
null.enabledbooleanЧи надсилаються події на цю підписку.
consecutiveFailuresintegerНевдалих спроб доставки поспіль. Обнуляється першою успішною доставкою.
failingSinceISO 8601 | nullПочаток поточної серії невдач або
null. Через 7 діб серії підписка вимикається автоматично — див. Доставка й повтори.disabledAtISO 8601 | nullКоли підписку вимкнено, або
null, якщо вона увімкнена.disabledReasonenum | nullmanual— вимкнено вручну в кабінеті чи через API,delivery_failures— автоматично після 7 діб невдач,null— підписка увімкнена.createdAtISO 8601Коли підписку створено.
updatedAtISO 8601Коли підписку востаннє змінено.
{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received",
"message.sent"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T09:12:05.301Z"
}Список підписок
/v2/webhooksвага 2Повертає всі підписки організації цілком, без пагінації.
curl "https://api.pager.co.ua/v2/webhooks" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received",
"message.sent"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T09:12:05.301Z"
}
],
"hasMore": false,
"nextCursor": null
}Створити підписку
/v2/webhooksвага 1Створює підписку й повертає її з кодом 201 разом із секретом підпису в полі secret. Збережіть секрет одразу: більше API його не поверне.
Параметри
Idempotency-Keystringзаголовокнеобов'язковийКлюч, з яким повтор запиту не створить другу підписку — див. Ідемпотентність.
urlstringтілообов'язковийПублічний
https://URL, до 2000 символів — див. Обмеження.eventsenum[]тілообов'язковийНепорожній масив подій:
message.received,message.sent,comment.received. Повтори в масиві прибираються.descriptionstring | nullтілонеобов'язковийОпис до 500 символів або
null.enabledbooleanтілонеобов'язковийfalse— підписка існує, але події не надсилаються. За замовчуваннямtrue.
- URL перевіряється під час створення. Не-
https, приватна адреса чи домен, який не резолвиться, повертають400 invalid_webhook_urlзparam: "url"; причина — уmessage. - Передавайте
Idempotency-Key: якщо відповідь загубилася, повтор із тим самим ключем поверне ту саму підписку з тим самим секретом, а не створить другу. - Після створення перевірте ендпоінт тестовою подією.
curl -X POST "https://api.pager.co.ua/v2/webhooks" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Idempotency-Key: a3f1c9e2-5b7d-4e8a-9c0b-1d2e3f4a5b6c" \
-H "Content-Type: application/json" \
-d '{"url":"https://crm.example.com/pager/webhook","events":["message.received","message.sent"],"description":"Синхронізація з CRM"}'{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received",
"message.sent"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T09:12:05.301Z",
"secret": "whsec_2Xk9vQ7mB4nR1tY8wZ3cL6pF0hJ5sD2gA9eU4iO7qWx"
}Отримати підписку
/v2/webhooks/{id}вага 1Повертає підписку й статистику доставок за останні 30 днів у полі stats: delivered — доставлено, pending — у черзі або чекають на повтор, dead — не доставлено після всіх спроб.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
curl "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received",
"message.sent"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T09:12:05.301Z",
"stats": {
"periodDays": 30,
"delivered": 1284,
"pending": 1,
"dead": 3
}
}Оновити підписку
/v2/webhooks/{id}вага 1Змінює лише передані поля. Тіло без жодного поля повертає 400.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
urlstringтілонеобов'язковийПублічний
https://URL, до 2000 символів — див. Обмеження.eventsenum[]тілонеобов'язковийНепорожній масив подій:
message.received,message.sent,comment.received. Повтори в масиві прибираються.descriptionstring | nullтілонеобов'язковийОпис до 500 символів або
null.enabledbooleanтілонеобов'язковийfalse— вимкнути підписку (disabledReason: "manual").true— увімкнути з чистого аркуша:consecutiveFailures,failingSince,disabledAtіdisabledReasonобнуляються.
- Новий
urlперевіряється так само, як під час створення. Секрет підпису при зміні URL лишається тим самим. - Увімкнення після автоматичного вимкнення — це саме
enabled: true.
curl -X PATCH "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b" \
-H "Authorization: Bearer $PAGER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"events":["message.received"]}'{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T12:05:17.640Z"
}Видалити підписку
/v2/webhooks/{id}вага 1Видаляє підписку разом із журналом доставок і відповідає 204. Доставки, що стояли в черзі, не надсилаються.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
curl -X DELETE "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b" \
-H "Authorization: Bearer $PAGER_API_KEY"Перевипустити секрет
/v2/webhooks/{id}/rotate-secretвага 1Створює новий секрет підпису й повертає підписку з ним у полі secret.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
- Старий секрет перестає діяти одразу, перехідного періоду немає. Доставки, що вже стоять у черзі, будуть підписані новим секретом.
curl -X POST "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b/rotate-secret" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b",
"url": "https://crm.example.com/pager/webhook",
"events": [
"message.received",
"message.sent"
],
"description": "Синхронізація з CRM",
"enabled": true,
"consecutiveFailures": 0,
"failingSince": null,
"disabledAt": null,
"disabledReason": null,
"createdAt": "2026-09-24T09:12:05.301Z",
"updatedAt": "2026-09-24T12:10:48.093Z",
"secret": "whsec_Hn4tE8rW1qZ6xC3vB9mK2pL7sD5fG0jA4yU8iO1eRtN"
}Надіслати тестову подію
/v2/webhooks/{id}/testвага 1Синхронно надсилає на URL підписки подію webhook.test і повертає запис доставки з результатом: статус delivered чи dead, код і тіло відповіді вашого сервера, тривалість.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
- Тестова подія не повторюється при невдачі й не впливає на серію невдач підписки. У журнал вона потрапляє.
- Працює й для вимкненої підписки: зручно перевірити виправлений ендпоінт, перш ніж увімкнути її.
- У
data.messageтестової події — рядок, а не об'єкт повідомлення.
curl -X POST "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b/test" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "dlv_0f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
"eventId": "evt_a0b1c2d3e4f5460718293a4b5c6d7e8f",
"eventType": "webhook.test",
"status": "delivered",
"attempt": 1,
"nextAttemptAt": null,
"responseStatus": 200,
"responseBody": "ok",
"durationMs": 184,
"createdAt": "2026-09-24T09:13:40.210Z",
"deliveredAt": "2026-09-24T09:13:40.402Z"
}Журнал доставок
/v2/webhooks/{id}/deliveriesвага 2Доставки підписки сторінками, від нових до старих. Один запис — одна подія: attempt показує, скільки спроб уже зроблено, а responseStatus, responseBody і durationMs — результат останньої.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
statusenumqueryнеобов'язковийpending,failed,deliveredабоdead.eventTypestringqueryнеобов'язковийЛише доставки цього типу події, наприклад
webhook.test.limitintegerqueryнеобов'язковийРозмір сторінки, від
1до100. За замовчуванням50.cursorstringqueryнеобов'язковийnextCursorіз попередньої сторінки.
status:pending— чекає на відправку,failed— остання спроба невдала, наступна оnextAttemptAt,delivered— доставлено оdeliveredAt,dead— усі спроби вичерпано.responseStatusдорівнюєnull, якщо відповіді не було (таймаут, помилка з'єднання); причина тоді вresponseBody.- Тіло самої події журнал не повертає. Записи зберігаються 30 діб.
curl "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b/deliveries?limit=2" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"data": [
{
"id": "dlv_4b7e1f0a-9c2d-4e8b-a6f3-5d1c0b9e8a72",
"eventId": "evt_6c1f0e9d8b7a45c3a2e1f0d9c8b7a6e5",
"eventType": "message.received",
"status": "delivered",
"attempt": 1,
"nextAttemptAt": null,
"responseStatus": 200,
"responseBody": "ok",
"durationMs": 184,
"createdAt": "2026-09-24T08:31:40.582Z",
"deliveredAt": "2026-09-24T08:31:40.771Z"
},
{
"id": "dlv_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"eventId": "evt_1d2c3b4a5f6e47d8a9b0c1d2e3f4a5b6",
"eventType": "message.received",
"status": "failed",
"attempt": 3,
"nextAttemptAt": "2026-09-24T08:36:12.004Z",
"responseStatus": 503,
"responseBody": "Service Unavailable",
"durationMs": 91,
"createdAt": "2026-09-24T08:29:03.117Z",
"deliveredAt": null
}
],
"hasMore": true,
"nextCursor": "WyIyMDI2LTA5LTI0VDA4OjMxOjQwLjU4MloiLCI0YjdlMWYwYS05YzJkLTRlOGItYTZmMy01ZDFjMGI5ZThhNzIiXQ"
}Повторити доставку
/v2/webhooks/{id}/deliveries/{deliveryId}/retryвага 1Ставить доставку в чергу на негайну відправку й відповідає 202 із записом у статусі pending. Результат з'явиться в журналі за кілька секунд.
Параметри
idstringшляхобов'язковийІдентифікатор підписки.
deliveryIdstringшляхобов'язковийidдоставки з журналу,dlv_….
- Працює для будь-якого статусу, зокрема
dead. Дляdeadце одна додаткова спроба: якщо вона невдала, доставка знову стаєdead. - Вимкнену підписку спершу увімкніть: повтор для неї ніколи б не надіслався, тому API повертає
409 webhook_disabled. - Подія йде з тим самим
id, тож якщо ваш сервер її вже обробив, він відкине її як дублікат.
curl -X POST "https://api.pager.co.ua/v2/webhooks/8f3a2c1e-7b6d-4e5f-9a0b-1c2d3e4f5a6b/deliveries/dlv_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/retry" \
-H "Authorization: Bearer $PAGER_API_KEY"{
"id": "dlv_9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"eventId": "evt_1d2c3b4a5f6e47d8a9b0c1d2e3f4a5b6",
"eventType": "message.received",
"status": "pending",
"attempt": 3,
"nextAttemptAt": "2026-09-24T08:33:20.518Z",
"responseStatus": 503,
"responseBody": "Service Unavailable",
"durationMs": 91,
"createdAt": "2026-09-24T08:29:03.117Z",
"deliveredAt": null
}
Ресурси
Коментарі
Коментарі клієнтів під постами Instagram і відповіді на них. Кожен коментар належить розмові з його автором, тож коментарі читаються й пишуться в межах розмови. Дерево дворівневе: гілка — коментар клієнта під постом,
replies— відповіді в ній від старих до нових. Гілки йдуть від нових до старих.422 channel_unsupported.Об'єкт гілки
idstringІдентифікатор коментаря в Pager.
conversationIdstringРозмова з автором коментаря.
parentIdstring | nullКорінь гілки для відповіді або
nullдля самого кореня.directionenumincoming— коментар клієнта,outgoing— відповідь від імені сторінки.textstringТекст коментаря.
usernamestringХто написав: username клієнта або назва каналу для відповідей сторінки.
authorIdstring | nullМенеджер, який відповів.
nullу коментарів клієнтів і у відповідей, надісланих через API.mediaobject | nullПост, під яким коментар:
idіurl.null, якщо невідомо.hasPrivateReplybooleanЧи вже надіслано автору приватну відповідь у директ. Meta дозволяє це лише раз на коментар.
createdAtISO 8601Коли коментар написано.
updatedAtISO 8601Коли коментар востаннє змінено.
repliesobject[]Лише в гілці: відповіді на коментар — ті самі поля, від старих до нових.
Коментарі розмови
/v2/conversations/{id}/commentsвага 2Повертає всі гілки коментарів розмови з відповідями, без пагінації.
Параметри
idstringшляхобов'язковийІдентифікатор розмови.
Відповісти на коментар
/v2/conversations/{id}/commentsвага 1outbound 1Відповідає на коментар публічно під постом або приватно в директ його автору. Відповідає
201з полемvisibility: дляpublic— нова відповідь уcomment, дляprivate— надіслане повідомлення вmessageі оновлений коментар уcomment(hasPrivateReply: true).Параметри
idstringшляхобов'язковийІдентифікатор розмови.
Idempotency-Keystringзаголовокнеобов'язковийКлюч, з яким повтор запиту не надішле відповідь удруге — див. Ідемпотентність.
replyToCommentIdstringтілообов'язковийidкоментаря цієї розмови, на який ви відповідаєте.visibilityenumтілообов'язковийpublic— публічна відповідь під постом від імені сторінки,private— приватне повідомлення в директ автору коментаря.textstringтілообов'язковийТекст відповіді, від 1 до 2000 символів.
replyToCommentId— відповідь, Pager відповість на її корінь.400 not_a_client_comment) і лише один раз: повторна повертає409 private_reply_exists. Вона з'являється в розмові як звичайне вихідне повідомлення й приходить у вебхук `message.sent`.402 message_limit_reached.422 channel_rejectedз причиною. Невдала приватна відповідь зберігається як недоставлене повідомлення, йогоidє в тексті помилки.Idempotency-Key. Окрім ваги1у відріgeneral, займає1у відріoutbound.Видалити коментар
/v2/comments/{id}вага 1outbound 1Видаляє коментар в Instagram і в Pager разом з усіма відповідями на нього й відповідає
204.Параметри
idstringшляхобов'язковийІдентифікатор розмови.
422 channel_rejected, і в Pager нічого не видаляється.1у відріoutbound, як і відповідь.