Skip to main content
POST
curl

Authorizations

x-api-key
string
header
required

Your application's API key, from Developers -> API keys in the Business Console. The primary key has full access. A named key can be scoped: none, read or write per resource, limited to some workflows or to approved sessions, to a list of IP addresses, and to an expiry date. 401 means the key is missing, wrong, revoked or expired; 403 means the key has no access to this resource or action, or the request came from an address outside its IP list; 404 on a session route means the session is outside the key's workflows or statuses. A key without media access receives image, video and PDF URLs as null, and a key without sessions write receives session links and tokens as null. See https://docs.didit.me/console/api-keys.

Body

application/json
wallet_address
string
required

The crypto address or network identifier to screen. Must match the selected network (e.g. a 0x-prefixed 40-hex-char address for EVM chains). Alias: address.

Example:

"0x94f1b9b64e2932f6a2db338f616844400cd58e8a"

blockchain
enum<string>
required

Network identifier. Managed screening supports BTC, ETH, LTC, XRP, BCH, DOGE, TRX, SOL, MATIC, BNB, BASE (Base), OP (Optimism), and ARB (Arbitrum One). USDT and USDC are legacy Ethereum aliases, not multi-network searches. Connected-provider coverage varies. LIGHTNING requires a supported connected provider. CELO (Celo), MODE (Mode) and PLUME (Plume) are screened through a connected TRM Labs account; managed screening answers 400 for them. Alias: currency.

Available options:
BTC,
LIGHTNING,
ETH,
LTC,
XRP,
BCH,
DOGE,
TRX,
SOL,
MATIC,
BNB,
USDT,
USDC,
BASE,
OP,
ARB,
CELO,
MODE,
PLUME
Example:

"ETH"

direction
enum<string>

Optional. Whether the address is being screened as an inbound (deposit) or outbound (withdrawal) counterparty. Accepts inbound, outbound, deposit, or withdrawal. Defaults to a neutral pre-transfer screen when omitted. This is passed to the provider as context only; it does not change the returned risk_score, severity, or the source_of_funds/destination_of_funds breakdowns, which are always both returned regardless of direction. Changing or omitting direction therefore does not require re-screening an address.

Available options:
inbound,
outbound,
deposit,
withdrawal

Response

The normalised wallet screening result.

provider
string
required

Provider that performed the screening (e.g. merklescience, crystal).

screening_type
enum<string>
required

Always WALLET_SCREENING for this endpoint.

Available options:
WALLET_SCREENING
risk_score
integer
required

Normalised 0-100 risk score. Higher means greater exposure to risky entities. Merkle Science grades an address 0-5, which maps to 0, 15, 35, 55, 75 or 95.

severity
enum<string>
required

Risk bucket derived from risk_score: 0-9 UNKNOWN, 10-39 LOW, 40-69 MEDIUM, 70-89 HIGH, 90-100 CRITICAL. UNKNOWN is the lowest band, not a separate no-data state: risk_score 0 (the common clean-address case) means no adverse assessment, while a non-zero score in the 1-9 range is a real but sub-LOW signal - read the risk_score, not just the band. Never treat UNKNOWN as an affirmative low-risk or clear rating; do not display it as a pass.

Available options:
UNKNOWN,
LOW,
MEDIUM,
HIGH,
CRITICAL
status
enum<string>
required

Screening outcome status.

Available options:
SCREENED,
PENDING,
ERROR
summary
string
required

Human-readable summary of the screening result.

wallet_address
string
required

The screened address, echoed back.

blockchain
string
required

The blockchain that was screened.

source_of_funds
object[]
required

Where the address received funds from, attributed by entity. Each entry is an exposure breakdown.

destination_of_funds
object[]
required

Where the address sent funds to, attributed by entity. Same item shape as source_of_funds with exposure_direction = outgoing.

counterparty_connections
object[]
required

Entities the provider attributes the screened address to. For Merkle Science these come from the address's own owner and user tags, so the same entity can appear twice, and they carry no fund flows: received_usd, sent_usd, received_hops and sent_hops are null and percentage is 0. Do not route on risk_level or is_direct here: use sanctions_hit, dominant_risk_category and risk_factors[].is_high_risk for the verdict, and exposure_type in source_of_funds/destination_of_funds for directness.

sanctions_hit
boolean
required

True if the address has direct or indirect sanctions exposure.

dominant_risk_category
string | null
required

Highest-weighted high-risk category, or null when none is dominant (e.g. sanctioned, mixer, stolen_funds).

report_signature
string
required

Opaque HMAC-SHA256 signature over this exact result, scoped to your application. Not meaningful on its own — repost the full response body, unmodified and including this field, to POST /v3/wallet-screening/pdf/ to render it as a PDF. The PDF endpoint rejects the request with 400 if report_signature is missing or if any signed field (e.g. risk_score, severity, sanctions_hit) was edited before repost.

transaction_hash
string | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

block_timestamp
string | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

total_value_usd
number | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

fee_usd
number | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

sender_rows
object[]

Transaction screening field, shared with the result shape. Always empty on a wallet screening result.

receiver_rows
object[]

Transaction screening field, shared with the result shape. Always empty on a wallet screening result.

transaction_flows
object[]

Transaction screening field, shared with the result shape. Always empty on a wallet screening result.

transaction_flows_status
string | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

transaction_flows_error
string | null

Transaction screening field, shared with the result shape. Always null on a wallet screening result.

network_nodes
object[]

Exposure graph nodes for transaction screening. Empty on a wallet screening result.

network_edges
object[]

Exposure graph edges for transaction screening. Empty on a wallet screening result.

pep_counterparty
boolean | null

Politically exposed person exposure. null when no PEP finding is available, which is every result today because no provider reports one; false only for an explicit negative screening result. Do not read null as a completed PEP check.

risk_factors
object[]

Ranked explanation of risk_score: what produced this verdict. Providers grade an address on their own model and return only a verdict (Merkle Science returns an integer 0-5), so the score alone is not actionable. Ordered high-risk first, then by the value that moved through each driver, capped at the five strongest; source_of_funds and destination_of_funds always carry the complete breakdown. A high risk_score with no is_high_risk entry means the provider reported no sanctions or attributed-entity match and graded the address purely on its own exposure model - summary states this explicitly.

raw_response
object

The provider's own payload. Its shape is provider-specific and can change without notice: read the normalised fields instead of parsing it.