Skip to content
This translation is behind the English original, updated 2026-09-15. Read the English version for the current text.

POST /apiv2/screening

Tạo một yêu cầu sàng lọc AML cho một địa chỉ blockchain. Đây là hợp đồng phiên bản 2: một cấu trúc phản hồi duy nhất cho mọi nhà cung cấp và mọi trạng thái của đơn hàng, các số thập phân ở dạng chuỗi, và một định dạng lỗi duy nhất.

Nó thay thế cho POST /apiv2/aml, endpoint này vẫn tiếp tục hoạt động và sẽ không bị gỡ bỏ mà không có thông báo trước.

URL điểm cuối

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

Tiêu đề yêu cầu

HeaderBắt buộcMô tả
Content-Typeapplication/json
X-API-KEYKhóa API của bạn từ bảng điều khiển Netts
X-Idempotency-KeyKhôngKhóa riêng của bạn để thử lại an toàn. Xem Tính bất biến

Nội dung yêu cầu

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

Tham số

Tham sốLoạiBắt buộcMô tả
addressstringĐịa chỉ cần sàng lọc, 10–128 ký tự
networkstringMã ticker của mạng lưới. Các mã ticker mà mỗi nhà cung cấp hỗ trợ được liệt kê bởi GET /apiv2/screening/providers; bảng đầy đủ về các mạng lưới cùng tên gọi của chúng có tại đây
providerstringelliptic hoặc bitok. Không có giá trị mặc định
wait_for_resultbooleanKhôngtrue sẽ chờ kết quả trong tối đa 15 giây. Mặc định là false
languagestringKhôngNgôn ngữ báo cáo. Chỉ hỗ trợ en

Các trường không xác định sẽ bị từ chối. Phần thân yêu cầu chứa trường không nằm trong bảng trên sẽ trả về 400 với mã 4001. Trong phiên bản 1, các trường không xác định đã bị bỏ qua trong im lặng, và việc viết sai chính tả trường wait đồng nghĩa với việc người gọi chờ đợi một kết quả không bao giờ được trả về một cách đồng bộ.

provider là bắt buộc và không có giá trị mặc định. Trong phiên bản 1, việc bỏ qua nhà cung cấp đồng nghĩa với Elliptic, do đó người gọi không đưa ra lựa chọn đã phải trả phí cho một nhà cung cấp mà họ chưa từng chỉ định.

provider là một chuỗi tự do trong schema, không phải là enum. Hiện tại hai giá trị được chấp nhận; việc bổ sung nhà cung cấp thứ ba không được trở thành một breaking change đối với bất kỳ ai xác thực phản hồi theo schema. Danh sách hiện tại, các mạng lưới mà mỗi nhà cung cấp hỗ trợ và thang điểm đánh giá của từng bên được cung cấp từ GET /apiv2/screening/providers.

Ví dụ yêu cầu

cURL — chờ kết quả

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 — chấp nhận và thăm dò

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"
  }'

Phản hồi là 202 Accepted với header Location trỏ đến đơn hàng.

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"])

Mã phản hồi

Trường hợpHeaders
Đơn hàng đã được tạo, quá trình sàng lọc chạy ngầm202 AcceptedLocation: /apiv2/screening/{client_order_id}
Kết quả nằm trong phản hồi (wait_for_result)200 OK
Kết quả được tái sử dụng từ lần kiểm tra gần đây, không tính phí200 OK
Địa chỉ không có hoạt động trên blockchain, không tính phí200 OK
Lỗixem LỗiContent-Type: application/problem+json

Các phản hồi chứa kết quả sàng lọc được gửi kèm với Cache-Control: private, no-store.

Phản hồi

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": { }
}

Tập hợp các trường không bao giờ thay đổi

