> For the complete documentation index, see [llms.txt](https://api-portal.novapost.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://api-portal.novapost.com/methods/ua/overview/webhooks.md).

# Webhooks

Webhook — це спосіб отримувати зміни статусів відправлень без періодичних запитів із вашого боку. Ви один раз вказуєте URL зворотного виклику, і Nova Post самостійно надсилає на нього webhook-сповіщення щоразу, коли статус відправлення змінюється.

Налаштування такого зв’язку називається **підпискою**. Ця стаття описує, як створити підписку, керувати нею та що саме надходить на ваш сервер.

### Як це працює

1. Ви створюєте підписку й вказуєте URL зворотного виклику та тип відправлень, які вас цікавлять.
2. Nova Post відстежує зміни статусів відправлень, що підпадають під цю підписку.
3. Щойно статус змінюється, на ваш URL надходить POST-запит із номером відправлення та історією його статусів.
4. Ваш сервер відповідає кодом 2xx — це підтверджує, що сповіщення отримано.

#### Коли надсилається webhook-сповіщення

{% hint style="info" %}
Webhook-сповіщення надсилається тоді, коли статус відправлення **змінюється на новий**.

Сповіщення про події, які відбулися до створення підписки, надсилатися не будуть. Сповіщення надсилаються лише за час існування активної підписки.
{% endhint %}

В історії відстеження один і той самий код статусу може повторюватися кілька разів поспіль. У такому разі webhook-сповіщення надсилається лише один раз — коли цей статус встановлено вперше. Наступне сповіщення надійде тоді, коли статус зміниться на інший.

Порівняння виконується з **попереднім** статусом, а не з усією історією. Тому якщо статус повернувся до попереднього значення після іншого, це вважається новою зміною і webhook-сповіщення надійде знову.

<table><thead><tr><th width="202">Послідовність статусів</th><th width="267">Кількість webhook-сповіщень</th><th>На які статуси</th></tr></thead><tbody><tr><td>4 → 4 → 4 → 5</td><td>2</td><td>4, 5</td></tr><tr><td>4 → 5 → 5 → 9</td><td>3</td><td>4, 5, 9</td></tr><tr><td>4 → 5 → 4</td><td>3</td><td>4, 5, знову 4</td></tr></tbody></table>

{% hint style="info" %}
Якщо відправлення підпадає одразу під кілька ваших підписок, webhook-сповіщення надсилається **один** раз — система захищає від дублювання. Створювати кілька підписок на ті самі відправлення не потрібно.
{% endhint %}

#### Відповідь вашого сервера

Ваш сервер має відповісти кодом із діапазону 2xx — це означає, що сповіщення прийнято. Будь-яка інша відповідь, як і відсутність відповіді, вважається невдалою доставкою.

Не виконуйте тривалу обробку до того, як відповісте: прийміть сповіщення, збережіть його у власну чергу й одразу поверніть 2xx, а бізнес-обробку виконуйте окремо.

#### Повторні спроби

Якщо ваш сервер недоступний, не встиг відповісти або повернув код помилки, система виконує **до 6 повторних спроб** доставки зі зростаючими інтервалами:

<table data-search="false"><thead><tr><th>Спроба</th><th>Інтервал після попередньої</th></tr></thead><tbody><tr><td>1-ша повторна</td><td>5 секунд</td></tr><tr><td>2-га повторна</td><td>10 секунд</td></tr><tr><td>3-тя повторна</td><td>20 секунд</td></tr><tr><td>4-та повторна</td><td>40 секунд</td></tr><tr><td>5-та повторна</td><td>80 секунд</td></tr><tr><td>6-та повторна</td><td>160 секунд</td></tr></tbody></table>

Якщо в підписці ввімкнено `sendWarnings`, після **третьої невдалої спроби доставки одного повідомлення** на адресу з `warningEmail` надходить лист про проблему.

Після шостої невдалої спроби повторне надсилання цього повідомлення припиняється. Сама підписка при цьому не змінюється й залишається активною: коли статус відправлення зміниться наступного разу, буде сформовано нове webhook-сповіщення, і його доставка почнеться заново.

#### Захист від повторної обробки

Через повторні спроби ваш сервер може отримати одне й те саме сповіщення кілька разів. Щоб це не спричинило подвійної обробки, використовуйте заголовок `x-np-attempt`.

Заголовок має формат `{UUID повідомлення}.{номер спроби}`:

```
x-np-attempt: 8f14e45f-ceea-467e-9a3a-0e1a1b1e2b1c.1
x-np-attempt: 8f14e45f-ceea-467e-9a3a-0e1a1b1e2b1c.2
```

Обидва рядки — це одне й те саме сповіщення, надіслане двічі. UUID до крапки незмінний для всіх спроб доставки однієї події та унікальний для різних подій, тому саме він є ключем перевірки на повтор. Номер після крапки показує, яка це за рахунком спроба.

### Перед початком

#### Що підготувати

<table><thead><tr><th width="59">#</th><th width="241">Що потрібно</th><th>Пояснення</th></tr></thead><tbody><tr><td>1</td><td>Публічний HTTPS-endpoint</td><td>Адреса на вашому сервері, яка приймає POST-запити. Має бути доступною з інтернету й не виконувати переадресацій.</td></tr><tr><td>2</td><td>JWT-токен</td><td>Потрібен для авторизації запитів до API Nova Post.</td></tr><tr><td>3</td><td>Власний секретний токен</td><td>Рядок, який ви формуєте самі. Nova Post додаватиме його до кожного webhook-запиту, щоб ваш сервер міг переконатися, що запит надійшов саме від Nova Post.</td></tr><tr><td>4</td><td>Перелік відправлень або правило їх відбору</td><td>Залежить від типу підписки — див. розділ<br> <a href="/methods/ua/overview/webhooks/subscription-types.md"><strong>Типи підписок</strong></a>.</td></tr><tr><td>5</td><td>Перелік типів подій</td><td>Необов’язково. Якщо фільтр не потрібен, надходитимуть усі підтримувані події. Допустимі значення — див. розділ <a href="/methods/ua/overview/webhooks/event-types-and-tracking-status-codes.md#tipi-podii-dlya-parametra-eventtypes"><strong>Типи подій для параметра eventTypes</strong></a>.</td></tr></tbody></table>

{% hint style="warning" %}
**JWT-токен і власний секретний токен — це різні облікові дані з різним призначенням.** \
JWT-токен потрібен, щоб Nova Post авторизувала ваші запити. Секретний токен потрібен, щоб ви могли перевіряти вхідні webhook-запити. Не використовуйте один замість іншого й не передавайте JWT-токен в URL зворотного виклику.
{% endhint %}

#### Середовища

<table><thead><tr><th width="134">Середовище</th><th width="341">Базовий URL</th><th>Призначення</th></tr></thead><tbody><tr><td><strong>Sandbox</strong></td><td><code>https://api-stage.novapost.com/v.1.0/</code></td><td>Перевірка інтеграції. У Sandbox <strong>працює виключно</strong> <strong>тестова відправка webhook</strong> — реальні зміни статусів відправлень webhook-сповіщень не породжують.</td></tr><tr><td><strong>PROD</strong></td><td><code>https://api.novapost.com/v.1.0/</code></td><td>Робоче середовище.</td></tr></tbody></table>

### Структура webhook-запиту

#### Заголовки

<table><thead><tr><th width="200">Заголовок</th><th>Опис</th></tr></thead><tbody><tr><td><code>Content-Type</code></td><td><strong>Content-Type</strong>, заданий у параметрі <code>contentType</code> підписки. За замовчуванням <code>text/plain</code>.</td></tr><tr><td><code>X-NP-Key</code> <strong>або власна</strong> <strong>назва</strong></td><td>Секретний токен підписки. Назва заголовка береться з параметра <code>secretTokenHeaderName</code>; якщо його не задано, використовується <code>X-NP-Key</code>.</td></tr><tr><td><code>x-np-attempt</code></td><td>Ідентифікатор спроби доставки у форматі <code>{UUID повідомлення}.{номер спроби}</code>. Використовується для захисту від повторної обробки.</td></tr></tbody></table>

#### Тіло запиту

```
{
  "number": "SHPL0000000001",
  "scheduled_delivery_date": "2024-11-20T20:03:00.000000Z",
  "history_tracking": [
    {
      "code": "4",
      "code_name": "On the way",
      "country_code": "UA",
      "settlement": "Kyiv",
      "date": "2024-11-19T09:32:05.000000Z"
    },
    {
      "code": "112",
      "code_name": "Change of delivery date",
      "country_code": "",
      "settlement": "",
      "date": "2024-11-19T09:33:56.000000Z"
    }
  ]
}
```

<table data-search="false"><thead><tr><th width="290">Параметр</th><th>Тип</th><th>Опис</th></tr></thead><tbody><tr><td><code>number</code></td><td>string</td><td>Номер відправлення.</td></tr><tr><td><code>scheduled_delivery_date</code></td><td>string</td><td>Запланована дата й час доставки у форматі ISO 8601. Може бути порожнім.</td></tr><tr><td><code>history_tracking</code></td><td>string[]</td><td>Масив об’єктів статусів відстеження.</td></tr><tr><td><code>history_tracking[].code</code></td><td>string</td><td>Код статусу відстеження. <strong>Будуйте бізнес-логіку</strong> <strong>саме на цьому параметрі</strong> — він сталий. Допустимі значення — див. розділ <a href="/methods/ua/overview/webhooks/event-types-and-tracking-status-codes.md#kodi-statusiv-vidstezhennya"><strong>Коди статусів відстеження</strong></a>.</td></tr><tr><td><code>history_tracking[].code_name</code></td><td>string</td><td>Назва статусу відстеження. Може змінюватися й потрібна лише для зручності читання — не використовуйте її для порівнянь у коді.</td></tr><tr><td><code>history_tracking[].country_code</code></td><td>string</td><td>Код країни, у якій було зафіксовано статус. Може бути порожнім.</td></tr><tr><td><code>history_tracking[].settlement</code></td><td>string</td><td>Назва населеного пункту. Може бути порожнім.</td></tr><tr><td><code>history_tracking[].date</code></td><td>string</td><td>Дата й час події статусу.</td></tr></tbody></table>

Тіло webhook-запиту містить щонайменше один статус відстеження. Кожне наступне webhook-сповіщення містить новий доданий статус і всі раніше доставлені статуси. Актуальний статус матиме найновіше значення поля `date`.

#### Авторизація

Кожен запит до API має містити заголовок Authorization із JWT-токеном:

```
Authorization: {jwt}
```

Термін дії токена — приблизно 1 година, після цього потрібно запросити новий. Порядок отримання токена описано у статті [Авторизація](/methods/ua/overview/authorization.md).

### Список методів

<table data-search="false"><thead><tr><th width="238">Назва</th><th>Опис</th></tr></thead><tbody><tr><td><a href="/methods/ua/overview/webhooks/subscription-list.md"><strong>Список підписок</strong></a></td><td>Отримати список усіх підписок, пов’язаних із клієнтом.</td></tr><tr><td><a href="/methods/ua/overview/webhooks/new-subscription.md"><strong>Нова підписка</strong></a></td><td>Цей метод використовується для створення нової підписки для отримання сповіщень про відстеження через webhook. Підписка може бути різних типів, наприклад для окремого номера або для компанії, і є необхідною для клієнтів, які хочуть отримувати оновлення статусів відправлень у реальному часі.</td></tr><tr><td><a href="/methods/ua/overview/webhooks/subscription-update.md"><strong>Оновлення підписки</strong></a></td><td><p>Цей метод оновлює дані існуючої підписки, зокрема callback URL, статус активності, типи подій тощо.</p><p>Він використовується для зміни налаштувань підписки клієнтами, які хочуть керувати способом отримання сповіщень про відстеження.</p><p><strong>Метод виконує повну заміну налаштувань, а не часткове</strong> <strong>оновлення</strong>. Параметри, які ви не передасте, буде скинуто. Наприклад, якщо змінити лише url, підписка втратить фільтр <code>eventTypes</code> і почне отримувати webhook-сповіщення за всіма подіями. Завжди передавайте повний набір параметрів, навіть якщо змінюєте один із них.</p><p><strong>Тип підписки змінити не можна</strong>. Якщо передати в запиті параметр type з іншим значенням, зміна не застосується. Щоб перейти на інший тип, створіть нову підписку й видаліть стару.</p><p><strong>Зверніть увагу</strong>: події, що відбудуться за час, поки підписка вимкнена, після її повторного ввімкнення не надійдуть.</p></td></tr><tr><td><a href="/methods/ua/overview/webhooks/subscription-deletion.md"><strong>Видалення підписки</strong></a></td><td><p>Цей метод видаляє підписку, зазначену за її унікальним ідентифікатором. Після видалення підписка більше не отримуватиме webhook-сповіщення. Видалення є незворотним, тому цю дію слід виконувати з обережністю.</p><p>Якщо потрібно лише тимчасово зупинити надсилання webhook-сповіщень, не видаляйте підписку, а вимкніть її методом <a href="/methods/ua/overview/webhooks/subscription-update.md"><strong>Оновити існуючу підписку</strong></a> зі значенням <code>isActive: false</code>.<br><strong>Зверніть увагу</strong>: події, що відбудуться за час, поки підписка вимкнена, після її повторного ввімкнення не надійдуть.</p></td></tr><tr><td><a href="/methods/ua/overview/webhooks/adding-numbers-to-a-subscription.md"><strong>Додавання номерів до підписки</strong></a></td><td><p>Цей метод дозволяє додавати номери відправлень до підписки типу <code>numbers</code>.</p><p>Додаються лише ті номери, які вже існують у системі Nova Post. Номер, якого ще немає в системі, до підписки не потрапить — його потрібно буде додати повторно після того, як відправлення буде створено.</p><p>Код <code>200</code> означає, що додано <code>щонайменше один</code> номер, а не обов’язково всі передані. Завжди перевіряйте вміст <code>missedNumbers</code>.</p></td></tr><tr><td><a href="/methods/ua/overview/webhooks/deleting-numbers-from-a-subscription.md"><strong>Видалення номерів із підписки</strong></a></td><td><p>Цей метод дозволяє видаляти номери відправлень із підписки типу <code>numbers</code>.</p><p><strong>Метод повертає код</strong> <code>200</code> <strong>у будь-якому разі, зокрема й тоді</strong>, <strong>коли не видалено жодного номера</strong>. Результат операції визначається параметром <code>status</code> у тілі відповіді, а не HTTP-кодом.</p></td></tr><tr><td><a href="/methods/ua/overview/webhooks/test-webhook.md"><strong>Тестовий webhook</strong></a></td><td>Цей метод дозволяє перевірити роботу webhook. Для успішної відповіді потрібна щонайменше одна активна підписка.</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://api-portal.novapost.com/methods/ua/overview/webhooks.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
