Skip to main content
POST
curl

Why it’s stateless

Standalone wallet screening writes nothing to the transactions table, so there is no stored record for this endpoint to render from. Instead, you repost the exact JSON that POST /v3/wallet-screening/ already gave you, and Didit renders that payload into a PDF without calling a provider again.

The report_signature field

Every POST /v3/wallet-screening/ response now includes a report_signature field — an opaque signature scoped to your application. This endpoint verifies it before rendering, so a caller can’t edit risk_score, severity, sanctions_hit, or any other field and get a clean-looking Didit-branded PDF for a result Didit never produced. Always repost the full response body unmodified, including report_signature. Reordering keys is fine; changing any signed value is not.

Billing

No provider call is made and nothing is billed — this only re-renders a result you already paid for when you called POST /v3/wallet-screening/.

Errors

Next steps

Screen Wallet

Run the underlying on-demand wallet screening and get the JSON result to repost here.

On-demand wallet screening

Overview of the standalone wallet-screening endpoint and result model.

Authorizations

x-api-key
string
header
required

Body

application/json

The unmodified JSON object returned by POST /v3/wallet-screening/, including report_signature.

Same shape as the POST /v3/wallet-screening/ response — pass that response body back verbatim, including report_signature.

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.

provider
string

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

screening_type
enum<string>

Always WALLET_SCREENING for this endpoint.

Available options:
WALLET_SCREENING
risk_score
integer

Normalised 0-100 risk score. Higher means greater exposure to risky entities.

severity
enum<string>

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>

Screening outcome status.

Available options:
SCREENED,
PENDING,
ERROR
summary
string

Human-readable summary of the screening result.

wallet_address
string

The screened address, echoed back.

blockchain
string

The blockchain that was screened.

sanctions_hit
boolean

True if the address has direct or indirect sanctions exposure.

dominant_risk_category
string | null

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

source_of_funds
object[]

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

destination_of_funds
object[]

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

counterparty_connections
object[]

Direct and indirect counterparty entities with received/sent amounts and risk levels.

Response

The rendered PDF document, returned directly as binary application/pdf — there is no JSON wrapper.

The response is of type file.