---
title: "Simulate an inbound payment with mocked risk screening (non-production only)"
method: POST
path: "/v1/payments/simulate-inbound"
tags: ["Payments"]
---

# Simulate an inbound payment with mocked risk screening (non-production only)

`POST /v1/payments/simulate-inbound`

## Request

- Base URL: `https://api.tesser.xyz`
- URL: `https://api.tesser.xyz/v1/payments/simulate-inbound`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/tesser/apis/tesser-api/docs/v1/payments/simulate-inbound/post.ts> (a function with typed inputs; its response is checked against the schema)

Sends a real on-chain test-USDC transfer from the platform faucet into a managed wallet and fakes its risk screening: either forces the verdict to mocked_risk_status, or screens the fixed findings of mocked_screening_scenario through the real screening pipeline. Send exactly one of the two. Not available in production. Returns 201 with the screened payment, or 202 with the tx hash if it is still being detected/screened.

## Request body

- SimulateInboundPaymentRequest
  - `to_account` string, uuid, required: Managed account ID that should receive the simulated inbound.
  - `mocked_risk_status` 'automatically_approved' | 'awaiting_decision' | 'automatically_rejected': The risk_status the screening verdict should be forced to. Send this or `mocked_screening_scenario`, exactly one.
  - `mocked_screening_scenario` 'vasp_findings_near_threshold': A named screening scenario: a fixed screening provider response that the real screening pipeline evaluates against your Risk Profile, so `risk_status` is whatever your Risk Profile decides. `vasp_findings_near_threshold`: a VASP-hosted sender with two findings just over the default 0.1% VASP-hosted threshold. Send this or `mocked_risk_status`, exactly one.
  - `network` 'BASE_SEPOLIA' | 'ETHEREUM_SEPOLIA' | 'POLYGON_AMOY' | 'TEMPO_MODERATO': EVM testnet to send on. Defaults to BASE_SEPOLIA.

## Response `201`

The simulated inbound payment, already screened: to mocked_risk_status, or to the risk_status your Risk Profile decides for mocked_screening_scenario.

