Skip to content

POST /apiv2/aml

Superseded by POST /apiv2/screening

POST /apiv2/screening is the version 2 contract: one response shape for every provider and every state of the order, decimal numbers as strings instead of JSON numbers, shares on one scale, and a single error format. This endpoint keeps working and will not be withdrawn without notice.

Submit an address for AML (Anti-Money Laundering) screening. Returns risk score, risk level, and detailed exposure analysis.

All timestamps in the response are UTC. The string format is unchanged — "2026-09-09 23:01:44", without a zone suffix.

Endpoint URL

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

Request Headers

HeaderRequiredDescription
Content-TypeYesapplication/json
X-API-KEYYesYour API key from Netts dashboard

Request Body

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

Parameters

ParameterTypeRequiredDescription
addressstringYesBlockchain address to check (10-100 characters)
networkstringYesBlockchain network identifier (see Supported Networks below)
providerstringNoAML provider: elliptic (default)
waitbooleanNoIf true, wait for result synchronously (up to 15 seconds). If false or omitted, return immediately with pending status and client_order_id — use it to poll result via GET /apiv2/aml/{order_id}
response_formatstringNoResponse detail level: rate (score only), full (default, complete data)
report_languagestringNoLanguage for report: en (default)

Providers

ProviderScore RangeDescription
elliptic0 — 10Elliptic risk score. 0 = no risk, 10 = maximum risk. null = no triggers detected

Example Requests

cURL (synchronous)

bash
curl -X POST https://netts.io/apiv2/aml \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_api_key" \
  -d '{
    "address": "YOUR_ADDRESS_HERE",
    "network": "trx",
    "provider": "elliptic",
    "wait": true
  }'

cURL (asynchronous)

bash
curl -X POST https://netts.io/apiv2/aml \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_api_key" \
  -d '{
    "address": "YOUR_ADDRESS_HERE",
    "network": "trx",
    "provider": "elliptic"
  }'

Python

python
import requests

url = "https://netts.io/apiv2/aml"
headers = {
    "Content-Type": "application/json",
    "X-API-KEY": "your_api_key",
}

payload = {
    "address": "YOUR_ADDRESS_HERE",
    "network": "trx",
    "provider": "elliptic",
    "wait": True
}

response = requests.post(url, headers=headers, json=payload)
data = response.json()

if response.status_code == 200:
    result = data.get("data", {})
    print(f"Order ID: {result.get('client_order_id')}")
    print(f"Status: {result.get('status')}")
    print(f"Risk Score: {result.get('risk_score')}")
    print(f"Risk Level: {result.get('risk_level')}")
    print(f"Sanctioned: {result.get('is_sanctioned')}")
else:
    print(f"Error: {data}")

Response

Success — Pending (200 OK)

When wait is not set or check is still processing:

json
{
    "success": true,
    "data": {
        "client_order_id": "A4C666ABE24BD4A",
        "status": "pending",
        "address": "T...example...",
        "provider": "elliptic",
        "price_usdt": 0.98,
        "price_trx": 4.136286,
        "currency": "TRX",
        "message": "AML check order accepted. Use GET /apiv2/aml/A4C666ABE24BD4A to check status."
    },
    "timestamp": "2026-03-10 09:56:31"
}

Success — Elliptic Completed (200 OK)

Full Elliptic response with all data structures:

