> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Screening Policies

> Enforce your TRM Labs or Chainalysis rules in Dynamic, enforce policies on sign-in and transactions.

A screening policy sets what Dynamic does with your provider's signals. Map its categories, risk scores, and exposure to block, alert, or allow.

Without a policy, Dynamic blocks on sanctions matches only. A policy is how you act on everything else the provider reports.

<Note>
  Screening policies are in Beta and are enabled per environment. To enable them, contact us through [Slack or email](/docs/get-started/welcome#support-&-feedback).
</Note>

## What you need

Screening policies require [bring your own screening key](/docs/get-started/security/address-screening#bring-your-own-screening-key).

You must have the Admin role on the environment to author a policy.

## What a policy cannot do

A policy can only make screening stricter. These guarantees hold for every policy:

* The sanctions baseline is evaluated first, before every rule you write.
* The baseline is generated on every screen. It is never stored and never cached, and no policy and no API request can weaken it.
* The baseline your provider evaluates is that provider's own sanctions determination, not Dynamic's sanctions list. See [the sanctions baseline](/docs/get-started/security/address-screening#the-sanctions-baseline).
* Exempting an address excuses that address from your own rules and nothing more. A sanctioned address stays blocked.
* A policy cannot hold a request for human review. There is no review action. An alert proceeds.

## A sign-in policy and a transaction policy

A policy belongs to one environment and one screening provider, and it is either a sign-in policy or a transaction policy. Which one applies depends on where the address is screened:

| Policy | API value | Covers |
| - | - | - |
| Sign-in policy | `SIGN_IN` | sign-in, linking a wallet to an existing user, wallet connect |
| Transaction policy | `TRANSACTION` | wallet addresses involved in Embedded Wallets, Flow; transaction signing, the screening API |

When you screen an address yourself with the address screening endpoint, you choose which policy it evaluates. It uses the transaction policy unless you ask for the sign-in policy. Every other surface always uses the policy shown in the table above.

The sign-in policy and the transaction policy are separate decisions, so they are authored separately. Blocking a wallet at sign-in denies the user your application. Blocking the same wallet on a transaction denies one transfer. You can alert at sign-in and block on transactions, or screen only transactions and leave sign-in on the baseline alone.

Neither policy inherits from the other. Each has its own rules and its own revision.

## The two decisions a policy makes

### When to screen

The first phase decides which addresses are sent to the provider at all. It runs before the provider call, so it can only read what is known without a provider response: the address, the chain, the asset, and the USD amount.

* The two outcomes are screen and skip.
* If no rule matches, the address is screened.
* A skip skips the paid provider call only. Dynamic-managed screening runs in its place, so the address is still checked against Dynamic's own sanctions list.
* An address skipped here never reaches the second phase.

<Warning>
  A skip drops the provider's own sanctions and ownership blocks at that surface, because those are evaluated against the provider's response. Dynamic still checks every address against its own sanctions list.
</Warning>

### How to decide

The second phase reads the provider response and produces the verdict.

* **Block** rejects the request and sends `wallet.addressScreening.blocked`. At sign-in, Dynamic returns `403` and issues no JWT. On a transaction, the screening response reports the block and the transaction is not signed.
* **Alert** does not block. The request proceeds, and Dynamic sends `wallet.addressScreening.alerted`.
* **Allow** proceeds with no event.

For what the end user sees when an address is blocked, see [when an address is blocked](/docs/get-started/security/address-screening#when-an-address-is-blocked).

## Evaluation order

Rules are evaluated top to bottom and the first match wins. The order of the layers is fixed and is not configurable:

1. **The sanctions baseline.** Government-sanctioned addresses are blocked here.
2. **Address exceptions.** Blocked addresses first, then exempted addresses.
3. **Your rules**, in the order they are stored.
4. **The default.** An address that reaches the end of the list is allowed.

Your rules are stored exactly as you send them. Dynamic does not reorder, normalize, or rewrite them.

The API and the webhook payloads call the sanctions baseline the sanctions floor. In a screening reason, the layer that decided is reported as `floor`, `address`, `customer`, or `default`, matching the four layers above.

Order matters within your own rules. Two rules on different categories can both match one address, because one address can carry many signals. The earlier rule decides, so an alert rule placed above a block rule on the same address produces an alert.

A policy holds at most 200 rules per phase.

## Address exceptions

An address exception names one address and one chain, and either blocks it or exempts it.

* Exceptions belong to the provider, not to one policy. An exception applies to sign-in, to transactions, or to both.
* Blocked exceptions are evaluated before exempted ones.
* A skip never bypasses a blocked exception. If **When to screen** would skip an address you have blocked, Dynamic calls the provider anyway and the address is blocked.
* An exempted address is still blocked if it is sanctioned, because the baseline is evaluated above the exception list.
* Addresses are compared exactly as they appear on their chain. Base58 and Base32 chains are case significant.

## What each provider exposes

Provider vocabularies are not cross-normalized. You write rules in the provider's own terms.

**TRM Labs** reports a category, a risk type, and a numeric risk score per signal. Categories are matched case sensitively in the casing TRM publishes, such as `Mixer`. Risk types are `OWNERSHIP`, `COUNTERPARTY`, and `INDIRECT`.

**Chainalysis** reports a category, a risk level, and where the category appears. Categories are lowercased before matching, such as `darknet market`. Risk levels are ordered: `Low`, `Medium`, `High`, `Severe`. A category can appear as an address identification, as direct exposure, or as indirect exposure.

<Warning>
  Chainalysis exposure conditions require a Chainalysis key licensed for exposure data. Without that license, the provider does not return exposure signals, and a rule that reads them never matches.
</Warning>

## When both providers are configured

Each provider has its own policy and produces its own verdict. The most severe verdict wins: block over alert over allow.

## Amount conditions

An amount condition applies only where the USD value of the transaction is established. That is Flow, checkout transactions, and the explicit context accepted by the screening API.

* Amounts are not available on the transaction signing path.
* An amount whose currency is not established as USD is treated as unknown rather than converted.
* When the amount is unknown, a rule with an amount condition does not match, and evaluation moves on to the next rule. Every sign-in has an unknown amount.

## When screening fails

Screening fails open.

* If a provider call fails, the request proceeds. Sign-in and signing are not blocked by a provider outage.
* If the first phase fails, every address is screened.
* If a stored provider response cannot be read, Dynamic falls back to the verdict recorded with it.
* Dynamic does not notify you when a provider key stops working.

## How changes take effect

* A saved policy is live everywhere within 60 seconds. During that window, different Dynamic hosts can evaluate different versions of your rules. The sanctions baseline is never affected.
* A provider response is reused for 24 hours. Reused responses are re-evaluated against your current policy, so editing a policy changes the verdict on a cached response with no new provider charge.

## Where to author a policy

In the developer console, open [Fraud Protection](https://console.dynamic.xyz/dashboard/fraud-prevention), find **Bring Your Own Screening Key** under **Compliance Screening**, and select **Edit policy** on the **TRM Labs** or **Chainalysis** card. The editor is a page of its own, with a **Sign-in** tab for the sign-in policy and a **Transactions** tab for the transaction policy, and each tab saves on its own. For the full walkthrough, see [Configure a screening policy](/docs/policies/configure-a-screening-policy).

Conditions the policy editor cannot express are authored through the API. See [Screening policy rules](/docs/policies/screening-policy-rules) for the rule format, and the `ScreeningPolicies` endpoints in the [API reference](/docs/api-reference/overview).

## Advanced rules

The policy editor authors one rule shape: a provider category, where in the provider response that category has to appear, and one or more action steps on risk score and amount. A condition outside that shape is an advanced rule, and is authored through the API.

* The policy editor shows an advanced rule read-only, at its real position in the evaluation order, with a delete control.
* Saving from the policy editor does not rewrite an advanced rule and does not move it.
* An advanced rule does not disable the policy editor. The two surfaces coexist.

## Not included

Screening policies do not provide:

* a dry run against a draft policy, or an estimate of how many recent screens a rule would have changed
* an approval step before a policy goes live
* policies over Dynamic-managed screening, which keeps fixed sanctions-only behavior
* conditions over transaction history, such as velocity or transfer counts over a time window
* amount conditions on the transaction signing path


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.