Аутентификация¶
В каждом запросе к /api/v1 передавайте свой API-ключ мерчанта в заголовке x-api-key. Ни логина,
ни обмена токенами, ни сессии, которую надо поддерживать, здесь нет. Двум эндпоинтам вне этого
префикса — /docs и /health — ключ не нужен.
curl https://api.pay.nullswap.com/api/v1/invoices?limit=20 \
-H "x-api-key: sk_live_2f8b1c0d4e5a69738f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e"
Ключ состоит из префикса sk_live_ и 64 шестнадцатеричных символов. Это не bearer-токен: заголовок
Authorization: Bearer ... просто игнорируется, и API ответит 401, как если бы ключ не передавали
вовсе.
Один ключ — один мерчант¶
Ключ однозначно определяет мерчанта. Отсюда следует правило, которое стоит запомнить прежде, чем читать остальные страницы:
Ни один маршрут в этом API не принимает id мерчанта
Ни в пути, ни в query-параметрах, ни в теле. Любая выборка заранее ограничена вашим мерчантом, и
всё, что вы создаёте, создаётся от его имени. Если вы ищете, куда подставить merchantId, —
такого поля нет.
В ответах merchantId всё же попадается — у инвойса, подписки на вебхук, статического кошелька, —
но лишь справочно: там всегда будет ваш собственный идентификатор.
Посмотреть, какому мерчанту принадлежит ключ:
{
"id": "9f1d2c3b-4a5e-4f60-8b71-2c3d4e5f6a7b",
"name": "Acme Store",
"status": "ACTIVE",
"createdAt": "2026-01-01T12:00:00.000Z",
"updatedAt": "2026-01-01T12:00:00.000Z"
}
Чего ключ не может¶
Администрирование мерчанта в это API не входит. Участники, API-ключи, белые списки IP и подписки на вебхуки заводятся и меняются вручную в кабинете. Подписки на вебхуки API читать умеет — вместе с секретом, которым вы проверяете подписи, — но создать, изменить или удалить их через API нельзя.
Если точнее, данные меняют всего шесть маршрутов, и это весь их список:
| Метод | Путь |
|---|---|
POST |
/api/v1/invoices |
POST |
/api/v1/invoices/{invoiceId}/payments/{paymentId}/resolve |
POST |
/api/v1/invoices/{invoiceId}/payments/{paymentId}/refund |
POST |
/api/v1/static-wallets |
POST |
/api/v1/merchant/withdrawals |
POST |
/api/v1/aml/check-address |
Маршрутов PUT, PATCH и DELETE нет.
Держите ключ на сервере¶
Ключ работает на предъявителя в самом прямом смысле: кто им владеет, тот может создавать инвойсы, выводить ваши деньги и читать всю историю ваших платежей.
Никогда не передавайте ключ в браузер или мобильное приложение
Обращайтесь к API только со своего бэкенда. Если ключ утёк, перевыпустите его в кабинете: старый перестанет работать уже со следующего запроса, потому что ключи нигде не кешируются.
Белый список IP¶
Ключ можно дополнительно привязать к списку адресов, с которых разрешены запросы (Настройки → Белый список IP).
- Пустой белый список фильтрацию не включает — ключ работает откуда угодно.
- Как только в списке появится хотя бы одна запись, запросы со всех остальных адресов начнут
получать
403 CallerIpNotAllowedError, даже если сам ключ полностью корректен.
Сверяемся мы с реальным адресом, с которого установлено TCP-соединение. Заголовок X-Forwarded-For
подделывается и потому не учитывается. Если ваш трафик выходит через NAT или egress-прокси, в белый
список нужно добавлять адрес этого узла, а не адрес сервера приложения.
Ошибки¶
| Статус | message |
Причина |
|---|---|---|
401 |
InvalidApiKeyError |
Заголовка нет, он повреждён, ключ неизвестен или отозван. Различить эти четыре случая по ответу нельзя — так задумано. |
403 |
CallerIpNotAllowedError |
Ключ верный, но запрос пришёл с адреса, которого нет в его белом списке. |
403 |
MerchantIsBlockedError |
Мерчант заблокирован. |
403 |
PermissionDeniedError |
Ресурс, который вы запросили, принадлежит другому мерчанту. |
Заблокированный мерчант не может и читать
MerchantIsBlockedError возникает на этапе аутентификации, ещё до того, как начнёт выполняться
сам маршрут, — а значит, затрагивает вообще все эндпоинты, включая чтение. Если у вас 403
трактуется как «запись отклонена», эту трактовку надо расширить.
Стоит различать 403 PermissionDeniedError и 404. Инвойс, который существует, но принадлежит
другому мерчанту, вернёт 403; идентификатор, которого нет вообще нигде, вернёт 404.