json
{
    "success": true,
    "data": {
        "client_order_id": "A019540900E55CA",
        "status": "completed",
        "address": "T...example...",
        "provider": "elliptic",
        "report_language": "en",
        "risk_score": 0.802904,
        "risk_level": "low",
        "is_sanctioned": true,
        "created_at": "2026-03-10 15:56:28",
        "completed_at": "2026-03-10 15:56:28",
        "result": {
            "risk_score": 0.802904473154148,
            "risk_score_detail": {
                "source": 0.233206,
                "destination": 0.802904
            },
            "contributions": {
                "source": [
                    {
                        "entities": [
                            {
                                "name": "Capitalist",
                                "is_vasp": true,
                                "actor_id": 53979,
                                "category": "Payment Services Provider",
                                "entity_id": "b73a9c87-...",
                                "category_id": "54f55bfe-...",
                                "is_primary_entity": true
                            }
                        ],
                        "indirect_value": { "usd": 40194.03 },
                        "contribution_value": { "usd": 40194.03 },
                        "counterparty_value": { "usd": 0 },
                        "min_number_of_hops": 2,
                        "indirect_percentage": 31.57,
                        "is_screened_address": false,
                        "contribution_percentage": 31.57,
                        "counterparty_percentage": 0
                    },
                    {
                        "entities": [
                            {
                                "name": "KuCoin",
                                "is_vasp": true,
                                "actor_id": 11620,
                                "category": "Exchange",
                                "entity_id": "e54292da-...",
                                "category_id": "0a52f7a2-...",
                                "is_primary_entity": true
                            }
                        ],
                        "indirect_value": { "usd": 28436.45 },
                        "contribution_value": { "usd": 29434.17 },
                        "counterparty_value": { "usd": 997.72 },
                        "min_number_of_hops": 1,
                        "indirect_percentage": 22.34,
                        "is_screened_address": false,
                        "contribution_percentage": 23.12,
                        "counterparty_percentage": 0.78
                    }
                ],
                "destination": [
                    {
                        "entities": [
                            {
                                "name": "Bybit",
                                "is_vasp": true,
                                "actor_id": 23354,
                                "category": "Exchange",
                                "entity_id": "bddde8b7-...",
                                "category_id": "0a52f7a2-...",
                                "is_primary_entity": true
                            }
                        ],
                        "indirect_value": { "usd": 26333.43 },
                        "contribution_value": { "usd": 27458.30 },
                        "counterparty_value": { "usd": 1124.86 },
                        "min_number_of_hops": 1,
                        "indirect_percentage": 20.69,
                        "is_screened_address": false,
                        "contribution_percentage": 21.57,
                        "counterparty_percentage": 0.88
                    }
                ]
            },
            "cluster_entities": [
                {
                    "name": "Unknown",
                    "is_vasp": null,
                    "actor_id": -4,
                    "category": "Unknown",
                    "entity_id": "00000000-...",
                    "category_id": "00000000-...",
                    "is_primary_entity": true,
                    "is_after_sanction_date": false
                }
            ],
            "evaluation_detail": {
                "source": [
                    {
                        "rule_id": "6c2dcb03-...",
                        "rule_name": "Obfuscating & Misc.",
                        "rule_type": "exposure",
                        "risk_score": 0.2332,
                        "matched_elements": [
                            {
                                "category": "Coin Swap Service",
                                "category_id": "ff85b715-...",
                                "contributions": [
                                    {
                                        "entity": "FixedFloat",
                                        "risk_triggers": {
                                            "category": "Coin Swap Service",
                                            "category_id": "ff85b715-..."
                                        },
                                        "indirect_value": { "usd": 2891.09, "native": 0, "native_major": 0 },
                                        "contribution_value": { "usd": 2968.66, "native": 0, "native_major": 0 },
                                        "counterparty_value": { "usd": 77.58, "native": 0, "native_major": 0 },
                                        "min_number_of_hops": 1,
                                        "indirect_percentage": 2.27,
                                        "is_screened_address": false,
                                        "contribution_percentage": 2.33,
                                        "counterparty_percentage": 0.06
                                    }
                                ],
                                "indirect_value": { "usd": 2891.09, "native": 0, "native_major": 0 },
                                "contribution_value": { "usd": 2968.66, "native": 0, "native_major": 0 },
                                "counterparty_value": { "usd": 0, "native": 0, "native_major": 0 },
                                "indirect_percentage": 100,
                                "contribution_percentage": 2.33,
                                "counterparty_percentage": 0
                            }
                        ],
                        "matched_behaviors": []
                    },
                    {
                        "rule_id": "0a2b68fd-...",
                        "rule_name": "Illicit Activity",
                        "rule_type": "exposure",
                        "risk_score": 0.0026,
                        "matched_elements": [
                            {
                                "category": "Token Blacklisting",
                                "category_id": "94b50de8-...",
                                "contributions": [
                                    {
                                        "entity": "Tether USD",
                                        "risk_triggers": {
                                            "category": "Token Blacklisting",
                                            "category_id": "94b50de8-..."
                                        },
                                        "contribution_value": { "usd": 1022.45, "native": 0, "native_major": 0 },
                                        "min_number_of_hops": 3,
                                        "contribution_percentage": 0.08
                                    }
                                ]
                            }
                        ],
                        "matched_behaviors": []
                    },
                    {
                        "rule_id": "df59fab5-...",
                        "rule_name": "Sanctions",
                        "rule_type": "exposure",
                        "risk_score": 0.0024,
                        "matched_elements": [
                            {
                                "category": "Sanctioned Entity",
                                "category_id": "c1648b7a-...",
                                "contributions": [
                                    {
                                        "entity": "Garantex",
                                        "risk_triggers": {
                                            "category": "Sanctioned Entity",
                                            "category_id": "c1648b7a-..."
                                        },
                                        "contribution_value": { "usd": 863.21, "native": 0, "native_major": 0 },
                                        "min_number_of_hops": 3,
                                        "contribution_percentage": 0.07
                                    }
                                ]
                            }
                        ],
                        "matched_behaviors": []
                    }
                ],
                "destination": []
            },
            "detected_behaviors": []
        },
        "sanctions": {
            "self": false,
            "self_entities": null,
            "exposure": {
                "share": 8.029045,
                "proximity": "mixed",
                "hops": 1,
                "entity": "Garantex Europe OU - OFAC SDN - 5 Apr 2022",
                "category": "OFAC Sanctioned Entity",
                "direction": "destination",
                "rule_name": "Sanctioned, TF & CSAM"
            },
            "items": [
                {
                    "entity": "Garantex Europe OU - OFAC SDN - 5 Apr 2022",
                    "category": "OFAC Sanctioned Entity",
                    "share": 8.02904473154148,
                    "counterparty_share": 2.472410320321629,
                    "indirect_share": 5.556634411219852,
                    "hops": 1,
                    "proximity": "mixed",
                    "is_sanctioned": true,
                    "trigger": "sanctions_list",
                    "value_usd": 7494.407584232807,
                    "direction": "destination",
                    "rule_name": "Sanctioned, TF & CSAM"
                }
            ]
        }
    },
    "timestamp": "2026-03-10 15:56:28"
}

