# Simulate a Policy Set on Your History

What a set would have decided on your tenant's past operations, at each operation's own time. Changes nothing.

## Overview

- Any version — a draft too. `days`: the window, default 30, at most 90. `limit`: the newest operations evaluated, default 2000, at most 5000; `operations.truncated` says the window held more (`truncatedBy` `limit`), or that the evaluation stopped at its time budget (`deadline`).
- **What it reads**, newest first (`operations.bySource`): transactions sent from custodial wallets, transactions prepared for client-side and MPC wallets, gasless permits, Earn operations, and recorded [operations](https://docs.aureahub.com/docs/guide-operations.md) that have none of those.
- **Amounts** in EUR from the token prices Aurea keeps; a signature whose token or price is not known stays unpriced (`amounts.unpriced`), and the rules treat its amount as missing. A rolling window's total and screening results are not known to a simulation.
- **Your address book**: when the set names the destination kind `address_book` and your [address book](https://docs.aureahub.com/docs/guide-address-book.md) is read at the signing points (every tenant's today), each signature's destination is read in the book **as it is now** — an active entry for that chain and wallet, or not — and `addressBook` counts them — e.g. `"addressBook": { "listed": 377, "notListed": 35 }`, beside `amounts`. Absent otherwise: `address_book` then matches no destination.
- **Results** under your tenant's profile (`results.tenant`) and under the institutional profile's defaults (`results.institutional`): counts per verdict, per rule (`matched`, and up to 10 operations as `{ source, id }`), for operations no rule decided (`defaultDecision`), and how many operations each reason was given for (`missing:<field>`, `possible-match:<position>`, `explicit-rule-required:<TYPE>`, `rule-matched`, `no-matching-rule`).
- At most **10 a minute**. `503` `POLICY_SIMULATION_TIMEOUT` when the history cannot be read in time: simulate a shorter window or fewer operations.

## Endpoint

### `POST /v1/policy-sets/{setId}/simulate`

Authentication: bearer token required.

Evaluates a policy set on the tenant's past operations.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `setId` | string | yes | The set's id |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `days` | integer | no | 1–90, default 30 |
| `limit` | integer | no | 1–5000, default 2000 |

**Responses**

`200` OK

```json
{
  "policySetId": "4c8a1e5f-9b2d-4e73-a6c0-1d7f3b9e2a58",
  "policySetVersion": 3,
  "policySetStatus": "draft",
  "tenantProfile": "legacy",
  "window": { "from": "2026-09-06T12:15:00.000Z", "to": "2026-10-06T12:15:00.000Z", "days": 30 },
  "limits": { "maxOperations": 2000, "samplePerRule": 10, "readBudgetMs": 5000, "evaluationBudgetMs": 10000 },
  "operations": {
    "read": 412,
    "evaluated": 412,
    "truncated": false,
    "truncatedBy": null,
    "bySource": { "custodial_transaction": 301, "prepared_transaction": 99, "gasless_permit": 12, "earn_operation": 0, "operation": 0 }
  },
  "amounts": { "referenceCurrency": "EUR", "priced": 398, "unpriced": 14 },
  "results": {
    "tenant": {
      "profile": "legacy",
      "verdicts": { "ALLOW": 410, "SCREEN": 0, "REQUIRE_APPROVAL": 0, "BLOCK": 2, "FREEZE": 0 },
      "rules": [
        {
          "ruleId": "e2b6d9f1-7a3c-4c58-8b0e-5f1a4d2c9b73",
          "position": 0,
          "name": "No contract deployments",
          "verdict": "BLOCK",
          "matched": 2,
          "sample": [
            { "source": "custodial_transaction", "id": "9a4c2e7b-1d5f-4b83-a0e6-3c8d1f5b7e29" },
            { "source": "prepared_transaction", "id": "2e7b5d1a-8c3f-4e96-b4a0-6d1c9f3e5b82" }
          ]
        }
      ],
      "defaultDecision": { "verdict": "ALLOW", "matched": 410, "sample": [] },
      "reasons": { "rule-matched": 2, "no-matching-rule": 410 }
    },
    "institutional": {
      "profile": "institutional",
      "verdicts": { "ALLOW": 0, "SCREEN": 0, "REQUIRE_APPROVAL": 0, "BLOCK": 412, "FREEZE": 0 },
      "rules": [
        {
          "ruleId": "e2b6d9f1-7a3c-4c58-8b0e-5f1a4d2c9b73",
          "position": 0,
          "name": "No contract deployments",
          "verdict": "BLOCK",
          "matched": 2,
          "sample": [
            { "source": "custodial_transaction", "id": "9a4c2e7b-1d5f-4b83-a0e6-3c8d1f5b7e29" },
            { "source": "prepared_transaction", "id": "2e7b5d1a-8c3f-4e96-b4a0-6d1c9f3e5b82" }
          ]
        }
      ],
      "defaultDecision": { "verdict": "BLOCK", "matched": 410, "sample": [] },
      "reasons": { "rule-matched": 2, "no-matching-rule": 410 }
    }
  }
}
```

The example's `sample` lists of the default decision are shortened to `[]`; they hold up to 10 operations like the rules' samples.

---

Web version: https://docs.aureahub.com/#policy-set-simulate
