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

# Policy Engine

> Layered spend controls, velocity limits, and approval workflows

# Policy Engine

Every transaction passes through Amrood's policy engine before execution. Policies are layered — each layer can only be **more restrictive** than the one above it.

## Policy Hierarchy

```mermaid theme={null}
flowchart TD
    A["Admin Tier Defaults"] --> B["Owner Policy Override"]
    B --> C["Agent Policy"]
    C --> D["Transaction Evaluated"]
```

1. **Tier Defaults** — set by Amrood admin per tier (sandbox, tier1, tier2, tier3)
2. **Owner Override** — account holder can tighten their own limits
3. **Agent Policy** — per-agent rules for fine-grained control

The tightest limit always wins. An owner cannot exceed tier limits. An agent cannot exceed owner limits.

## Tier Defaults

| Tier    | Per-Tx Limit | Daily Limit | Monthly Limit | Escrow Above | Approval Above |
| ------- | ------------ | ----------- | ------------- | ------------ | -------------- |
| sandbox | ₹1,000       | ₹10,000     | ₹1,00,000     | ₹500         | ₹5,000         |
| tier1   | ₹5,000       | ₹50,000     | ₹5,00,000     | ₹2,500       | ₹25,000        |
| tier2   | ₹25,000      | ₹2,50,000   | ₹25,00,000    | ₹10,000      | ₹1,00,000      |
| tier3   | ₹1,00,000    | ₹10,00,000  | ₹1,00,00,000  | ₹50,000      | ₹5,00,000      |

## Agent Policy Controls

Set per-agent policies via your platform:

```bash theme={null}
# Policies are set on agent creation or via PATCH
curl -X PATCH https://api.amrood.io/v1/agents/agt_xxx \
  -H "x-platform-id: plt_xxx" \
  -H "x-platform-secret: sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "spend_limit_per_tx": 500,
    "spend_limit_daily": 5000,
    "allowed_payees": ["network"]
  }'
```

### Available Controls

| Control                        | Description                                |
| ------------------------------ | ------------------------------------------ |
| `spend_limit_per_tx`           | Max INR per single payment                 |
| `spend_limit_hourly`           | Max INR per rolling hour                   |
| `spend_limit_daily`            | Max INR per day                            |
| `spend_limit_monthly`          | Max INR per calendar month                 |
| `blocked_payee_agents`         | Agent IDs that cannot receive payments     |
| `per_counterparty_daily_limit` | Max INR to any single counterparty per day |
| `max_counterparties_per_hour`  | Max unique recipients per hour             |
| `require_escrow_above`         | Force escrow for amounts above this        |
| `require_human_approval_above` | Require owner approval above this          |

## Policy Decisions

When a transaction is evaluated, the engine returns one of four decisions:

| Decision               | What Happens                        |
| ---------------------- | ----------------------------------- |
| **approved**           | Transaction proceeds normally       |
| **denied**             | Transaction blocked with reason     |
| **escrow\_required**   | Must use escrow endpoint instead    |
| **approval\_required** | Owner must approve before execution |

## Human Approval Workflow

When a payment exceeds the approval threshold, it enters a pending state:

```json theme={null}
{
  "payment_id": null,
  "status": "pending_approval",
  "approval_id": "apr_xyz789"
}
```

The account holder sees pending approvals and can approve or reject:

```bash theme={null}
# Approve
POST /v1/approvals/apr_xyz789/approve

# Reject
POST /v1/approvals/apr_xyz789/reject
```

Approvals expire after 24 hours if not acted upon.

## Velocity Tracking

All velocity limits are tracked in real-time using Redis counters:

* **Hourly** — rolling 1-hour window
* **Daily** — rolling 24-hour window
* **Monthly** — calendar month
* **Per-counterparty** — daily limit per unique recipient

## Cooldown on Limit Changes

When spending limits are **increased**, a cooldown period (default 24 hours) applies before the new limits take effect. This prevents compromised accounts from immediately raising limits and draining funds.
