Prerequisites
- A screening policy saved at least 60 seconds ago.
- An API token. Screening needs the
environment.settings.readpermission and reading events needsenvironment.events.read. See API token permissions.
Validate in a separate environment first
Policies belong to one environment, so a sandbox environment gives you a place to save and test a change before it reaches your live users. Validate the change there, then make the same change in your live environment.- Sandbox needs a screening provider key stored on the environment, and screening policies must be enabled for it. See the prerequisites for configuring a policy. You can store the same key you use in live, which makes the provider return the same results for the same address in both environments.
- Make the identical change in the live environment by hand in the editor, or by reading the policy from sandbox and writing the same rules to live through the API. Address exceptions belong to the provider in each environment, so add them again in live.
- Confirm the result in live afterward with the checks below. If sandbox uses a different provider key than live, the provider can return different results for the same address.
Screen a test address
GET /environments/{environmentId}/wallet/sanctions is the same screening as GET /sdk/{environmentId}/wallet/sanctions, described in Screening policy rules, called with an API token. Use scope to choose the sign-in policy or the transaction policy, and screen once for each policy you edited. Send amountUsd and asset to exercise an amount threshold:
action is allow, alert, or block, and an action of alert leaves isBlocked false. Screening an address through this endpoint emits the same events as any other surface, with an origin of api. Compare the result with what you expect:
Which address you test with depends on what you are validating.
- The simplest check: an address exception. Add an address exception that blocks a wallet you control, set Applies to to the policy you are testing, and screen that wallet. You get a block with
reason.matchedofaddressand awallet.addressScreening.blockedevent, without depending on any provider data or affecting anyone else. This confirms that screening and event delivery work end to end, not that your rules match. Remove the exception when you finish. - A rule, in sandbox. If you have a test address with transaction history that your provider returns categories for, save a rule in sandbox that blocks one of the categories the address falls under, then screen the address and confirm the block. Whether an address matches a rule depends on what your screening provider returns for it, and that can differ between provider accounts, so use an address you have already seen your provider flag in that category, at or above the rule’s risk level.
- An amount threshold. Pass
amountUsdandassetin the request. A sign-in has no amount, so a threshold with an amount cannot be tested on the Sign-in policy.
Confirm the event
An alert or a block emits an event, and an allowed address emits none. The event carries areason that names the layer that decided. For a match on one of your rules, reason.rule is the rule exactly as it was evaluated, so you can confirm that the rule you intended decided and not another one above it. This is how you catch the overlap described in put the rules in order. See Policy and screening webhooks for every field.
Review past alerts and blocks
Dynamic records the events whether or not a webhook subscribes to them, and the Events API returns them, so you can review what a policy has done without having been listening at the time.GET /environments/{environmentId}/events returns the events your policies emitted. Send both dates to cover more than one day:
cursor. Each event has the data of the matching webhook event, described in Policy and screening webhooks:
- Filter by event name.
resourceTypematches the start of the event name.wallet.addressScreening, as in the request above, returns both your alerts and your blocks. Usewallet.addressScreening.alertedfor alerts alone,wallet.sanctionsfor blocks by the sanctions baseline, andadmin.addressScreening.policyfor changes to your policies, so you can line a change in behavior up with the edit that caused it. - Choose the days.
startDateandendDatetake UTC dates in the form2026-10-07. A request withoutstartDatereturns only today’s events, and a request withstartDateand noendDatereturns only that day, so send both to cover a range.startDatecan be at most 30 days ago and a range can span at most 30 days. Events are kept for 90 days in live environments and 30 days in sandbox, but the Events API does not read further back than 30 days. - Page through the results. A page holds 50 events, newest first. Send the
cursorfrom a response as thecursorquery parameter of your next request, and stop when a response has none. - Filter on the payload yourself. Only
resourceTypeand the dates filter the results. To narrow byorigin,chain,walletAddress, orreason.category, read each event’sdataand filter in your own code. - Expect alerts and blocks only. An allowed address emits no event, so the history never lists a screen that passed.
- Run a new rule as an alert first. Set the action to Alert, let real traffic run for a while, then read the
wallet.addressScreening.alertedevents. If the rule alerts on addresses you did not expect, narrow it before you switch it to Block. - Confirm a change took effect. After a save, events carry the policy’s new
reason.revision. Compare it with therevisionthe policy read returns. Events that still carry the old value were decided before the change went live. - Look for a block you did not intend. A block on a legitimate address is visible as a
wallet.addressScreening.blockedevent with the rule that caused it inreason.rule. Usereason.matchedto tell a rule from an address exception.