Skip to content
Translated page. The English version is the source of truth.

POST /apiv2/screening ​

Замовити AML-перевірку для блокчейн-адреси: єдина структура відповіді для кожного провайдера та кожного стану замовлення, десяткові числа у вигляді рядків та єдиний формат помилок.

URL ендпойнта ​

POST https://netts.io/apiv2/screening

Заголовки запиту ​

ЗаголовокОбов'язковийОпис
Content-TypeТакapplication/json
X-API-KEYТакВаш API-ключ із панелі керування Netts
X-Idempotency-KeyНіВаш власний ключ для безпечних повторних спроб. Див. Ідемпотентність

Тіло запиту ​

json
{
    "address": "YOUR_ADDRESS_HERE",
    "network": "trx",
    "provider": "elliptic",
    "wait_for_result": true
}

Параметри запиту ​

ПараметрТипОбов'язковийОпис
addressstringТакАдреса для перевірки, 10–128 символів
networkstringТакТікер мережі. Тікери, які підтримує кожен провайдер, повертаються через GET /apiv2/screening/providers
providerstringТакelliptic або bitok. Значення за замовчуванням немає
wait_for_resultbooleanНіtrue очікує на результат до 15 секунд. За замовчуванням false
languagestringНіМова звіту. Тільки en

Невідомі поля відхиляються. Тіло запиту, що містить поле, якого немає у таблиці вище, повертає 400 із кодом 4001.

Поле provider є обов'язковим і не має значення за замовчуванням. Ви завжди самі обираєте провайдера, за якого сплачуєте.

Поле provider у схемі є довільним рядком, а не переліком (enum). Наразі приймаються два значення; додавання третього провайдера не повинно стати критичною зміною (breaking change) для тих, хто валідує відповіді за схемою. Поточний список, мережі, які покриває кожен провайдер, і шкала оцінювання доступні через GET /apiv2/screening/providers.

Приклади ​

cURL — очікування результату ​

bash
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 — прийняття та опитування ​

bash
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 ​

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 AcceptedLocation: /apiv2/screening/{client_order_id}
Результат міститься у відповіді (wait_for_result)200 OK—
Результат повторно використано з нещодавньої перевірки, кошти не списано200 OK—
Адреса не має активності в блокчейні, кошти не списано200 OK—
Помилкадив. ПомилкиContent-Type: application/problem+json

Відповіді, що містять результат перевірки, надсилаються з Cache-Control: private, no-store.

Відповідь ​