Response Fields

FieldTypeDescription
data.client_order_idstringUnique order ID for status polling
data.statusstringpending, processing, completed, failed, skipped
data.risk_scorenumber | nullRisk score. Elliptic: 0-10. null = no triggers
data.risk_levelstring | nullnone, low, medium, high or severe. Elliptic returns low, medium, high; BitOK adds none and severe. null when the provider detected no triggers at all
data.is_sanctionedbooleantrue if exposure to sanctioned entities detected. Unchanged since the endpoint launched: it does not distinguish a sanctioned address from an address merely linked to one — see data.sanctions for that
data.sanctionsobject | nullBreakdown of the sanctions finding: whether the address itself is listed, how close the link is and how large. See Sanctions
data.resultobjectFull provider response (when response_format=full)

Sanctions

is_sanctioned is a single boolean, and it says true in two very different situations: the screened address is itself on a sanctions list, and the screened address once received a fraction of a percent through two intermediaries from someone who is. The flag keeps its original meaning for backward compatibility; data.sanctions tells the two cases apart.

FieldTypeDescription
sanctions.selfbooleantrue when the screened address itself is the sanctioned entity
sanctions.self_entitiesarray | nullNames of its own sanctioned entities, when self is true
sanctions.exposureobject | nullThe single largest sanctions link — what to show in a summary
sanctions.exposure.sharenumberShare of funds involved, in percent (8.03 means 8.03%)
sanctions.exposure.proximitystringscreened_address, counterparty, indirect or mixed
sanctions.exposure.hopsnumber | nullMinimum number of transaction hops to the sanctioned entity
sanctions.exposure.entitystring | nullSanctioned entity name, including the list and the date
sanctions.exposure.directionstring | nullsource for incoming funds, destination for outgoing
sanctions.itemsarrayEvery sanctions contribution, largest share first, same fields as exposure plus counterparty_share, indirect_share, value_usd and trigger
sanctions.relatedarray | nullBitOK only: exposure to exchanges under EU or UK sanctions, kept apart from the sanctions list itself