Mọi khối được liệt kê ở trên đều có mặt trong mọi phản hồi, bất kể nhà cung cấp là ai và trạng thái của đơn hàng là gì. Những gì nhà cung cấp không cung cấp sẽ là null; một danh sách không có phần tử nào sẽ là [], không phải null; một khối chưa có dữ liệu sẽ được điền các giá trị null thay vì bị lược bỏ. Một bộ phân tích duy nhất có thể xử lý một lượt kiểm tra vừa được chấp nhận cũng như chính lượt kiểm tra đó sau khi hoàn thành.

Hai lưu ý cho mã nguồn của bạn:

  • bỏ qua các trường mà bạn không biết. Các trường mới được thêm vào các khối này mà không cần phiên bản mới. Việc từ chối một trường không xác định là lỗi phía bạn, không phải của chúng tôi;
  • provider_data không thuộc hợp đồng API. Cấu trúc của nó phụ thuộc vào nhà cung cấp và sẽ thay đổi khi nhà cung cấp thay đổi. Mọi thứ mà hợp đồng đảm bảo đều nằm trong các khối bên trên.

order

TrườngLoạiMô tả
client_order_idstringĐịnh danh đơn hàng, dùng để đọc kết quả sau này
statusstringpending, processing, completed, skipped, failed
api_versionstringHợp đồng đã tạo đơn hàng
cache_hitbooleantrue khi kết quả gần đây được tái sử dụng và không bị tính phí
created_atstringRFC 3339, UTC, micro giây
started_atstring | nullThời điểm lệnh gọi nhà cung cấp bắt đầu. null đối với skipped
completed_atstring | nullThời điểm có kết quả
errorstringChỉ dành cho failed: lý do thất bại
reasonstringChỉ dành cho skipped: address_inactive

Tất cả dấu thời gian đều là UTC, RFC 3339, với hậu tố Z và độ chính xác đến micro giây.

billing

TrườngLoạiMô tả
chargedbooleanĐã trừ tiền hay chưa
price_usdtstringGiá niêm yết của nhà cung cấp tính bằng USDT
base_amountstringGiá đơn hàng bằng loại tiền tệ bị tính phí, chưa bao gồm chênh lệch giá cho người dùng phụ
markup_amountstringChênh lệch giá cho người dùng phụ. "0" đối với tài khoản trực tiếp
charged_amountstringSố tiền thực tế bị trừ từ số dư
charged_currencystringTRX
exchange_ratestring | nullTỷ giá được sử dụng để quy đổi
payment_statusstringpaid, pending, failed, not_charged

payment_status sẽ ở trạng thái pending trong một thời gian ngắn sau khi kiểm tra thành công: khoản phí được tạm giữ trước và sẽ quyết toán trong vòng một giờ. failed có nghĩa là tiền đã được hoàn lại. not_charged có nghĩa là chưa từng có khoản phí nào được tạo — kết quả được tái sử dụng hoặc một địa chỉ bị bỏ qua.

precheck

Trước khi thực hiện sàng lọc có tính phí, địa chỉ sẽ được kiểm tra hoạt động trên blockchain. Một địa chỉ không có hoạt động sẽ không được gửi tới nhà cung cấp và không bị tính phí.

TrườngLoạiMô tả
activity_checkedbooleanViệc kiểm tra đã chạy hay chưa. false trên các mạng lưới không hỗ trợ tính năng này
activity_statusstringactive, inactive, unknown
sourcestring | nullTên của cơ chế kiểm tra

unknown không làm dừng quá trình sàng lọc có tính phí: nếu dịch vụ kiểm tra hoạt động không khả dụng, địa chỉ sẽ được coi là đang hoạt động.

check

TrườngLoạiMô tả
providerstringNhà cung cấp đã thực hiện kiểm tra
provider_check_idstring | nullĐịnh danh riêng của nhà cung cấp — hãy trích dẫn mã này khi khiếu nại kết quả với họ
checked_atstring | nullThời điểm nhà cung cấp đưa ra kết quả
statusstringXem bảng bên dưới
provider_statusstring | nullNguyên văn trạng thái của nhà cung cấp, không chỉnh sửa
order.statuscheck.statusÝ nghĩa
pendingpendingĐơn hàng đã được chấp nhận, chưa bắt đầu
processingrunningNhà cung cấp đang xử lý
completedcompletedĐã nhận được kết quả
failedfailedBị từ chối trước hoặc trong quá trình gọi nhà cung cấp
skippednot_performedĐịa chỉ không có hoạt động; không bao giờ gọi nhà cung cấp và không tính phí

