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

# POST /api/policies — Create a Spending Policy

> POST /api/policies — creates a new AI spending policy with budget limits, transaction caps, allowed assets, and optional rate limiting.

Create a spending policy to define how much an AI session can spend, which assets it can use, and when transactions require your manual approval before hitting the Stellar network. Every AI session must be backed by exactly one policy. You can create a policy from a managed preset (with sensible defaults already filled in) or define completely custom limits for advanced use cases.

## Endpoint

```
POST /api/policies
```

## Authentication

All requests must include a valid bearer token in the `Authorization` header, or a `pay3_session` cookie obtained during wallet authentication.

```
Authorization: Bearer <token>
```

## Request body

**name** `string` *required*

A human-readable display name for this policy, e.g. `"Low-Risk Trading Bot"`. Maximum 120 characters.

**preset** `string` *required*

The template to base this policy on. Must be one of `CONSERVATIVE`, `BALANCED`, `DEFI`, or `CUSTOM`. When using a managed preset, Pay3 fills in all budget fields automatically — you only need to supply `name` and `preset`. Use `CUSTOM` to specify your own limits.

**dailyBudget** `string`

*(Required when `preset` is `CUSTOM`)* Maximum total spend per calendar day, in USD. Resets at midnight UTC. Provide as a numeric string, e.g. `"250"`.

**perTransactionMax** `string`

*(Required when `preset` is `CUSTOM`)* Hard cap on a single transaction, in USD. Any transaction request above this amount is rejected immediately. Provide as a numeric string.

**manualApprovalThreshold** `string`

*(Required when `preset` is `CUSTOM`)* Transactions exceeding this USD amount (but within `perTransactionMax`) are held in the approval queue and require your explicit confirmation before execution. Provide as a numeric string.

**sessionDurationHours** `number`

*(Required when `preset` is `CUSTOM`)* How many hours a session created with this policy stays active before expiring automatically.

**allowedAssets** `array`

*(Required when `preset` is `CUSTOM`)* Array of asset ticker strings the AI is permitted to transact with, e.g. `["USDC", "XLM"]`. Any transaction involving an asset not in this list will be rejected.

**allowedRecipientIds** `array`

*(Optional)* Array of contact UUIDs from your Pay3 address book. When set, the AI may only send funds to these contacts. Omit to allow transfers to any Stellar address.

**monthlyBudget** `string`

*(Optional)* An optional monthly spend cap in USD, as a numeric string. Set to `null` to apply no monthly limit.

**rateLimitPerMinute** `number`

*(Optional)* Maximum number of transactions the AI may submit per minute. Omit or set to `null` to apply no rate limit.

## Response

Returns the newly created policy object in full. The response shape mirrors the objects returned by [GET /api/policies](https://pay3.mintlify.site/api-reference/policies/list.md). The HTTP status code is `201 Created`.

### Response fields

**id** `string` *required*

Unique UUID assigned to the newly created policy.

**name** `string` *required*

The display name as stored.

**preset** `string` *required*

The preset used: `CONSERVATIVE`, `BALANCED`, `DEFI`, or `CUSTOM`.

**dailyBudget** `string` *required*

Maximum total spend per day in USD, as a decimal string.

**monthlyBudget** `string`

Monthly spend cap in USD as a decimal string, or `null` if none was set.

**perTransactionMax** `string` *required*

Per-transaction hard cap in USD as a decimal string.

**manualApprovalThreshold** `string` *required*

Transactions above this amount (USD) will be routed to the approval queue.

**sessionDurationHours** `number` *required*

Lifetime in hours for sessions created under this policy.

**allowedAssets** `array` *required*

Asset codes the AI is permitted to transfer.

**allowedActions** `array` *required*

Actions permitted under this policy. One or more of `CHECK_BALANCE`, `TRANSFER`, `VIEW_TRANSACTION_HISTORY`.

**allowedRecipientIds** `array` *required*

Array of contact UUIDs allowed as recipients. Empty array means no recipient restriction.

**rateLimitPerMinute** `number`

Maximum transactions per minute. `null` if no rate limit was set.

**isActive** `boolean` *required*

Always `true` for a newly created policy.

**createdAt** `string` *required*

ISO 8601 timestamp when the policy was created.

**updatedAt** `string` *required*

ISO 8601 timestamp when the policy was last modified. Equals `createdAt` on creation.

## Error responses

| Status | Meaning |
| - | - |
| `400 Bad Request` | Missing required fields, invalid `preset` value, or malformed request body. |
| `401 Unauthorized` | Missing or invalid bearer token. |

> [!TIP]
>
> For most use cases, start with a managed preset (`CONSERVATIVE`, `BALANCED`, or `DEFI`). Each preset ships with carefully chosen defaults — you can always tighten them by creating a `CUSTOM` policy later once you know your AI's spending patterns.

## Example request — using a preset

```bash theme={null}
curl -X POST https://api.pay3.dev/api/policies \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Balanced Preset",
    "preset": "BALANCED"
  }'
```

## Example request — custom policy

```bash theme={null}
curl -X POST https://api.pay3.dev/api/policies \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Custom Policy",
    "preset": "CUSTOM",
    "dailyBudget": "250",
    "perTransactionMax": "75",
    "manualApprovalThreshold": "50",
    "sessionDurationHours": 72,
    "allowedAssets": ["USDC", "XLM"],
    "allowedRecipientIds": [
      "b5c6d7e8-1234-5678-abcd-ef0123456789"
    ],
    "monthlyBudget": null,
    "rateLimitPerMinute": 10
  }'
```

## Example response

```json theme={null}
{
  "id": "f9e8d7c6-dcba-4321-fedc-ba9876543210",
  "name": "My Custom Policy",
  "preset": "CUSTOM",
  "dailyBudget": "250.0000000",
  "monthlyBudget": null,
  "perTransactionMax": "75.0000000",
  "manualApprovalThreshold": "50.0000000",
  "sessionDurationHours": 72,
  "allowedAssets": ["USDC", "XLM"],
  "allowedActions": ["CHECK_BALANCE", "TRANSFER", "VIEW_TRANSACTION_HISTORY"],
  "allowedRecipientIds": ["b5c6d7e8-1234-5678-abcd-ef0123456789"],
  "rateLimitPerMinute": 10,
  "isActive": true,
  "createdAt": "2025-07-08T14:30:00.000Z",
  "updatedAt": "2025-07-08T14:30:00.000Z"
}
```

> [!NOTE]
>
> Preset budget values (for `CONSERVATIVE`, `BALANCED`, and `DEFI`) are fixed by Pay3 and cannot be overridden in the request body. To use different limits, choose `CUSTOM`.


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