# Managing Targets
Source: https://docs.chain.link/ace/guides/policy-manager/manage-targets
Last Updated: 2026-09-23

> For the complete documentation index, see [llms.txt](/llms.txt).

A **target** is a smart contract protected by ACE and associated with a Policy Engine. ACE can detect a target from its onchain attachment to the engine, or you can register it through the Coordinator API. Once the target appears under the engine, you can configure its [default policy result](#default-allow-behavior) and attach [policy instances](/ace/guides/policy-manager/manage-policies) to its functions through [protections](/ace/guides/policy-manager/manage-protections).

> **NOTE**
>
> Before adding a target, connect the contract to a [deployed Policy Engine](/ace/guides/policy-manager/manage-engines).
> Most contracts inherit `PolicyProtected` and use the `runPolicy` modifier. A contract can also call the Policy Engine
> directly and call `attach()` when it connects, as `AdvancedPoolHooks` does. See [Making Your Contract
> ACE-Compatible](/ace/guides/policy-manager/contracts/ace-compatible) for both integration paths.

## Register a target

When a contract calls `PolicyEngine.attach()`, ACE detects the onchain attachment and creates a target automatically.

If ACE does not detect your integration, register the target with a `POST` request. Provide the contract name, type, protected methods, and onchain addresses:

```bash
curl -X POST https://ace.api.chain.link/v1/targets \
  -H "Content-Type: application/json" \
  -H "Authorization: Apikey <API_KEY>" \
  -d '{
    "title": "My ERC-20 Token",
    "description": "Production ERC-20 token with compliance enforcement",
    "policy_engine_id": "<POLICY_ENGINE_ID>",
    "protected_methods": [
      "transfer(address,uint256)",
      "transferFrom(address,address,uint256)"
      #[any other methods you want to protect]
    ],
    "desired_default_allow": true,
    "metadata": {"contract_type": "ERC-20"},
    "onchain_targets": [
      {
        "chain_selector": "16015286601757825753",
        "address": "0xYourContractAddressOnSepolia"
      },
      {
        "chain_selector": "3478487238524512106",
        "address": "0xYourContractAddressOnArbitrumSepolia"
      },
      #[any other chains where your contract is deployed]
    ]
  }'
```

| Field                   | Required | Description                                                   |
| ----------------------- | -------- | ------------------------------------------------------------- |
| `title`                 | Yes      | Human-readable name for the target                            |
| `description`           | No       | Description of the contract                                   |
| `policy_engine_id`      | Yes      | UUID of the policy engine to associate with                   |
| `protected_methods`     | No       | Array of function signatures that can be protected            |
| `contract_type_ids`     | No       | Array of contract type UUIDs the target implements            |
| `desired_default_allow` | No       | Whether to allow transactions by default (default: `true`)    |
| `onchain_targets`       | No       | Array of objects with `chain_selector` and contract `address` |
| `metadata`              | No       | Arbitrary JSON metadata (e.g., `{"contract_type": "ERC-20"}`) |

## Default allow behavior

The **default policy result** controls what happens when a transaction passes through the entire policy chain and no policy explicitly returns Allow or Reject (i.e., every policy returns Continue). This is configured per target contract via the `desired_default_allow` field:

- **`true` (default)** — The transaction is allowed. This is appropriate when you want policies to act as blockers (reject specific cases), and everything else passes through.
- **`false`** — The transaction is rejected. This is appropriate for allowlist-style enforcement where only explicitly approved transactions proceed.

For more on how policy evaluation ordering works, see [Policy Ordering & Composition](/ace/concepts/policy-ordering#the-default-result).

### Change the default policy result

## View targets

## Update a target

You can update a target's name, description, contract type, protected methods, default allow behavior, and on-chain addresses.

> **CAUTION: PUT is a full replacement**
>
> The `PUT /targets/{id}` endpoint **replaces the entire resource** — any field you omit is reset to its default (empty
> string, empty array, or `true` for `desired_default_allow`). Always include every field you want to keep, not just the
> ones you are changing.

## Link targets

When a contract attaches to a Policy Engine on a new chain, the control plane creates a separate **detected target** (titled "unknown target"). Rather than managing each chain deployment as its own target, you can **merge** detected targets into an existing target to keep a single multi-chain target with all its onchain addresses in one place.

### Conditions

A detected target can be merged (linked) into an existing target when:

- The detected target was auto-discovered — it still has the default "unknown target" title.
- The detected target has at least one on-chain address.
- A valid destination target exists in the same policy engine: it must be a different target, already named, and deployed on a **different chain** than the source (no shared chain selectors).

If no valid destination exists, the detected target cannot be merged — you can only rename it via **Edit details**.

### How it works

Merging transfers the on-chain addresses from the source target(s) to the destination target, then archives the sources. After the merge, the destination target contains all chain deployments and any protections remain on the destination.

> **CAUTION**
>
> Merging is irreversible. The source targets are archived and their on-chain addresses become part of the destination
> target. Make sure you select the correct destination before confirming.

## Archive a target

Archiving a target removes it from active use. All target protections associated with the target must be archived first.

> **CAUTION**
>
> All target protections must be archived before the target itself can be archived. See [Protecting Target
> Functions](/ace/guides/policy-manager/manage-protections) for how to archive protections.

## Related pages

- [Making Your Contract ACE-Compatible](/ace/guides/policy-manager/contracts/ace-compatible) — how to integrate `PolicyProtected` into your contract
- [Managing Policy Engines](/ace/guides/policy-manager/manage-engines) — create the engine your target will use
- [Managing Policies](/ace/guides/policy-manager/manage-policies) — create policy instances to attach to your target
- [Protecting Target Functions](/ace/guides/policy-manager/manage-protections) — attach policies to specific functions on your target
- [Coordinator API Reference](/api/ace/coordinator/docs) — full API schema