risk

TrườngLoạiMô tả
scorestring | nullĐiểm số của chính nhà cung cấp, dưới dạng chuỗi thập phân
scaleobjectminmax của thang điểm của nhà cung cấp đó
levelstringnone, low, medium, high, severe
level_sourcestringcomputed — chúng tôi suy ra mức độ từ điểm số; provider — do nhà cung cấp công bố
provider_levelstring | nullTừ ngữ riêng của nhà cung cấp, khi họ có trả về
policystringTên của chính sách ngưỡng điểm, netts-risk-v1
by_directionobjectĐiểm số được chia thành sourcedestination, khi nhà cung cấp có phân tách

Điểm số không bao giờ được quy đổi lại thang đo. Elliptic hoạt động theo thang 0–10 và BitOK hoạt động theo thang 0–1, và điểm 7 trên thang này không tương đương với 0.7 trên thang kia theo bất kỳ nghĩa thực tế nào. Thang đo được trả về trong phản hồi để quá trình tích hợp được viết cho một nhà cung cấp không bị đọc sai kết quả của nhà cung cấp khác chỉ sau một thay đổi cấu hình.

Mức độ rủi ro sử dụng một bộ từ vựng thống nhất trên toàn bộ API. Khi nhà cung cấp tự công bố một mức độ rủi ro, chúng tôi sẽ chuyển tiếp nguyên văn và ghi rõ trong level_source; khi họ không cung cấp, chúng tôi suy ra mức độ từ điểm số bằng các ngưỡng của netts-risk-v1 và thông báo điều đó. Cùng một từ sẽ xuất hiện trong phản hồi API, bảng điều khiển và báo cáo PDF cho cùng một lượt kiểm tra.

exposure[], rules[], entities[]

exposure[] phân tích dòng tiền theo danh mục đối tác giao dịch. rules[] liệt kê các quy tắc của nhà cung cấp đã được kích hoạt. entities[] liệt kê các thực thể mà chính địa chỉ đó thuộc về; primary_entity chọn một trong số đó theo quy tắc cố định — thực thể mà nhà cung cấp đánh dấu là chính, nếu không có thì lấy thực thể đầu tiên, nếu không có nữa thì là null. sanctioned_entities[] lưu trữ các thực thể trong entities[] bị gắn cờ là hoạt động sau ngày áp dụng lệnh trừng phạt.

Tỷ lệ chia là phân số, không bao giờ là phần trăm

Mỗi tỷ lệ trong phản hồi là một trường duy nhất, share_fraction, một chuỗi thập phân từ "0" đến "1".

text
Elliptic báo cáo 31.574732212596924 %  ->  "share_fraction": "0.31574732212596924"
BitOK báo cáo    0.8488                ->  "share_fraction": "0.8488"

Các nhà cung cấp sử dụng đơn vị khác nhau: cùng một phần ba mức độ liên quan có thể đến dưới dạng 31.57 từ bên này và 0.3157 từ bên kia. Một trường đơn lẻ chứa cả hai cách tính sẽ không thể đọc được nếu không biết rõ nhà cung cấp. Con số gốc của nhà cung cấp theo đúng đơn vị của họ vẫn được giữ trong provider_data.

Số được biểu diễn dưới dạng chuỗi

Mọi con số đến từ nhà cung cấp — điểm số, tỷ lệ chia, khối lượng USD, và mọi số tiền trong billing — đều là chuỗi thập phân.

json
"score": "0.9634087310611608"

