Screening
Address risk, traces and on-chain transaction inspection.
Jump to an operation:
List the caller's past screenings — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: unavailable
Callers business key, agent. Test mode fixture addresses.
query Parameters
limitDefault 25. Out of range is never rejected: a value outside 1..100, a fraction, or a non-number is not a 400 — 0, a negative number, a non-integer or anything non-numeric falls back to the default (25); anything above 100 is capped to 100. A documented clamp, not a silent one; minimum/maximum are deliberately absent from this schema so a generated client (the MCP tool included) does not reject a value the API itself accepts.
cursorOpaque cursor from a previous response's next_cursor.
Headers
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
List the caller's past screenings — available › Responses
A page of screenings.
has_morenext_cursorA1-2: required (still nullable) — every producer already emits null rather than omitting the field when there is no next page, so this only removes a third, unused wire state (absent) a strict client had to handle for nothing.
Screen one address before sending funds — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.write· Test mode: unavailable
Runs a free risk screen on one address and chain — unmetered by design (matches prod: guard.check has never spent a credit; only screenings.reports.create's full report does, D-84, which for a business key spends the account owner's own credit balance — see that operation). The result is a signal, never a verdict — action is a suggestion, never an authorization. The account-scoped api_screenings row stores the address itself (case-preserved, never a hash) so it can be listed back and embedded in address_book; it is never shared across accounts. chain must name a network screening covers (ScreeningCreateRequest.chain); any other value, or an address that cannot exist on that network, is refused 409 network_not_supported before any check runs or any row is written — never screened as Ethereum. Do not call this for a transaction hash — use GET /v1/transactions/{chain}/{hash} — and never chain action straight into a transfer without a human in the loop. Callers: business key, agent. Test mode: fixture addresses.
Headers
Idempotency-Key^[A-Za-z0-9_-]{16,12… · requiredCaller-generated, 16-128 characters of [A-Za-z0-9_-] (a UUID or a base64url token both qualify). The value is part of a primary key, so the shape is enforced, not advisory: outside it the request is 400 invalid_request/idempotency_key_invalid. A replay within 24 hours returns the stored response; a different body under the same key is idempotency_error; a replay of a request that failed after it may have taken effect is 409 idempotency_failed — reconcile, then retry under a NEW key. After 24 hours the key is forgotten and the request is new (D-108).
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Screen one address before sending funds — available › Request Body
addressCase-preserved verbatim — never lowercase a BTC, Tron or Solana address.
chainThe network to screen on, by chain id or name, case-insensitive: Ethereum (1, eth), BNB Chain (56, bsc), Polygon (137), Arbitrum (42161), Optimism (10), Base (8453), Avalanche (43114), bitcoin, tron, solana, xrp (XRP Ledger), ton, cardano, cosmos. Any other value — blank, tempo, litecoin — whatever the address, and an address that cannot exist on the named network (an EVM address on bitcoin, a Bitcoin address on tron) are refused 409 network_not_supported; nothing is ever screened as Ethereum by default. An address is judged by the named network's own address format; on solana that is any base58 string of 32–44 characters.
Screen one address before sending funds — available › Responses
The screening.
id^scr_ · requiredPrefixed, opaque. The prefix is part of the contract; the suffix is never parsed.
objectlivemodecreated_ataddressCase-preserved verbatim.
chainrisk_scorerisk_levelverdictDerived, coarser than risk_level. Still a signal, never a block decision.
actionA suggestion the caller may act on — never an authorization by itself.
cachedscreened_atupdated_atflagsFree-form, source-shaped detail — never re-typed per source.
confidencecoverageThe sources actually checked, so a client can see what was not.
provider_versionRead one screening by id — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: unavailable
Callers business key, agent. Test mode fixture addresses.
path Parameters
id^scr_ · requiredHeaders
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Read one screening by id — available › Responses
The screening.
id^scr_ · requiredPrefixed, opaque. The prefix is part of the contract; the suffix is never parsed.
objectlivemodecreated_ataddressCase-preserved verbatim.
chainrisk_scorerisk_levelverdictDerived, coarser than risk_level. Still a signal, never a block decision.
actionA suggestion the caller may act on — never an authorization by itself.
cachedscreened_atupdated_atflagsFree-form, source-shaped detail — never re-typed per source.
confidencecoverageThe sources actually checked, so a client can see what was not.
provider_versionList the reports run on one screening — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: unavailable
Callers business key, agent. Test mode fixture addresses.
path Parameters
id^scr_ · requiredquery Parameters
limitDefault 25. Out of range is never rejected: a value outside 1..100, a fraction, or a non-number is not a 400 — 0, a negative number, a non-integer or anything non-numeric falls back to the default (25); anything above 100 is capped to 100. A documented clamp, not a silent one; minimum/maximum are deliberately absent from this schema so a generated client (the MCP tool included) does not reject a value the API itself accepts.
cursorOpaque cursor from a previous response's next_cursor.
Headers
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
List the reports run on one screening — available › Responses
A page of reports.
has_morenext_cursorA1-2: required (still nullable) — every producer already emits null rather than omitting the field when there is no next page, so this only removes a third, unused wire state (absent) a strict client had to handle for nothing.
Generate the full report and evidence PDF — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.write· Test mode: unavailable
Spends 1 credit unless an equivalent report for this address was generated within the last 30 days, in which case the cached report is returned at no cost (cached: true). No account-level credit ledger exists yet (D-82) — a business-key call spends the account's OWNER member's own personal credit balance (resolveBillingUserId), the same balance GET /v1/credits reads. Callers: business key, agent. Test mode: fixture addresses.
path Parameters
id^scr_ · requiredHeaders
Idempotency-Key^[A-Za-z0-9_-]{16,12… · requiredCaller-generated, 16-128 characters of [A-Za-z0-9_-] (a UUID or a base64url token both qualify). The value is part of a primary key, so the shape is enforced, not advisory: outside it the request is 400 invalid_request/idempotency_key_invalid. A replay within 24 hours returns the stored response; a different body under the same key is idempotency_error; a replay of a request that failed after it may have taken effect is 409 idempotency_failed — reconcile, then retry under a NEW key. After 24 hours the key is forgotten and the request is new (D-108).
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Generate the full report and evidence PDF — available › Responses
The report — freshly generated or served from the 30-day cache.
id^rpt_ · requiredPrefixed, opaque. The prefix is part of the contract; the suffix is never parsed.
objectlivemodecreated_atcachedTrue when this report was served from the 30-day cache rather than spending a fresh credit.
updated_atRead one full screening report — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: unavailable
Callers business key, agent. Test mode fixture addresses.
path Parameters
id^scr_ · requiredreport_id^rpt_ · requiredHeaders
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Read one full screening report — available › Responses
The report.
id^rpt_ · requiredPrefixed, opaque. The prefix is part of the contract; the suffix is never parsed.
objectlivemodecreated_atcachedTrue when this report was served from the 30-day cache rather than spending a fresh credit.
updated_atDownload a report's evidence PDF — planned
Status: Planned — not built yet · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: fixturesThis operation is planned — not built yet. It is documented for the contract it will carry, but it does not run today. Never call it expecting a live result.
Returns the generated PDF only when evidence_pdf.available is true on the report — a 404 otherwise, never an empty 200. Callers: business key, agent. Test mode: fixture addresses.
path Parameters
id^scr_ · requiredreport_id^rpt_ · requiredHeaders
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Download a report's evidence PDF — planned › Responses
The PDF.
Follow where a transaction's funds moved — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.write· Test mode: unavailable
Starting from one origin transaction hash, follows value across hops and names the counterparties reached. Slow and expensive relative to a screening — call it after check_address_risk returns high or critical, not before; on a clean address it tells you nothing new. Takes a transaction hash, not a bare address — an address alone has no single flow to follow; use the incident transaction (e.g. the transfer that sent funds to a scammer). Callers: business key, agent. Test mode: fixture addresses.
Headers
Idempotency-Key^[A-Za-z0-9_-]{16,12… · requiredCaller-generated, 16-128 characters of [A-Za-z0-9_-] (a UUID or a base64url token both qualify). The value is part of a primary key, so the shape is enforced, not advisory: outside it the request is 400 invalid_request/idempotency_key_invalid. A replay within 24 hours returns the stored response; a different body under the same key is idempotency_error; a replay of a request that failed after it may have taken effect is 409 idempotency_failed — reconcile, then retry under a NEW key. After 24 hours the key is forgotten and the request is new (D-108).
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Follow where a transaction's funds moved — available › Request Body
hashThe origin transaction hash to trace forward from (the incident transfer, e.g. the transaction that sent funds to a scammer) — a trace always starts from a specific transaction, never a bare address, since an address alone has no single "flow" to follow.
chainFollow where a transaction's funds moved — available › Responses
The trace.
id^trc_ · requiredPrefixed, opaque. The prefix is part of the contract; the suffix is never parsed.
objectlivemodecreated_atupdated_atInspect one on-chain transaction — available
Status: Available · Callers: business key, agent (business key), dashboard session · Scope:
screenings.read· Test mode: unavailable
Reads one on-chain transaction by hash: amounts, transfers, both sides, and a short risk brief on each counterparty. Use screenings.create for an address and orders.get for a Swaps order — this is neither. Callers: business key, agent. Test mode: fixture addresses.
path Parameters
chainhashHeaders
Swaps-VersionPins behaviour within /v1 to a dated version; defaults to the key's version; echoed on every response.
Swaps-AccountA1-2. Selects which of the caller's account memberships this request acts on, by Account.id (acct_…), when the credential can reach more than one; the caller's default account otherwise (D-109, supabase/functions/api-v1/auth.ts). Declared on every operation a dashboard session can call (#3561: the runtime caller class, not the formal security list, which names only businessKey on operations both credential classes reach). A value the session is not a member of answers 404 not_found. A business key already resolves to exactly one account (its own) and ignores this header.
Inspect one on-chain transaction — available › Responses
The transaction.
chainhashA short risk brief on each side of the transaction.