json
{
  "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_idstringІдентифікатор замовлення, що використовується для зчитування результату згодом
statusstringpending, processing, completed, skipped, failed
api_versionstringКонтракт, який створив замовлення
cache_hitbooleantrue, якщо було повторно використано нещодавній результат і кошти не списувалися
created_atstringRFC 3339, UTC, мікросекунди
started_atstring | nullЧас початку виклику провайдера. null для skipped
completed_atstring | nullЧас отримання результату
errorstringТільки для failed: причина невдачі
reasonstringТільки для skipped: address_inactive

Усі часові мітки наведені в UTC, RFC 3339, із суфіксом Z та точністю до мікросекунд.

billing ​

ПолеТипОпис
chargedbooleanЧи було списано кошти
price_usdtstringПрайсова ціна провайдера в USDT
base_amountstringВартість замовлення у валюті списання, без націнки субкористувача
markup_amountstringНацінка субкористувача. "0" для прямого облікового запису
charged_amountstringСума, фактично списана з балансу
charged_currencystringTRX
exchange_ratestring | nullКурс, використаний для конвертації
payment_statusstringpaid, pending, failed, not_charged, postpaid

payment_status має значення pending протягом короткого часу після успішної перевірки: списання спочатку холдується і завершується протягом години. failed означає, що кошти було повернено. not_charged означає, що списання взагалі не створювалося — повторно використаний результат або пропущена адреса. postpaid — див. Облікові записи з післяплатою.

precheck ​

Перед платною перевіркою адреса перевіряється на наявність активності в блокчейні. Адреса без активності не надсилається провайдеру і кошти за неї не списуються.

ПолеТипОпис
activity_checkedbooleanЧи виконувалася перевірка. false для мереж, де вона відсутня
activity_statusstringactive, inactive, unknown
sourcestring | nullНазва механізму

Значення unknown не зупиняє платну перевірку: якщо сервіс перевірки активності недоступний, адреса вважається активною.

check ​

ПолеТипОпис
providerstringПровайдер, який виконав перевірку
provider_check_idstring | nullВласний ідентифікатор провайдера — вказуйте його при оскарженні результату перед ним
checked_atstring | nullЧас формування результату провайдером
statusstringДив. таблицю нижче
provider_statusstring | nullВласне формулювання провайдера без змін
order.statuscheck.statusЗначення
pendingpendingЗамовлення прийнято, виконання ще не розпочато
processingrunningПровайдер обробляє запит
completedcompletedРезультат отримано
failedfailedВідхилено до або під час виклику провайдера
skippednot_performedАдреса не має активності; виклик провайдера не здійснювався, кошти не списувалися

risk ​

ПолеТипОпис
scorestring | nullВласна оцінка провайдера у вигляді десяткового рядка
scaleobjectmin та max шкали цього провайдера
levelstringnone, low, medium, high, severe
level_sourcestringcomputed — рівень розраховано на основі оцінки; provider — рівень вказано провайдером
provider_levelstring | nullВласне позначення провайдера, якщо воно надається
policystringНазва політики порогових значень, netts-risk-v1
by_directionobjectОцінка, розділена на 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".

text
Elliptic reports 31.574732212596924 %  ->  "share_fraction": "0.31574732212596924"
BitOK reports    0.8488                ->  "share_fraction": "0.8488"

Одиниці вимірювання у провайдерів відрізняються: одна й та сама третина зв'язку відображається як 31.57 у одного та як 0.3157 у іншого. Єдине поле, що містило б обидва формати, було б неможливо інтерпретувати без знання провайдера. Оригінальне число провайдера в його власних одиницях зберігається у provider_data.

Числа представлені рядками ​

Кожне число, яке надходить від провайдера — оцінки, частки, обсяги в USD, а також кожна сума в billing — є десятковим рядком.

json
"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 із власним значенням для безпечного повторення запиту: той самий ключ із тим самим тілом повертає збережену відповідь замість створення повторної перевірки.

СитуаціяКодВідповідь
Перший запит із цим ключем ще обробляється4094090
Той самий ключ, але інше тіло запиту4094093
Той самий ключ, те саме тіло запиту, перевірку вже завершенозбережений кодзбережена відповідь

Якщо ви не передаєте заголовок, ключ генерується автоматично на основі API-ключа, адреси, провайдера та вашої IP-адреси з вікном у дві секунди. Це захищає від подвійного натискання або повторного запиту з боку шлюзу, але не від повторення через хвилину: такий запит вважається повноцінним новим замовленням і тарифікується.

Відповіді з помилками ​

Кожна помилка, згенерована застосунком, відповідає стандарту RFC 9457 із Content-Type: application/problem+json:

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Значення
4000400Тіло запиту не є валідним JSON
4001400Поле не пройшло валідацію або надіслано невідоме поле
4002403Провайдер недоступний для вашого акаунта
4003400Некоректний ідентифікатор замовлення
4004400Провайдер не підтримує запитану мережу
4010401Відсутній API-ключ
4011401API-ключ або IP-адресу не прийнято
4040404Замовлення не знайдено
4041404Обліковий запис не знайдено
4090409Запит із цим ключем ідемпотентності все ще обробляється
4091409Дублікат запиту
4093409Цей ключ ідемпотентності вже використовувався з іншим тілом запиту
1004403Недостатньо коштів на балансі
5000500Внутрішня помилка
5001500Списання коштів не вдалося
5002500Замовлення не було створено
5030503Провайдер недоступний

Помилки, що не використовують цей формат ​

Деякі збої трапляються на рівні шлюзу до того, як запит досягне застосунку, і вони зберігають формат шлюзу. Сприймайте будь-яку відповідь, чий 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 перевірки з післяплатою ​

json
"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"
}
ПолеОпис
chargedfalse: з депозиту нічого не списується
price_usdtВартість перевірки в доларах США. Ця сума додається до вашої заборгованості
charged_amountТа сама ціна в TRX для довідки
payment_statuspostpaid. Для невдалої або пропущеної перевірки — not_charged

Досягнуто кредитного ліміту (402) ​

json
{
  "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Опис
1004402Досягнуто кредитного ліміту для післяплати
5032503Ціна тимчасово недоступна
5034503Білінг тимчасово недоступний — перевірку не прийнято
5036503Перевірка кредитного ліміту тимчасово недоступна — спробуйте пізніше

Для всіх відповідей вище замовлення не створюється і рахунок не виставляється.

Примітки ​

  • Тарифікація: фіксована ціна за перевірку для кожного провайдера, див. GET /apiv2/screening/providers; списується з TRX-балансу за курсом на момент списання.
  • Час обробки: більшість перевірок завершується за кілька секунд; адреса з довгою історією може оброблятися до трьох хвилин. Використовуйте асинхронний режим та читайте результат за допомогою GET /apiv2/screening/{client_order_id}.
  • Неактивні адреси повертають статус skipped і за них не списуються кошти.
  • Необроблена відповідь провайдера ніколи не повертається. provider_data — це адаптована проекція; поля, що належать нашому обліковому запису у провайдера, а не перевіреній адресі, нікому не розкриваються.

Звіти ​

Endpoint повертає лише JSON і нічого іншого. Формати PDF або Markdown не підтримуються.

Усе, з чого формується звіт, уже міститься у відповіді: уніфікований блок та provider_data. Рендеринг звіту на вашому боці дозволяє створити саме той документ, який вам потрібен — з вашим брендингом, вашою мовою, вашим макетом, що особливо важливо, якщо ви перепродаєте перевірки, адже звіт із нашою назвою не підходить для надання вашому кінцевому клієнту.

Якщо вам потрібен звіт як доказ для третьої сторони — банку, регулятора, контрагента — зверніть увагу, що непідписаний PDF не є доказом незалежно від того, хто його створив: його можна відредагувати в текстовому редакторі за хвилину. Документ, що підлягає перевірці, потребує цифрового підпису або публічної сторінки верифікації, а це вже інша функціональність. Якщо це ваш випадок, повідомте нам про вимоги вашого контрагента.

Зручні для читання людиною PDF-звіти за цими самими перевірками доступні на панелі керування Netts сімнадцятьма мовами.

Дивіться також ​