Việc phân tích chuỗi này thành kiểu số trong JSON trên JavaScript, Go hoặc bất kỳ ngôn ngữ nào sử dụng số thực dấu phẩy động nhị phân sẽ trả về giá trị xấp xỉ, và giá trị bạn in ra sẽ không còn khớp với giá trị mà nhà cung cấp đưa ra. Hãy phân tích các trường này bằng kiểu số thập phân chính xác: Decimal trong Python, BigDecimal trong Java, decimal.Decimal hoặc chuỗi trong JavaScript.

Các trường do chúng tôi tự định nghĩa chứ không phải của nhà cung cấp — scale.min, scale.max, hops — là các số JSON thông thường.

Tái sử dụng kết quả gần đây

Khi bạn sàng lọc cùng một địa chỉ, mạng lưới và nhà cung cấp trong vòng 60 giây, kết quả trước đó sẽ được trả về và không bị tính phí.

Mỗi yêu cầu vẫn tạo một đơn hàng riêng với client_order_id riêng biệt; đơn hàng được tái sử dụng sẽ được đánh dấu "cache_hit": true và khối billing của nó sẽ báo cáo "charged": false cùng với "payment_status": "not_charged". Định danh của đơn hàng gốc tạo ra kết quả sẽ không được tiết lộ — nó có thể thuộc về một tài khoản khác.

Việc tái sử dụng chỉ diễn ra trong phạm vi một tài khoản. Kết quả được sàng lọc bởi người khác sẽ không bao giờ được trả về cho bạn.

Tính bất biến

Gửi X-Idempotency-Key với giá trị của riêng bạn để đảm bảo an toàn khi thử lại: cùng một khóa với cùng một phần thân yêu cầu sẽ trả về phản hồi đã lưu thay vì tạo đơn kiểm tra lần thứ hai.

Trường hợpPhản hồi
Yêu cầu đầu tiên với khóa này vẫn đang chạy4094090
Cùng một khóa, nhưng phần thân yêu cầu khác4094093
Cùng một khóa, cùng phần thân, đã hoàn tất trước đómã đã lưuphản hồi đã lưu

Nếu bạn không gửi header này, một khóa sẽ được tự động tạo cho bạn từ khóa API, địa chỉ, nhà cung cấp và địa chỉ IP của bạn, trong khung thời gian hai giây. Nó giúp bảo vệ khỏi việc nhấp đúp và yêu cầu thử lại từ gateway, chứ không bảo vệ khỏi việc lặp lại sau đó một phút: yêu cầu sau đó là một đơn hàng mới thực sự và sẽ bị tính phí.

Phạm vi của khóa áp dụng theo từng endpoint. Cùng một giá trị được gửi tới POST /apiv2/aml và tới endpoint này là hai cam kết độc lập cho hai yêu cầu khác nhau — phần thân khác nhau, và các phản hồi cũng vậy. Việc sử dụng lại khóa của bạn trong quá trình chuyển đổi tích hợp từ phiên bản 1 sang phiên bản 2 là an toàn: nó không trả về phản hồi phiên bản 1 và cũng không bị tính là cùng một khóa được sử dụng với phần thân khác.

Lỗi

Mọi lỗi do ứng dụng đưa ra đều tuân theo RFC 9457 với 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, detailinstance là các trường tiêu chuẩn. Trường số code được giữ lại dưới dạng phần mở rộng để các tích hợp được viết cho phiên bản 1 có thể tiếp tục khớp với nó. Các trường bổ sung tùy thuộc vào từng loại lỗi và cần phải bỏ qua nếu bạn không biết đến chúng.

