# Add a policy for an automatic release of quarantined transfers ![Beta](/assets/beta-label.9b17384c64e8fb7cb732f95290c8a2c0d60692664b94277dc09c2c605b8b07a9.93c15c9d.png)

Quarantined transfers need a policy that automates the release of quarantined transfers on child domains.

Note:
Alternatively, you can add a policy for manually releasing quarantined transfers. For more information, see [Add a policy for a manual release of quarantined transfers](/pt-br/products/custody/compliance/transaction-screening/manual-quarantine-release-policy).

To add a policy for automatically releasing quarantined transfers in your Elliptic or Chainalysis integration, complete these steps:

1. In the left navigation, select **Integrations**, and on the tile for your compliance solution provider, select **Configure**.
2. In the Integration window, next to **Add policy for automatic release of quarantined transfers**, select **Start**.
The **Add a policy for automatic release of quarantined transfers** window opens, displaying your previously configured risk scores.
*Example using Elliptic integration*
![Policy automatic release quarantined transfers](/assets/policy-automatic-release-quarantined-transfers.a6c59247c9ae44ea1dece1d50a6c3ef5085b372d8ab0d67e4d0c4243ff6fc969.93c15c9d.png)
3. In the **Policy name** field, change the name to a unique name of your choosing.
4. In the **Role** fields, select the amount of users and the role type from the drop-down list, for example **1** and **Admin**.
5. If you want two or more different role types to be required for approving quarantine releases, select the **AND** condition. If you want either the role you already defined or another role to be required for approving quarantine releases, select **OR**.
6. Repeat step 4, for example **1** and **Compliance manager**.
7. *Optional:* If you wish to set up additional conditions that must be met for the approval of quarantined releases workflow, select **Add condition** and repeat step 4.
8. When you're done adding all conditions, select **Submit for approval**.
9. On your security device or the desktop app, sign the operation. For more information, see [Sign intents](/pt-br/products/custody/identity-and-access/authentication/ui-authentication#sign-ui-operations).


## Automate release with the SDK

The policy governs who approves the release of quarantined transfers. Each release is still a `v0_ReleaseQuarantinedTransfers` intent that someone must submit. To submit release intents from your own service, use the `QuarantineReleaseAgent` in the SDK.

The agent lists the quarantined transfers in each domain that it scans. It submits one release intent for the custody account that holds the funds: the recipient account for an incoming transfer, or the sender account for an outgoing transfer. It skips transfers that it has already released, and an error on one transfer doesn't stop the others.

Scope the client to the compliance domain
The agent submits release intents as the user that its configuration authenticates as. If the quarantined accounts are in subdomains of the compliance domain, configure that user in the compliance domain. If the user belongs to the root domain, release intents for those subdomains fail with an `UnauthorizedException`.

The SDK examples assume a configured client. See [Integrate via SDK](/pt-br/products/custody/get-started/integrate-via-sdk). The following examples run the agent:

TypeScript
The TypeScript agent takes a configuration rather than a client. Omit `domainIds` to scan the root domain and every domain that the configured user can see.

```typescript
import {
  QuarantineReleaseAgent,
  loadConfiguration,
} from '@ripple/ripple-custody-client-lib-typescript';

const agent = new QuarantineReleaseAgent({
  config: loadConfiguration(),
  domainIds: [domainId],
  pollIntervalMs: 10_000,
  onRelease: (r) => console.log(`Released ${r.transferId}`),
  onError: (transferId, error) => console.error(transferId, error.message),
});

agent.start();
// On shutdown:
await agent.stop();
```

To run a single scan instead of polling, call `await agent.run()`. It returns the transfers released in that pass.

Java
The Java agent has no background loop. Each call to `releasePendingQuarantines` scans one domain, submits the release intents, and waits for them to execute. By default, each call has a budget of 60 seconds. The method returns the number of releases that completed. The agent doesn't resubmit a release that's still waiting for approval. The next call checks it again. Call the method on your own schedule.

```java
import com.ripple.custody.QuarantineReleaseAgent;
import com.ripple.custody.errors.CustodyError;

QuarantineReleaseAgent agent = new QuarantineReleaseAgent(client.getConfig());

while (running) {
    try {
        int released = agent.releasePendingQuarantines(domainId);
    } catch (CustodyError e) {
        // A release was rejected, failed, or expired. The next call retries it.
    }
    try {
        Thread.sleep(10_000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        break;
    }
}
```

Python
Omit `domain_ids` to scan the root domain and every domain that the client can see.

```python
from ripple_custody_client_lib_python import QuarantineReleaseAgent

agent = QuarantineReleaseAgent(
    client,
    domain_ids=[domain_id],
    poll_interval=10.0,
    on_release=lambda r: print(f"Released {r.transfer_id}"),
    on_error=lambda transfer_id, exc: print(transfer_id, exc),
)

agent.start()  # Polls in a background thread.
# On shutdown:
agent.stop()
```

To run a single scan instead of polling, call `agent.poll_once()`. It returns the transfers released in that pass. You can also use the agent as a context manager, which starts polling on entry and stops on exit. For asyncio code, use `AsyncQuarantineReleaseAgent` with `AsyncCustodyClient`.

By default, the TypeScript and Python agents record a transfer as released as soon as they submit the release intent. To record it only after the intent executes, set `waitExecuted: true` (TypeScript) or `wait_executed=True` (Python).

For a complete program, see example `32` (quarantine release agent). To get the examples, see [Examples](/pt-br/products/custody/developer-experience/sdks#examples).