Wallet Risk Screening Data
Every payment's external counterparty wallet is screened via a blockchain analytics provider. The sender wallet is screened on an inbound payment; the destination or destination VASP wallet on an outbound payment. This page explains how the outcome is reported on the payment record and how to read it. For what screening evaluates and how the decision is made, see Compliance and Risk Management.
Screening results appear on the payment resource in two places:
risk_status_reasons[]— the structured signals that determined the outcome, one object per signal.provider_metadata[]— the raw screening response, passed through for your own analytics and audit.
Risk Statuses and Webhooks
Screening produces one risk_status per payment after the initial check:
risk_status | Meaning |
|---|---|
unchecked | Initial state; screening has not yet resolved. |
automatically_approved | No material risk (no risk factors, or no risk factors above threshold). |
awaiting_decision | Material exposure warranting review by your organization. |
automatically_rejected | A severe finding, a blocklisted counterparty, or a screening failure (per your configured failure action). |
If the initial status was awaiting_decision and your organization manually reviews the payment and reports a decision, then the risk_status will be updated to either:
risk_status | Meaning |
|---|---|
manually_approved | A reviewer in your organization approved the payment. |
manually_rejected | A reviewer in your organization rejected the payment. |
Every risk_status change fires a payment.risk_updated webhook.
On inbound payments, screening runs in parallel with on-chain finalization: payment.risk_updated and step.completed can fire in either order, and the screening outcome does not gate the balance credit. On outbound payments, an approving outcome is required before the payment executes. See Receive an Inbound Payment for the full inbound event sequence.
How a Screen Resolves to a Status
The checks below are applied in order; the first that resolves determines the risk_status. See Compliance and Risk Management for the prose version.
Reading risk_status_reasons[]
The array is designed so you can reconstruct the decision from the payment record alone:
- Every reason that decided the outcome appears, tagged
DECISIVE. - Every risk factor above its materiality threshold that did not decide the outcome also appears, tagged
NON_DECISIVE— you see what was evaluated, not only what tipped the decision. - When the external entity was on an allowlist or blocklist, any reason that would otherwise have decided it appears tagged
SUPERSEDED_BY_ALLOWLISTorSUPERSEDED_BY_BLOCKLIST. - Risk factors at or below threshold never appear here, but the complete raw screening data is always available in
provider_metadata[]. - Each factor with thresholds carries both the configured threshold and the observed value, so you can determine which gate tripped — percentage, dollar, or both.
- When the only above-threshold factors are Low or Medium severity, they are surfaced but the payment still approves automatically — severity, not the threshold breach, is what decides.
Field Reference
| Field | Description |
|---|---|
risk_status_reason_type | One of OWNERSHIP, COUNTERPARTY, INDIRECT (risk-indicator types), BEHAVIORAL (wallet behavior patterns), ENTITY (entity attribution, including allowlist and blocklist matches), or ERROR (screening failure, or a token-contract attribution). |
risk_status_reason_category | For OWNERSHIP / COUNTERPARTY / INDIRECT: a wallet screening risk category. For BEHAVIORAL: a behavioral pattern from the same taxonomy. For ENTITY: the entity's category — or, for an allowlist or blocklist match, the participant role matched (ORIGINATOR, ORIGINATOR_VASP, BENEFICIARY, BENEFICIARY_VASP, CUSTODY_SERVICE, INTERMEDIARY_VASP, CONTRACT). For ERROR: SCREENING_FAILED when wallet screening could not be completed, or Token Contract when the screened wallet is attributed to a token contract (the payment is routed to manual review). |
risk_status_reason_participant_id | The id of the participant referenced. Populated for ENTITY reasons and for the token-contract ERROR reason; otherwise null. |
risk_status_reason_message | A plain-English description of the risk or the failure to screen. |
risk_status_reason_severity | Low, Medium, High, or Severe. For an ENTITY reason recording a list match: ALLOWLISTED or BLOCKLISTED. The screening-failure reason carries Severe. |
risk_status_reason_significance | How the reason figured in the decision: DECISIVE, NON_DECISIVE, SUPERSEDED_BY_ALLOWLIST, SUPERSEDED_BY_BLOCKLIST, or null. |
volume_usd_percent | The observed share of the wallet's volume for this risk indicator (e.g., "25"). OWNERSHIP / COUNTERPARTY / INDIRECT only; else null. |
volume_usd_percent_threshold | The configured percentage threshold, if set; else null. OWNERSHIP / COUNTERPARTY / INDIRECT only. |
volume_usd_amount | The observed dollar volume for this risk indicator (e.g., "999"). OWNERSHIP / COUNTERPARTY / INDIRECT / BEHAVIORAL only; else null. |
volume_usd_amount_threshold | The configured dollar threshold, if set; else null. OWNERSHIP / COUNTERPARTY / INDIRECT / BEHAVIORAL only. |
confidence_score | The observed confidence level of the entity attribution (e.g., HIGH_CONFIDENCE, NEAR_CERTAINTY). CERTAIN — identifies an entity identity established through a Travel Rule authorization flow rather than inferred from on-chain analytics. For ENTITY reasons only when risk_status_reason_severity = ALLOWLISTED or BLOCKLISTED. null otherwise. |
confidence_score_threshold | The confidence level the entity attribution must exceed in order for an entity to be eligible for allowlisting or blocklisting. For ENTITY reasons only when risk_status_reason_severity = ALLOWLISTED or BLOCKLISTED. null otherwise. |
Severity and thresholds
A Severe finding about the wallet itself — its ownership, its entity attribution, or its behavior — rejects automatically with no thresholds applied. A Severe finding for the same risk category but with risk_status_reason_type = COUNTERPARTY or INDIRECT is evaluated against its materiality thresholds. This is to ensure that when the screened wallet itself demonstrates severe risk factors (e.g. owned by a sanctioned entity, linked to terrorist financing) it is blocked, whereas a legitimate, high-volume custodial wallet can pass despite incidental contact with risky addresses.
Outcome Examples
Approved, nothing surfaced. A screen with no risk factors — or none above threshold — produces an empty array. The two cases differ only in the raw response in provider_metadata[]:
Code
Approved with factors above threshold. The "Medium" severity factor decided the outcome. When the most severe risk factor identified has a low or medium severity, the payment still approves:
Code
Routed to manual review. A "High" severity counterparty exposure above its materiality threshold decided the outcome; the "Low" severity factor above its threshold is surfaced for context:
Code
Rejected due to blocklist match. The blocklist match decides ahead of every other check. The High counterparty exposure would have routed the payment to review on its own, so it is tagged SUPERSEDED_BY_BLOCKLIST:
Code
Rejected because screening could not complete. No screening response was obtained, so provider_metadata[] carries no wallet-screening entry. The rejection carries a dedicated screening-failure reason, so it is programmatically distinguishable from a risk-based rejection:
Code
Manual Review
When risk_status is awaiting_decision, submit a decision via the risk review endpoint or in the Tesser dashboard. After the decision is recorded, risk_status transitions to manually_approved or manually_rejected, risk_reviewed_by and risk_reviewed_at populate, and a second payment.risk_updated fires. risk_status_reasons[] is unchanged from the automatic outcome — the record keeps showing what the screen found.
Raw Screening Data
The provider_metadata[] entry with provider_metadata_type = WALLET_RISK_SCREENING carries the raw screening response: the wallet's volumes and transaction counts, the full set of risk indicators (including those below threshold), behavioral patterns, and entity attributions. Use it for your own analytics and audit; Tesser's outcome is derived only from the material signals summarized in risk_status_reasons[].
Abridged example:
Code
The raw payload reflects the screening provider's response shape (camelCase field names) and is passed through as received.
What Your Organization Can Configure
The thresholds, lists, and failure behavior that drive these outcomes ship with Tesser defaults and can be tuned for your organization — see What Your Organization Can Configure.