POST /apiv2/screening
Замовити AML-перевірку для блокчейн-адреси: єдина структура відповіді для кожного провайдера та кожного стану замовлення, десяткові числа у вигляді рядків та єдиний формат помилок.
URL ендпойнта
POST https://netts.io/apiv2/screeningЗаголовки запиту
| Заголовок | Обов'язковий | Опис |
|---|---|---|
| Content-Type | Так | application/json |
| X-API-KEY | Так | Ваш API-ключ із панелі керування Netts |
| X-Idempotency-Key | Ні | Ваш власний ключ для безпечних повторних спроб. Див. Ідемпотентність |
Тіло запиту
{
"address": "YOUR_ADDRESS_HERE",
"network": "trx",
"provider": "elliptic",
"wait_for_result": true
}Параметри запиту
| Параметр | Тип | Обов'язковий | Опис |
|---|---|---|---|
| address | string | Так | Адреса для перевірки, 10–128 символів |
| network | string | Так | Тікер мережі. Тікери, які підтримує кожен провайдер, повертаються через GET /apiv2/screening/providers |
| provider | string | Так | elliptic або bitok. Значення за замовчуванням немає |
| wait_for_result | boolean | Ні | true очікує на результат до 15 секунд. За замовчуванням false |
| language | string | Ні | Мова звіту. Тільки en |
Невідомі поля відхиляються. Тіло запиту, що містить поле, якого немає у таблиці вище, повертає 400 із кодом 4001.
Поле provider є обов'язковим і не має значення за замовчуванням. Ви завжди самі обираєте провайдера, за якого сплачуєте.
Поле provider у схемі є довільним рядком, а не переліком (enum). Наразі приймаються два значення; додавання третього провайдера не повинно стати критичною зміною (breaking change) для тих, хто валідує відповіді за схемою. Поточний список, мережі, які покриває кожен провайдер, і шкала оцінювання доступні через GET /apiv2/screening/providers.
Приклади
cURL — очікування результату
curl -X POST https://netts.io/apiv2/screening \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-d '{
"address": "YOUR_ADDRESS_HERE",
"network": "trx",
"provider": "elliptic",
"wait_for_result": true
}'cURL — прийняття та опитування
curl -X POST https://netts.io/apiv2/screening \
-H "Content-Type: application/json" \
-H "X-API-KEY: your_api_key" \
-d '{
"address": "YOUR_ADDRESS_HERE",
"network": "trx",
"provider": "bitok"
}'Відповіддю є 202 Accepted із заголовком Location, що вказує на замовлення.
Python
import requests
from decimal import Decimal
url = "https://netts.io/apiv2/screening"
headers = {
"Content-Type": "application/json",
"X-API-KEY": "your_api_key",
}
payload = {
"address": "YOUR_ADDRESS_HERE",
"network": "trx",
"provider": "elliptic",
"wait_for_result": True,
}
response = requests.post(url, headers=headers, json=payload)
if response.status_code in (200, 202):
body = response.json()
print("Order:", body["order"]["client_order_id"])
print("Status:", body["order"]["status"])
if body["risk"]["score"] is not None:
# Parse provider numbers as Decimal, never as float
print("Score:", Decimal(body["risk"]["score"]), "of", body["risk"]["scale"]["max"])
print("Level:", body["risk"]["level"], "-", body["risk"]["level_source"])
print("Charged:", body["billing"]["charged_amount"], body["billing"]["charged_currency"])
else:
problem = response.json()
print(problem["code"], problem["title"], "-", problem["detail"])Коди відповідей
| Ситуація | Код | Заголовки |
|---|---|---|
| Замовлення створено, перевірка виконується у фоновому режимі | 202 Accepted | Location: /apiv2/screening/{client_order_id} |
Результат міститься у відповіді (wait_for_result) | 200 OK | — |
| Результат повторно використано з нещодавньої перевірки, кошти не списано | 200 OK | — |
| Адреса не має активності в блокчейні, кошти не списано | 200 OK | — |
| Помилка | див. Помилки | Content-Type: application/problem+json |
Відповіді, що містять результат перевірки, надсилаються з Cache-Control: private, no-store.
Відповідь
{
"schema_version": 2,
"order": {
"client_order_id": "A90D21F68C9AEA2",
"status": "completed",
"api_version": "v2",
"cache_hit": false,
"created_at": "2026-09-13T08:14:29.614988Z",
"started_at": "2026-09-13T08:14:30.288251Z",
"completed_at": "2026-09-13T08:14:34.993174Z"
},
"request": {
"address": "YOUR_ADDRESS_HERE",
"network": "trx",
"provider": "elliptic"
},
"billing": {
"charged": true,
"price_usdt": "0.98",
"base_amount": "2.882421",
"markup_amount": "0",
"charged_amount": "2.882421",
"charged_currency": "TRX",
"exchange_rate": "0.33999200",
"payment_status": "pending"
},
"precheck": {
"activity_checked": true,
"activity_status": "active",
"source": "tron-address-checker"
},
"check": {
"provider": "elliptic",
"provider_check_id": "b4903a5d-9f22-4075-b51b-beb40b419b97",
"checked_at": "2026-09-13T08:14:32.144000Z",
"status": "completed",
"provider_status": "complete"
},
"risk": {
"score": "0.9634087310611608",
"scale": { "min": 0, "max": 10 },
"level": "low",
"level_source": "computed",
"provider_level": null,
"policy": "netts-risk-v1",
"by_direction": {
"source": "0.12332156899576921",
"destination": "0.9634087310611608"
}
},
"sanctions": {
"self": false,
"self_entities": null,
"exposure": {
"entity": "HTX (formerly Huobi) - Post-Sanctions - UK Sanctions List - 26 May 2026",
"category": "Exchange",
"share_fraction": "0.004409451392423414",
"proximity": "indirect",
"hops": 3,
"direction": "source",
"rule_name": "Sanctioned, TF & CSAM"
},
"items": []
},
"exposure": [
{
"category": "Exchange",
"share_fraction": "0.1888065152442461",
"direction": "source",
"hops": 2,
"is_screened_address": false,
"entities": [
{ "name": "Binance", "category": "Exchange", "is_vasp": true,
"is_primary": true, "is_after_sanction_date": null }
]
}
],
"rules": [
{ "name": "Sanctioned, TF & CSAM", "type": "exposure", "level": null,
"score": "0.061426483114820525", "share_fraction": null, "category": null,
"proximity": null, "direction": "source", "detected_at": null }
],
"entities": [
{ "name": "Unknown", "category": "Unknown", "is_vasp": null,
"is_primary": true, "is_after_sanction_date": false }
],
"primary_entity": {
"name": "Unknown", "category": "Unknown", "is_vasp": null,
"is_primary": true, "is_after_sanction_date": false
},
"sanctioned_entities": [],
"wallet": {
"inflow_usd": "354663.6116669158",
"outflow_usd": "80248.63081808022"
},
"provider_data": { }
}Набір полів ніколи не змінюється
Кожен блок, наведений вище, присутній у кожній відповіді, незалежно від провайдера та стану замовлення. Дані, які провайдер не надає, позначаються як null; список без елементів повертається як [], а не null; блок, для якого ще немає даних, заповнюється значеннями null, а не пропускається. Єдиний парсер обробляє перевірку, яку щойно прийнято, і ту саму перевірку після її завершення.
Два висновки для вашого коду:
- ігноруйте невідомі вам поля. Нові поля додаються до цих блоків без випуску нової версії. Відхилення невідомого поля є помилкою з вашого боку, а не з нашого;
provider_dataне є частиною контракту. Його структура залежить від провайдера і змінюється разом зі зміною провайдера. Усе, що гарантується контрактом, міститься у вищезазначених блоках.
order
| Поле | Тип | Опис |
|---|---|---|
| client_order_id | string | Ідентифікатор замовлення, що використовується для зчитування результату згодом |
| status | string | pending, processing, completed, skipped, failed |
| api_version | string | Контракт, який створив замовлення |
| cache_hit | boolean | true, якщо було повторно використано нещодавній результат і кошти не списувалися |
| created_at | string | RFC 3339, UTC, мікросекунди |
| started_at | string | null | Час початку виклику провайдера. null для skipped |
| completed_at | string | null | Час отримання результату |
| error | string | Тільки для failed: причина невдачі |
| reason | string | Тільки для skipped: address_inactive |
Усі часові мітки наведені в UTC, RFC 3339, із суфіксом Z та точністю до мікросекунд.
billing
| Поле | Тип | Опис |
|---|---|---|
| charged | boolean | Чи було списано кошти |
| price_usdt | string | Прайсова ціна провайдера в USDT |
| base_amount | string | Вартість замовлення у валюті списання, без націнки субкористувача |
| markup_amount | string | Націнка субкористувача. "0" для прямого облікового запису |
| charged_amount | string | Сума, фактично списана з балансу |
| charged_currency | string | TRX |
| exchange_rate | string | null | Курс, використаний для конвертації |
| payment_status | string | paid, pending, failed, not_charged, postpaid |
payment_status має значення pending протягом короткого часу після успішної перевірки: списання спочатку холдується і завершується протягом години. failed означає, що кошти було повернено. not_charged означає, що списання взагалі не створювалося — повторно використаний результат або пропущена адреса. postpaid — див. Облікові записи з післяплатою.
precheck
Перед платною перевіркою адреса перевіряється на наявність активності в блокчейні. Адреса без активності не надсилається провайдеру і кошти за неї не списуються.
| Поле | Тип | Опис |
|---|---|---|
| activity_checked | boolean | Чи виконувалася перевірка. false для мереж, де вона відсутня |
| activity_status | string | active, inactive, unknown |
| source | string | null | Назва механізму |
Значення unknown не зупиняє платну перевірку: якщо сервіс перевірки активності недоступний, адреса вважається активною.
check
| Поле | Тип | Опис |
|---|---|---|
| provider | string | Провайдер, який виконав перевірку |
| provider_check_id | string | null | Власний ідентифікатор провайдера — вказуйте його при оскарженні результату перед ним |
| checked_at | string | null | Час формування результату провайдером |
| status | string | Див. таблицю нижче |
| provider_status | string | null | Власне формулювання провайдера без змін |
order.status | check.status | Значення |
|---|---|---|
pending | pending | Замовлення прийнято, виконання ще не розпочато |
processing | running | Провайдер обробляє запит |
completed | completed | Результат отримано |
failed | failed | Відхилено до або під час виклику провайдера |
skipped | not_performed | Адреса не має активності; виклик провайдера не здійснювався, кошти не списувалися |
risk
| Поле | Тип | Опис |
|---|---|---|
| score | string | null | Власна оцінка провайдера у вигляді десяткового рядка |
| scale | object | min та max шкали цього провайдера |
| level | string | none, low, medium, high, severe |
| level_source | string | computed — рівень розраховано на основі оцінки; provider — рівень вказано провайдером |
| provider_level | string | null | Власне позначення провайдера, якщо воно надається |
| policy | string | Назва політики порогових значень, netts-risk-v1 |
| by_direction | object | Оцінка, розділена на source та destination, якщо провайдер надає такий поділ |
Оцінка ніколи не масштабується повторно. Elliptic використовує діапазон 0–10, а BitOK — 0–1, і 7 за однією шкалою за жодним змістом не дорівнює 0.7 за іншою. Шкала передається у відповіді для того, щоб інтеграція, написана під одного провайдера, не інтерпретувала хибно дані іншого після простої зміни конфігурації.
Рівень ризику уніфікований для всього API. Якщо провайдер надає власний рівень, ми передаємо його без змін і зазначаємо це в level_source; якщо ж ні, ми виводимо рівень з оцінки за пороговими значеннями netts-risk-v1 і вказуємо відповідне джерело. Одне й те саме слово відображається у відповіді API, на панелі керування та в PDF-звіті для тієї самої перевірки.
exposure[], rules[], entities[]
exposure[] розподіляє кошти за категоріями контрагентів. rules[] містить перелік правил провайдера, які спрацювали. entities[] містить організації, до яких належить сама адреса; primary_entity обирає одну з них за фіксованим правилом — організація, яку провайдер позначив як основну, інакше перша зі списку, інакше null. sanctioned_entities[] містить ті організації з entities[], які позначені як активні після дати накладення санкцій.
Частки виражаються дробами, а не відсотками
Кожна частка у відповіді представлена окремим полем, share_fraction, десятковим рядком від "0" до "1".
Elliptic reports 31.574732212596924 % -> "share_fraction": "0.31574732212596924"
BitOK reports 0.8488 -> "share_fraction": "0.8488"Одиниці вимірювання у провайдерів відрізняються: одна й та сама третина зв'язку відображається як 31.57 у одного та як 0.3157 у іншого. Єдине поле, що містило б обидва формати, було б неможливо інтерпретувати без знання провайдера. Оригінальне число провайдера в його власних одиницях зберігається у provider_data.
Числа представлені рядками
Кожне число, яке надходить від провайдера — оцінки, частки, обсяги в USD, а також кожна сума в billing — є десятковим рядком.
"score": "0.9634087310611608"Парсинг цього значення як числа JSON у JavaScript, Go чи будь-якій іншій мові з двійковою плаваючою комою повертає наближене значення, і виведене число перестає відповідати значенню, виданому провайдером. Парсіть ці поля з використанням десяткового типу: Decimal у Python, BigDecimal у Java, decimal.Decimal або рядок у JavaScript.
Поля, які належать нам, а не провайдеру — scale.min, scale.max, hops — є звичайними числами JSON.
Повторне використання нещодавнього результату
Якщо ви перевіряєте ту саму адресу, мережу та провайдера знову протягом 60 секунд, повертається попередній результат і кошти не списуються.
Кожен запит усе одно створює власне замовлення зі своїм client_order_id; для повторно використаного встановлюється "cache_hit": true, а його блок billing повертає "charged": false зі значенням "payment_status": "not_charged". Ідентифікатор замовлення, з якого було взято результат, не розкривається — воно може належати іншому обліковому запису.
Повторне використання відбувається лише в межах одного облікового запису. Результат перевірки, виконаної кимось іншим, вам ніколи не повертається.
Idempotency
Надішліть заголовок X-Idempotency-Key із власним значенням для безпечного повторення запиту: той самий ключ із тим самим тілом повертає збережену відповідь замість створення повторної перевірки.
| Ситуація | Код | Відповідь |
|---|---|---|
| Перший запит із цим ключем ще обробляється | 409 | 4090 |
| Той самий ключ, але інше тіло запиту | 409 | 4093 |
| Той самий ключ, те саме тіло запиту, перевірку вже завершено | збережений код | збережена відповідь |
Якщо ви не передаєте заголовок, ключ генерується автоматично на основі API-ключа, адреси, провайдера та вашої IP-адреси з вікном у дві секунди. Це захищає від подвійного натискання або повторного запиту з боку шлюзу, але не від повторення через хвилину: такий запит вважається повноцінним новим замовленням і тарифікується.
Відповіді з помилками
Кожна помилка, згенерована застосунком, відповідає стандарту RFC 9457 із Content-Type: application/problem+json:
{
"type": "https://doc.netts.io/api/v2/errors/insufficient-funds",
"title": "Insufficient funds",
"status": 403,
"detail": "Insufficient funds. Required: 2.888742 TRX, Available: 1.203000 TRX",
"instance": "/apiv2/screening",
"code": 1004,
"required_trx": "2.888742",
"available_trx": "1.203000"
}Поля type, title, status, detail та instance є стандартними. Числовий код code є розширенням: використовуйте його для обробки помилок. Додаткові поля залежать від конкретної помилки та мають ігноруватися, якщо вони вам невідомі.
| Код | HTTP | Значення |
|---|---|---|
4000 | 400 | Тіло запиту не є валідним JSON |
4001 | 400 | Поле не пройшло валідацію або надіслано невідоме поле |
4002 | 403 | Провайдер недоступний для вашого акаунта |
4003 | 400 | Некоректний ідентифікатор замовлення |
4004 | 400 | Провайдер не підтримує запитану мережу |
4010 | 401 | Відсутній API-ключ |
4011 | 401 | API-ключ або IP-адресу не прийнято |
4040 | 404 | Замовлення не знайдено |
4041 | 404 | Обліковий запис не знайдено |
4090 | 409 | Запит із цим ключем ідемпотентності все ще обробляється |
4091 | 409 | Дублікат запиту |
4093 | 409 | Цей ключ ідемпотентності вже використовувався з іншим тілом запиту |
1004 | 403 | Недостатньо коштів на балансі |
5000 | 500 | Внутрішня помилка |
5001 | 500 | Списання коштів не вдалося |
5002 | 500 | Замовлення не було створено |
5030 | 503 | Провайдер недоступний |
Помилки, що не використовують цей формат
Деякі збої трапляються на рівні шлюзу до того, як запит досягне застосунку, і вони зберігають формат шлюзу. Сприймайте будь-яку відповідь, чий Content-Type відрізняється від application/problem+json, як одну з наступних:
| Ситуація | HTTP | Тіло відповіді |
|---|---|---|
| Відсутній API-ключ або ключ не прийнято | 401 | {"detail":{"code":-1,"msg":"Invalid or missing API key"}} |
| Перевищено ліміт запитів | 429 | {"message":"API rate limit exceeded"} |
| Невідомий шлях або метод, який не підтримується маршрутом | 404 / 405 | {"detail":"Method Not Allowed"} |
Ліміти запитів
5 запитів на секунду та 150 на хвилину сумарно для всіх шляхів перевірки.
Облікові записи з післяплатою
Облікові записи з післяплатою використовують той самий endpoint, URL, заголовки та тіло запиту, що й усі інші. Різниця полягає у способі оплати перевірки:
- З вашого депозиту нічого не списується. Вартість кожної завершеної перевірки в доларах США (наприклад, $0.98 для Elliptic) додається до заборгованості вашого рахунку у валюті розрахунку, зазначеній у вашому договорі. Ви оплачуєте її за рахунком-фактурою згідно з вашими домовленостями.
- Ваш обліковий запис має кредитний ліміт. Поки сума заборгованості залишається в межах ліміту, перевірки приймаються навіть із нульовим депозитом.
- Оплачуються лише завершені перевірки. Невдала перевірка, адреса без активності (
skipped) та повторно використаний нещодавній результат нічого не коштують.
Післяплата вмикається командою Netts для облікового запису за запитом.
billing перевірки з післяплатою
"billing": {
"charged": false,
"price_usdt": "0.98",
"base_amount": "2.960725",
"markup_amount": "0",
"charged_amount": "2.960725",
"charged_currency": "TRX",
"exchange_rate": "0.33100000",
"payment_status": "postpaid"
}| Поле | Опис |
|---|---|
| charged | false: з депозиту нічого не списується |
| price_usdt | Вартість перевірки в доларах США. Ця сума додається до вашої заборгованості |
| charged_amount | Та сама ціна в TRX для довідки |
| payment_status | postpaid. Для невдалої або пропущеної перевірки — not_charged |
Досягнуто кредитного ліміту (402)
{
"type": "https://doc.netts.io/api/v2/errors/credit-limit-reached",
"title": "Postpaid credit limit reached",
"status": 402,
"detail": "Postpaid credit limit reached.",
"instance": "/apiv2/screening",
"code": 1004,
"payment_mode": "postpaid",
"reason": "limit_reached"
}Перевірка не замовляється і кошти не нараховуються. Нові перевірки знову прийматимуться, щойно буде зареєстровано ваш платіж або збільшено ваш ліміт.
Коди помилок для післяплати
| Код | HTTP | Опис |
|---|---|---|
1004 | 402 | Досягнуто кредитного ліміту для післяплати |
5032 | 503 | Ціна тимчасово недоступна |
5034 | 503 | Білінг тимчасово недоступний — перевірку не прийнято |
5036 | 503 | Перевірка кредитного ліміту тимчасово недоступна — спробуйте пізніше |
Для всіх відповідей вище замовлення не створюється і рахунок не виставляється.
Примітки
- Тарифікація: фіксована ціна за перевірку для кожного провайдера, див. GET /apiv2/screening/providers; списується з TRX-балансу за курсом на момент списання.
- Час обробки: більшість перевірок завершується за кілька секунд; адреса з довгою історією може оброблятися до трьох хвилин. Використовуйте асинхронний режим та читайте результат за допомогою GET /apiv2/screening/{client_order_id}.
- Неактивні адреси повертають статус
skippedі за них не списуються кошти. - Необроблена відповідь провайдера ніколи не повертається.
provider_data— це адаптована проекція; поля, що належать нашому обліковому запису у провайдера, а не перевіреній адресі, нікому не розкриваються.
Звіти
Endpoint повертає лише JSON і нічого іншого. Формати PDF або Markdown не підтримуються.
Усе, з чого формується звіт, уже міститься у відповіді: уніфікований блок та provider_data. Рендеринг звіту на вашому боці дозволяє створити саме той документ, який вам потрібен — з вашим брендингом, вашою мовою, вашим макетом, що особливо важливо, якщо ви перепродаєте перевірки, адже звіт із нашою назвою не підходить для надання вашому кінцевому клієнту.
Якщо вам потрібен звіт як доказ для третьої сторони — банку, регулятора, контрагента — зверніть увагу, що непідписаний PDF не є доказом незалежно від того, хто його створив: його можна відредагувати в текстовому редакторі за хвилину. Документ, що підлягає перевірці, потребує цифрового підпису або публічної сторінки верифікації, а це вже інша функціональність. Якщо це ваш випадок, повідомте нам про вимоги вашого контрагента.
Зручні для читання людиною PDF-звіти за цими самими перевірками доступні на панелі керування Netts сімнадцятьма мовами.
Дивіться також
- GET /apiv2/screening/{client_order_id} — отримати інформацію про перевірку
- GET /apiv2/screening/history — ваші перевірки з курсорною пагінацією
- GET /apiv2/screening/providers — провайдери, ціни, мережі, шкали
- GET /apiv2/screening/price — ціна конкретного провайдера
- Санкції в результатах AML — що означає блок
sanctionsі що означає прапорець провайдера