When to use it
Wallet screening writes nothing to the transactions table. If you need the screening attached to a monitored transaction (with rules, alerts, and webhooks), submit a transaction instead.
Prerequisites
Transaction monitoring must be configured for the application with either a managed provider or an existing provider key. Configure it in Transactions > Settings > Provider Preferences in the Business Console. If no provider is configured, the endpoint returns409 Conflict.
Request
POST https://verification.didit.me/v3/wallet-screening/
Authenticate with the x-api-key header.
Chain coverage
Managed screening supports Base (BASE), Optimism (OP) and Arbitrum One (ARB) for both wallet and transaction-hash screening.
Connected providers may have different coverage; a chain must also be supported by your selected provider and account.
Celo (CELO), Mode (MODE) and Plume (PLUME) are screened through a connected TRM Labs account (Marketplace, bring your own key); managed screening does not cover them and answers 400.
Do not submit ETH for another EVM network: the same address can have different activity and risk on each chain.
With managed screening, USDT and USDC are legacy aliases for Ethereum, not a search across every network where those tokens exist.
Use the network identifier (ETH, TRX, SOL, MATIC, BNB, BASE, OP, ARB, or with TRM Labs CELO, MODE or PLUME) for the wallet’s actual chain.
For tokens in recorded transactions, keep the token in transaction_details.currency and specify the network separately in transaction_details.crypto_params.crypto_chain.
See asset and network selection.
Response
The response is the standardised screening result — identical in shape to theWALLET_SCREENING provider result returned by transaction screening.
How
severity is set. severity is the band of the normalised 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 the provider returned no adverse assessment, while a non-zero score in the 1-9 range is a real but sub-LOW signal - so read the risk_score itself, not just the band. Either way, do not render UNKNOWN as an affirmative “clear” or pass.direction does not change the risk model. The optional direction field is passed to the provider as context only. It does not affect risk_score, severity, or which breakdown lists are returned: both source_of_funds and destination_of_funds are always returned regardless. Changing or omitting direction therefore does not require re-screening a previously screened address.Risk factors
risk_factors is the ranked answer to “why is this address scored the way it is”. Providers grade an address on their own model and return only a verdict — Merkle Science returns an integer 0-5 — so risk_score alone cannot be actioned. Each entry names one driver, ordered high-risk first and then by the value that moved through it.
A high score with no
is_high_risk factor is a real, meaningful outcome. It means the provider graded the address on its own exposure model without reporting a sanctions, PEP or attributed-entity match — the factors that are listed are the fund flows behind the grade. summary states this explicitly, so treat these addresses as “review the flows”, not as a confirmed hit. risk_factors is capped at the five strongest drivers; source_of_funds and destination_of_funds always carry the complete breakdown.risk_factors is a top-level field, not a nested one. Results screened before it existed omit the key entirely — read it as an empty list rather than assuming an empty explanation.Exposure breakdown
Each entry insource_of_funds / destination_of_funds describes one entity the address exchanged funds with:
Counterparty connections
counterparty_connections lists the 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.0. Read the fund flows from source_of_funds and destination_of_funds.
Example
A real response for an address on the OFAC sanctions list, screened with Merkle Science. Onlyraw_response is shortened and report_signature replaced:
sanctions_hit: true can indicate that the wallet itself is sanctioned or only that its funds have sanctions exposure, so it does not by itself mean the screened wallet owner is sanctioned.
When the same screening runs on a recorded transaction, rules can also read custom_values.wallet_sanctioned, which is true only when the provider attributes the wallet itself to a sanctioned entity, and custom_values.aml_sanctions_exposure_pct.
See Screening fields for rules.
Read risk_factors, source_of_funds and destination_of_funds to distinguish attribution from exposure.
See Crypto & Wallet Screening for a walkthrough.
PDF report
To get a Didit-branded PDF of a screening result, repost the exact response body — includingreport_signature — to POST /v3/wallet-screening/pdf/. This is stateless: no provider call, no additional billing, nothing persisted. Editing any signed field (risk_score, severity, sanctions_hit, …) before reposting fails with 400.
Billing
One AML monitoring usage is billed per successful screening at the same rate as transaction-coupled crypto screening. See pricing for managed and connected-key rates. Sandbox applications are not billed. Validation errors (400) and unconfigured-provider errors (409) are never billed.
Errors
Next steps
API reference
Full request and response schema for the Screen Wallet endpoint.
Screen Wallet PDF
Render a screening result as a Didit-branded PDF.
Crypto & wallet screening
Automatic screening during transaction creation and the result model.