HTTPÝ nghĩa
4000400Phần thân không phải là JSON hợp lệ
4001400Một trường không vượt qua xác thực, hoặc trường không xác định đã được gửi
4002403Nhà cung cấp không khả dụng cho tài khoản của bạn
4003400Định danh đơn hàng sai định dạng
4004400Nhà cung cấp không hỗ trợ mạng lưới được yêu cầu
4010401Không có khóa API
4011401Khóa API hoặc địa chỉ IP không được chấp nhận
4040404Không tìm thấy đơn hàng
4041404Không tìm thấy tài khoản
4090409Yêu cầu với khóa bất biến này vẫn đang chạy
4091409Yêu cầu trùng lặp
4093409Khóa bất biến này đã được sử dụng với phần thân khác
1004403Số dư không đủ
5000500Lỗi nội bộ
5001500Không thể thực hiện trừ tiền
5002500Đơn hàng không được tạo
5030503Nhà cung cấp không khả dụng

Các lỗi không sử dụng định dạng này

Một số lỗi xảy ra tại gateway trước khi yêu cầu tới được ứng dụng, và chúng giữ nguyên cấu trúc riêng của gateway. Hãy xử lý bất kỳ phản hồi nào có Content-Type không phải là application/problem+json như một trong các trường hợp sau:

Trường hợpHTTPPhần thân
Không có khóa API, hoặc khóa không được chấp nhận401{"detail":{"code":-1,"msg":"Invalid or missing API key"}}
Đã vượt quá giới hạn tần suất429{"message":"API rate limit exceeded"}
Đường dẫn không tồn tại, hoặc phương thức không được hỗ trợ404 / 405{"detail":"Method Not Allowed"}

Giới hạn tần suất

Giới hạn này được chia sẻ chung với POST /apiv2/aml và các đường dẫn AML khác: 5 yêu cầu mỗi giây và 150 yêu cầu mỗi phút. Việc chuyển sang endpoint này không cấp thêm hạn mức riêng cho bạn.

Ghi chú

  • Định giá: Elliptic $0.98, BitOK $0.50 mỗi lượt kiểm tra, được trừ từ số dư TRX theo tỷ giá tại thời điểm trừ tiền.
  • Thời gian xử lý: phần lớn các lượt kiểm tra hoàn thành trong vài giây; một địa chỉ có lịch sử giao dịch dài có thể mất tới ba phút. Hãy sử dụng chế độ bất đồng bộ và đọc kết quả bằng GET /apiv2/screening/{client_order_id}.
  • Địa chỉ không hoạt động sẽ trả về skipped và không bị tính phí.
  • Phản hồi thô của nhà cung cấp không bao giờ được trả về. provider_data là dữ liệu đã được rà soát và chọn lọc; các trường thuộc về tài khoản của chúng tôi với nhà cung cấp thay vì thuộc về địa chỉ được sàng lọc sẽ không được công khai cho bất kỳ ai.

Báo cáo

Endpoint chỉ trả về JSON và không có gì khác. Không hỗ trợ định dạng PDF và Markdown.

Mọi thông tin cấu thành một báo cáo đều đã có sẵn trong phản hồi: khối dữ liệu chuẩn hóa và provider_data. Việc hiển thị báo cáo ở phía bạn sẽ mang lại tài liệu mà bạn thực sự mong muốn — thương hiệu riêng, ngôn ngữ riêng, bố cục riêng — điều này đặc biệt quan trọng nếu bạn bán lại dịch vụ kiểm tra, vì một báo cáo mang tên chúng tôi sẽ không phải là tài liệu thích hợp để gửi cho khách hàng của bạn.

Nếu bạn cần báo cáo làm bằng chứng cho bên thứ ba — ngân hàng, cơ quan quản lý, đối tác — lưu ý rằng một tệp PDF không có chữ ký số sẽ không có giá trị bằng chứng dù do bất kỳ ai tạo ra: nó có thể được chỉnh sửa bằng trình soạn thảo văn bản trong một phút. Một tài liệu có thể xác thực cần có chữ ký số hoặc một trang xác minh công khai, và đó là một tính năng khác. Nếu đó là trường hợp của bạn, hãy cho chúng tôi biết đối tác của bạn yêu cầu những gì.

Các báo cáo PDF trực quan cho các lượt kiểm tra này có sẵn trên bảng điều khiển Netts, được hỗ trợ bằng mười bảy ngôn ngữ.

Xem thêm