- PaymentResponse
  - `data` Payment, required
    - `id` string, required: Unique payment identifier
    - `workspace_id` string, required: Workspace ID the payment belongs to
    - `organization_reference_id` string, nullable: External reference ID for tracking.
    - `payment_info` PaymentInfo: Optional caller intent about why a payment is being sent. Both fields optional.
      - `payment_description_wire` string: Free-text description forwarded to the payout provider (max 140 chars); appears on the beneficiary's bank statement.
      - `payment_reason_code` string: Short code classifying the payment's purpose. Stored by Tesser, not forwarded to the provider.
    - `direction` 'inbound' | 'outbound' | 'rebalance', required: Payment direction.
    - `funding_account_id` string, nullable, required: Funding account ID. Payment-only field. Top-level (not part of any overlay).
    - `desired` PaymentDesiredOverlay, required: Caller's stated intent at creation. Frozen except by the two-step PATCH flow which fills account IDs.
      - `from` PaymentDesiredFromLegResponse, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` PaymentDesiredToLegResponse, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `estimated` PaymentEstimatedOverlay, required: Tesser's projection for how the payment will proceed.
      - `from` PaymentEstimatedFromLeg, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` PaymentEstimatedToLeg, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `actual` PaymentActualOverlay, required: What actually settled. Populated once at least one step has `status: completed`.
      - `from` PaymentActualFromLeg, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` PaymentActualToLeg, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `risk_status` 'unchecked' | 'awaiting_decision' | 'automatically_approved' | 'manually_approved' | 'automatically_rejected' | 'manually_rejected' | 'null', nullable, required: Risk assessment status. Cross-ramp payments are not risk-screened: `null` when no status is stored, otherwise the stored status.
    - `risk_status_reasons` RiskStatusReason[], required: Reasons `risk_status` was assigned to the specific outcome (`automatically_approved`, `awaiting_decision`, `automatically_rejected`).
      - `risk_status_reason_type` 'ENTITY' | 'ACCOUNT' | 'OWNERSHIP' | 'COUNTERPARTY' | 'INDIRECT' | 'BEHAVIORAL' | 'ERROR', required: Type of risk identified for the screened wallet or wallets it interacted with. `OWNERSHIP`: risk from the screened wallet's own activity. `COUNTERPARTY`: a wallet the screened wallet directly interacted with. `INDIRECT`: wallets the screened wallet had indirect exposure to (two or more hops away). `BEHAVIORAL`: the screened wallet's behavior demonstrates a pattern of money laundering or funds obfuscation. `ENTITY`: risk from the screened wallet's attributed entity, including allowlist and blocklist matches. `ACCOUNT`: the screened wallet address itself matched your allowlist; the reason points at the account holding it. `ERROR`: wallet screening could not be completed.
      - `risk_status_reason_category` string, required: The specific risk category within the type. For `risk_status_reason_type` = `OWNERSHIP`, `COUNTERPARTY`, or `INDIRECT`: one of the [supported risk categories](/overviews/wallet-screening-risk-categories#supported-risk-categories). For `BEHAVIORAL`: one of the [behavioral signatures](/overviews/wallet-screening-risk-categories#behavioral-signatures). For `ENTITY`: one of the supported risk categories when `risk_status_reason_severity` is `Low`, `Medium`, `High`, or `Severe`; the participant role (`ORIGINATOR`, `ORIGINATOR_VASP`, `BENEFICIARY`, `BENEFICIARY_VASP`, `CUSTODY_SERVICE`, or `INTERMEDIARY_VASP`) when `risk_status_reason_severity` is `ALLOWLISTED` or `BLOCKLISTED`. For `ACCOUNT`: the participant role of the screened wallet — `BENEFICIARY` on an outbound payment, `ORIGINATOR` on an inbound one. For `ERROR`: `SCREENING_FAILED` when wallet screening could not be completed, or `Token Contract` when the counterparty is a token contract.
      - `risk_status_reason_participant_id` string, nullable: Links this reason to the corresponding `participants[].resource.id`. Populated on `ENTITY` reasons, on the token-contract `ERROR` reason, and on `ACCOUNT` reasons (the account holding the allowlisted address); otherwise null.
      - `risk_status_reason_message` string, required: Plain-English description of the risk category.
      - `risk_status_reason_severity` 'Low' | 'Medium' | 'High' | 'Severe' | 'ALLOWLISTED' | 'BLOCKLISTED', required: Severity of the signal: `Low`, `Medium`, `High`, or `Severe`. For an `ENTITY` reason recording an allowlist or blocklist match: `ALLOWLISTED` or `BLOCKLISTED`.
      - `risk_status_reason_significance` 'DECISIVE' | 'NON_DECISIVE' | 'SUPERSEDED_BY_ALLOWLIST' | 'SUPERSEDED_BY_BLOCKLIST', nullable: How the reason figured in the `risk_status` outcome. `DECISIVE`: drove the outcome. `NON_DECISIVE`: exceeded a threshold in your risk policy but did not drive the outcome (a more severe reason was identified). `SUPERSEDED_BY_ALLOWLIST` / `SUPERSEDED_BY_BLOCKLIST`: would have been decisive but for an allowlist or blocklist match. Null when not applicable.
      - `volume_usd_percent` string, nullable: Observed share of the wallet's volume for this risk indicator, as a percentage. `OWNERSHIP`, `COUNTERPARTY`, and `INDIRECT` reasons only; otherwise null.
      - `volume_usd_percent_threshold` string, nullable: Configured percentage-of-volume threshold for this risk indicator, if set; otherwise null.
      - `volume_usd_amount` string, nullable: Observed USD volume for this risk indicator. `OWNERSHIP`, `COUNTERPARTY`, `INDIRECT`, and `BEHAVIORAL` reasons only; otherwise null.
      - `volume_usd_amount_threshold` string, nullable: Configured USD-volume threshold for this risk indicator, if set; otherwise null.
      - `confidence_score` 'LOW_CONFIDENCE' | 'LOW_MODERATE_CONFIDENCE' | 'MODERATE_CONFIDENCE' | 'HIGH_MODERATE_CONFIDENCE' | 'HIGH_CONFIDENCE' | 'NEAR_CERTAINTY' | 'CERTAIN' | 'EXACT_MATCH', nullable: The observed confidence level of the entity attribution. Populated for `risk_status_reason_type` = `ENTITY` when `risk_status_reason_severity` = `ALLOWLISTED` or `BLOCKLISTED`, and for `risk_status_reason_type` = `ACCOUNT`. `null` otherwise. The wallet screening provider supplies `LOW_CONFIDENCE` through `NEAR_CERTAINTY`; `CERTAIN` is Tesser-defined and marks an identity supplied through a Travel Rule data provider rather than inferred by the wallet screening provider; `EXACT_MATCH` is Tesser-defined and marks an `ACCOUNT` reason — the screened wallet address itself is on your allowlist, so no attribution was involved.
      - `confidence_score_threshold` 'LOW_CONFIDENCE' | 'LOW_MODERATE_CONFIDENCE' | 'MODERATE_CONFIDENCE' | 'HIGH_MODERATE_CONFIDENCE' | 'HIGH_CONFIDENCE' | 'NEAR_CERTAINTY' | 'CERTAIN', nullable: The confidence level the entity attribution must exceed in order for an entity to be eligible for allowlisting or blocklisting. Populated only for `risk_status_reason_type` = `ENTITY` when `risk_status_reason_severity` = `ALLOWLISTED` or `BLOCKLISTED`. `null` otherwise, including on an `ACCOUNT` reason: an address match has no confidence bar.
    - `provider_metadata` object[], required: Provider-defined responses for the payment, one entry per provider, passed through for analytics and audit. Wallet screening data can reference chains other than the payment network; use the payment's estimated or actual network fields for routing and risk_status, risk_status_reasons, and participants for Tesser's normalized screening outcome.
      - `provider_metadata_type` 'WALLET_RISK_SCREENING' | 'TRAVEL_RULE': What the payload is.
      - `provider_metadata_key` 'TRM_LABS' | 'NOTABENE': The provider that produced it: `TRM_LABS` (wallet screening) or `NOTABENE` (Travel Rule data).
      - `provider_metadata_data` object: The raw provider payload: the wallet screening provider's response (provider internal URL fields removed) or the Notabene transfer record. Wallet screening covers all supported chains on which an address exists, so provider-defined fields such as entities[].entity can reference a chain other than the payment network.
    - `participants` object[], required: Participants Tesser identified in the flow of funds, with the record each was reconciled to.
      - `role` 'ORIGINATOR' | 'ORIGINATOR_VASP' | 'BENEFICIARY' | 'BENEFICIARY_VASP' | 'CUSTODY_SERVICE' | 'INTERMEDIARY_VASP' | 'CONTRACT': The participant's role in the flow of funds.
      - `resource` object: The record the participant was reconciled to and the reconciliation outcome.
        - `resource_type` 'COUNTERPARTY' | 'TENANT' | 'WORKSPACE' | 'ACCOUNT': The kind of record the participant was reconciled to: `COUNTERPARTY` (most common); `TENANT` (the sending or receiving wallet belongs to one of your tenants directly); `WORKSPACE` (one of your organization's own wallets); or `ACCOUNT` (the account holding a wallet address on your allowlist — see `risk_status_reason_type` = `ACCOUNT`).
        - `id` string, nullable: Identifier of the record the participant was reconciled to — a counterparty, tenant, workspace, or account ID, per `resource_type`.
        - `name_match_score` string, nullable: The name-match score, 0–100. Null where no name matching applied.
        - `name_match_threshold` string, nullable: The lowest score that counts as a match; the comparison is inclusive, so a score equal to the threshold matches. Null where no name matching applied.
        - `name_match_comparison_id` string, nullable: ID of the record whose name most closely matched the supplied name — the record the score was computed against. Null where no name matching applied.
        - `resolution` 'EXACT_MATCH' | 'PARTIAL_MATCH' | 'DID_NOT_MATCH' | 'COUNTERPARTY_CREATED' | 'USER_SUPPLIED_ID': The reconciliation outcome.
    - `risk_reviewed_by` string, nullable: User ID who reviewed the risk.
    - `risk_reviewed_at` string, date-time, nullable: Timestamp when risk was reviewed.
    - `risk_review_reason` string, nullable: Reason the reviewer gave when approving or rejecting the payment. Null when none was given or the payment was not manually reviewed.
    - `balance_status` 'unreserved' | 'awaiting_funds' | 'reserved', nullable, required: Balance reservation status.
    - `balance_reserved_at` string, date-time, nullable, required: Timestamp when balance was reserved.
    - `steps` PaymentStep[], required: Payment execution steps.
      - `id` string, required: Unique step identifier
      - `payment_id` string, required: ID of the parent payment
      - `step_sequence` integer, required: Order of this step in the payment flow (1-based)
      - `step_type` 'transfer' | 'swap', required: Type of step
      - `estimated` PaymentStepEstimatedOverlay, required: Planned values for this step.
        - `from` PaymentStepEstimatedFromLeg, required: Source side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
        - `to` PaymentStepEstimatedToLeg, required: Destination side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
      - `actual` PaymentStepActualOverlay, required: Settled values once the step reaches `status: completed`. All-null until then; remains all-null on failure.
        - `from` PaymentStepActualFromLeg, required: Source side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
        - `to` PaymentStepActualToLeg, required: Destination side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
      - `transaction_hash` string, nullable: Blockchain transaction hash
      - `unsigned_transaction` string, nullable: Unsigned transaction bytes for client signing. Present only for Turnkey-signed steps in `signature_requested` status.
      - `fees` StepFee[], required: Fees associated with this step.
        - `fee_amount` string, required: Fee amount.
        - `fee_currency` string, required: Fee currency code.
        - `fee_type` string, required: Fee type (e.g., 'gas', 'provider', 'tesser_fee').
        - `fee_metadata` object: Additional metadata for the fee (JSON object).
      - `provider_key` 'capa' | 'circle_mint' | 'kraken' | 'openfx' | 'turnkey' | 'zuba', nullable: Provider used for this step
      - `status` 'created' | 'signature_requested' | 'signed' | 'submitted' | 'confirmed' | 'completed' | 'failed', required: Current status of this step
      - `status_reasons` StatusReason[], nullable: Reasons for the current status
        - `error_code` string, required
        - `error_message` string, required
      - `created_at` string, date-time, required: Step creation timestamp
      - `updated_at` string, date-time, required: Step last update timestamp
      - `signature_requested_at` string, date-time, nullable: Timestamp when a signature was requested for the step
      - `signed_at` string, date-time, nullable: Timestamp when the step was cryptographically signed
      - `submitted_at` string, date-time, nullable: Timestamp when step was submitted
      - `confirmed_at` string, date-time, nullable: Timestamp when step was confirmed
      - `completed_at` string, date-time, nullable: Timestamp when step completed
      - `failed_at` string, date-time, nullable: Timestamp when step failed
    - `created_at` string, required: ISO 8601 timestamp of creation.
    - `updated_at` string, required: ISO 8601 timestamp of last update.
    - `expires_at` string, date-time, nullable, required: ISO 8601 timestamp when the payment expires.

## Other responses

- `202`: The on-chain transfer was broadcast but the inbound was not detected and screened within the wait budget. Once payment_id is present, poll GET /v1/payments/{paymentId} for the screened payment.

---

[API](https://skmtc.dev/tesser/apis/tesser-api.md) - [All operations](https://skmtc.dev/tesser/apis/tesser-api/llms.txt) - [OpenAPI document](https://skmtc.dev/tesser/apis/tesser-api/revisions/14f951e986b1?raw)