Proximity mirrors the Closest Proximity column of an Elliptic report:

ValueMeaning
screened_addressThe screened address is the trigger itself, not a counterparty
counterpartyDirect counterparty of the screened address
indirectReached through intermediaries — see hops
mixedBoth direct and indirect flows to the same entity

A contribution counts as a sanctions link only when the provider marks it as such — risk_triggers.is_sanctioned for Elliptic, the sanctions category for BitOK. The Elliptic rule named Sanctioned, TF & CSAM also fires on country and category triggers, so the rule name alone is not a sanctions verdict.

Elliptic result Object

FieldTypeDescription
risk_scorenumberPrecise risk score (0-10)
risk_score_detailobjectBreakdown: source and destination scores
contributionsobjectsource and destination arrays of fund flow contributors
contributions[].entitiesarrayKnown entities associated with the contribution
contributions[].entities[].namestringEntity name (e.g. "Binance", "KuCoin")
contributions[].entities[].categorystringEntity type (e.g. "Exchange", "Payment Services Provider")
contributions[].entities[].is_vaspboolean | nullWhether the entity is a Virtual Asset Service Provider
contributions[].contribution_value.usdnumberTotal USD volume of the contribution
contributions[].contribution_percentagenumberPercentage of total funds from this entity
contributions[].indirect_value.usdnumberUSD volume received indirectly (via intermediaries)
contributions[].indirect_percentagenumberPercentage of funds received indirectly
contributions[].counterparty_value.usdnumberUSD volume as direct counterparty
contributions[].counterparty_percentagenumberPercentage as direct counterparty
contributions[].min_number_of_hopsnumberMinimum transaction hops from the entity (0 = direct)
contributions[].is_screened_addressbooleantrue if this is the screened address itself
cluster_entitiesarrayKnown entities directly associated with the address cluster
cluster_entities[].namestringEntity name
cluster_entities[].categorystringEntity category
cluster_entities[].is_vaspboolean | nullVASP status
cluster_entities[].is_after_sanction_datebooleantrue if activity occurred after entity was sanctioned
evaluation_detailobjectsource and destination arrays of triggered risk rules
evaluation_detail[].rule_namestringRule name (e.g. "Sanctions", "Illicit Activity", "Obfuscating & Misc.")
evaluation_detail[].rule_typestringRule type (e.g. "exposure")
evaluation_detail[].risk_scorenumberRisk score contribution from this rule
evaluation_detail[].matched_elementsarrayCategories and entities that triggered the rule
evaluation_detail[].matched_elements[].categorystringRisk category (e.g. "Sanctioned Entity", "Gambling", "Token Blacklisting")
evaluation_detail[].matched_elements[].contributionsarrayEntities within the matched category
evaluation_detail[].matched_elements[].contributions[].entitystringEntity name
evaluation_detail[].matched_elements[].contributions[].contribution_percentagenumberExposure percentage
evaluation_detail[].matched_elements[].contributions[].min_number_of_hopsnumberTransaction hops
evaluation_detail[].matched_elements[].contributions[].is_screened_addressbooleantrue when the screened address itself triggered the rule
evaluation_detail[].matched_elements[].contributions[].risk_triggersobjectWhy the rule fired: is_sanctioned for a sanctions list, country for a jurisdiction, category for an entity type
evaluation_detail[].matched_behaviorsarrayDetected behavioral patterns
detected_behaviorsarrayGlobal behavioral patterns detected on the address

Risk Levels

Elliptic (0-10 scale):

RangeLevelDescription
0 — 3lowMinimal risk. No significant exposure
3 — 7mediumModerate risk. Some risky categories detected
7 — 10highHigh risk. Sanctioned, illicit, or high-risk entities
null-No risk triggers detected

