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

# Manage a shared policy

> V3 Directory routes for DID, Persona, and Application policies

These routes are available on the USE2 OpenDispatch Directory with the production spec 123 chain.

| Method and path | Result |
| - | - |
| `GET /policies/v3/{scope}/{id}` | Finalized V3 policy and scope, or `404` |
| `GET /policies/v3/{scope}/{id}/nonce` | Current owner DID and V3 policy nonce |
| `PUT /policies/v3/{scope}/{id}` | Submit a complete policy replacement; `202` means accepted for processing |
| `DELETE /policies/v3/{scope}/{id}` | Submit a policy removal; `202` means accepted for processing |

`scope` is `did`, `persona`, or `application`. URL-encode the complete `id`. A DID scope belongs to that DID. A Persona scope belongs to its active operator DID. An Application scope belongs to the application's current `control_did`. An inactive or missing scope cannot accept a policy.

The `GET` response is `{ "scope": { ... }, "policy": { ... } }`. The nonce response is `{ "scope": { ... }, "operator_did": "...", "nonce": "..." }`. A missing policy returns `404`; a missing or inactive scope returns a corresponding error.

## Signed write request

```json theme={null}
{
  "action": "set_policy_v3",
  "policy": {
    "policy_id": "0x<deterministic-64-hex-id>",
    "scope": {"type": "APPLICATION", "id": "talaria"},
    "revision": 1,
    "operator_did": "did:openpayload:1111111111111111111111",
    "policy_ttl_seconds": 60,
    "ruleset": [
      {
        "id": "notify-on-cache",
        "priority": 100,
        "conditions": [{"type": "EventEquals", "value": "CacheStored"}],
        "action": {
          "type": "DeliveryPlan/v1",
          "entry_step": "notify",
          "steps": [{
            "id": "notify",
            "operation": "Send",
            "recipient_did": "did:openpayload:1111111111111111111111",
            "payload_template": {
              "action": "sendPush",
              "recipient": {"$from": "/event/message_recipient_did"}
            }
          }],
          "transitions": []
        }
      }
    ]
  },
  "nonce": "<current-v3-policy-nonce>",
  "valid_until": "<epoch-milliseconds>",
  "signer_key_id": "did:openpayload:1111111111111111111111#keys-1",
  "canonical_payload": "<base64-or-hex-SCALE-authorization>",
  "signature": "<base64-or-hex-ed25519-signature>"
}
```

The DID key identified by `signer_key_id` signs the exact SCALE authorization payload. The payload contains `operator_did`, the V3 operation (`SetPolicy` or `ClearPolicy`), the full policy or scope, the current owner nonce, `valid_until`, and `signer_key_id` in that order. For `DELETE`, use `action: "clear_policy_v3"` and omit `policy`. A successful submission increments the owner nonce. The policy revision is 1 on creation and the finalized revision plus one on replacement. Re-read finalized state after `202` to confirm activation.

See [shared policies and control actions](/concepts/policy-v3) for rule semantics, payload templates, and Call domain authorization.


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