BitOK (0-1 scale): the provider returns the level itself — none, low, medium, high or severe.

risk_level is the single verdict used everywhere: the API response, the dashboard and the PDF report all print the same word for the same check.

Error Responses

Authentication Error (401)

json
{
    "detail": {
        "code": -1,
        "msg": "API key not provided"
    }
}

Validation Error (400)

json
{
    "success": false,
    "error": {
        "code": 4001,
        "msg": "Invalid or missing address"
    }
}
json
{
    "success": false,
    "error": {
        "code": 4002,
        "msg": "Invalid provider. Use: elliptic"
    }
}

Insufficient Balance (402)

json
{
    "success": false,
    "error": {
        "code": 4020,
        "message": "Insufficient balance"
    },
    "timestamp": "2026-03-10 10:00:00"
}

Provider Unavailable (503)

json
{
    "success": false,
    "error": {
        "code": 5030,
        "message": "Provider elliptic not available"
    },
    "timestamp": "2026-03-10 10:00:00"
}

Error Code Reference

CodeDescriptionHTTP Status
-1Authentication failed401
4001Invalid or missing address400
4002Invalid provider400
4020Insufficient balance402
5030Provider unavailable503

Rate Limits

The following rate limits apply to all AML endpoints (per IP address):

PeriodLimitDescription
1 second2 requestsMaximum 2 requests per second
1 minute30 requestsMaximum 30 requests per minute

Rate Limit Exceeded (429)

json
{
    "message": "API rate limit exceeded"
}

Result Caching

If the same address + provider combination was checked within the last 60 seconds, the cached result is returned at no charge.

Supported Networks

The network parameter is required. Use the ticker from the table below.

Elliptic — Holistic Screening

Screening is performed for a specific address on a specific network. However, Elliptic traces all assets associated with that address — including tokens, cross-chain transfers, and interactions with known entities across other networks.

NetworkTickerNative Asset
AlgorandalgoALGO
AptosaptAPT
ArbitrumarbETH
Avalanche (C-Chain)avaxAVAX
BasebaseETH
Binance ChainbnbBNB
Binance Smart ChainbscBNB
BitcoinbtcBTC
BittensortaoTAO
CardanoadaADA
CeloceloCELO
CosmosatomATOM
Crypto.comcroCRO
DogecoindogeDOGE
dYdXdydxDYDX
EthereumethETH
Ethereum ClassicetcETC
FantomftmFTM
FilecoinfilFIL
FlareflrFLR
GnosisgnosisxDai
HederahbarHBAR
HyperEVMhypeHYPE
InjectiveinjINJ
Internet ComputericpICP
LinealineaLINEA
LitecoinltcLTC
MobileCoinmobMOB
NearnearNEAR
OptimismopETH
PolkadotdotDOT
PolygonmaticMATIC
RipplexrpXRP
SeiseiSEI
SolanasolSOL
StarknetstrkSTRK
StellarxlmXLM
SuisuiSUI
TezosxtzXTZ
TONtonTON
TrontrxTRX
XDCxdcXDC
XLayerokbOKB
ZilliqazilZIL
zkSynczksyncETH

Single Asset Screening

These networks support individual address/transaction screening:

NetworkTickerNative Asset
Bitcoin CashbchBCH
HorizenzenZEN
ZCashzecZEC

Provider & Network Compatibility

When using provider: "elliptic" — all networks from Holistic and Single Asset tables are available (47 networks). If an unsupported network is passed, the API returns error code 4001.

Notes

  • Pricing: Elliptic — $0.98 per check. Prices shown in TRX at current rate
  • Sync timeout: wait: true waits up to 15 seconds. If check takes longer, returns pending status
  • Processing time: Most checks complete within a few seconds. However, some requests (especially for addresses with complex transaction history) may take up to 3 minutes to process. Use asynchronous mode (omit wait or set wait: false) and poll via GET /apiv2/aml/{order_id} for such cases
  • Inactive addresses: Addresses with no blockchain activity return skipped status at no charge