> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://www.openfort.io/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

# Policies

Criteria-based rules that decide which operations an account may perform or have sponsored.

## List policies

`GET /v2/policies`

Returns a list of policies.

### Query parameters

- `limit` `integer <int32>`: Specifies the maximum number of records to return.
- `skip` `integer <int32>`: Specifies the offset for the first records to return.
- `order` `string`: Specifies the order in which to sort the results.
- `scope` `string[]`: Filter by scope.
- `enabled` `boolean`: Filter by enabled status.
- `accountId` `string`: Filter by account ID (for account-scoped policies).
- `operation` `string[]`: Only include policies that have at least one rule with an operation in this list.
- `operationNotIn` `string[]`: Exclude policies where all rules have operations in this list.

### Responses

#### `200`: Successful response.

Body (`application/json`):

- `object` `string` _(required)_
- `url` `string` _(required)_
- `data` `object[]` _(required)_
  - `id` `string` _(required)_
  - `object` `string` _(required)_
  - `createdAt` `integer <int32>` _(required)_
  - `scope` `string` _(required)_: The scope of the policy.
  - `description` `string | null` _(required)_: A description of what this policy does.
  - `accountId` `string | null` _(required)_: The account ID for account-scoped policies.
  - `enabled` `boolean` _(required)_: Whether the policy is enabled.
  - `priority` `integer <int32>` _(required)_: Priority of the policy.
  - `rules` `object[]` _(required)_: The rules that make up this policy. Rules are processed sequentially until a match occurs.
    - `id` `string` _(required)_
    - `object` `string` _(required)_
    - `createdAt` `integer <int32>` _(required)_
    - `action` `string` _(required)_: The action to take when this rule matches.
    - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
    - `criteria` `object[]` _(required)_: Array of criteria to match for this rule. All criteria must match (AND logic).
- `start` `integer <int32>` _(required)_
- `end` `integer <int32>` _(required)_
- `total` `integer <int32>` _(required)_

#### `401`: Unauthorized.

### Example request

```bash
curl 'https://api.openfort.io/v2/policies?limit=10&skip=0&order=desc&scope=project,account&enabled=true&accountId=acc_48eeba57-2cd5-4159-a2cb-057a23a35e65&operation=signEvmTransaction,signEvmMessage&operationNotIn=sponsorEvmTransaction,sponsorSolTransaction'
```

```ts
fetch('https://api.openfort.io/v2/policies?limit=10&skip=0&order=desc&scope=project,account&enabled=true&accountId=acc_48eeba57-2cd5-4159-a2cb-057a23a35e65&operation=signEvmTransaction,signEvmMessage&operationNotIn=sponsorEvmTransaction,sponsorSolTransaction')
```

## Create a policy

`POST /v2/policies`

Creates a new policy with the specified rules.

### Request body (required) (`application/json`)

- `scope` `string` _(required)_: The scope of the policy. - 'project': applies to all accounts (soft validation - no match = user pays) - 'account': applies to a specific account (soft validation) - 'transaction': only when explicitly passed (hard validation - no match = tx fails)
- `description` `string`: A description of what this policy does.
- `accountId` `string`: The account ID for account-scoped policies (starts with acc_). Required when scope is 'account'.
- `enabled` `boolean`: Whether the policy is enabled.
- `priority` `integer <int32>`: Priority of the policy. Higher priority policies are evaluated first.
- `rules` `object[]` _(required)_: The rules that make up this policy. Rules are processed sequentially until a match occurs.
  - `action` `string` _(required)_: The action to take when this rule matches.
  - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
  - `criteria` `object[]`: Array of criteria to match for this rule. All criteria must match (AND logic).

### Responses

#### `201`: Created.

Body (`application/json`):

- `id` `string` _(required)_
- `object` `string` _(required)_
- `createdAt` `integer <int32>` _(required)_
- `scope` `string` _(required)_: The scope of the policy.
- `description` `string | null` _(required)_: A description of what this policy does.
- `accountId` `string | null` _(required)_: The account ID for account-scoped policies.
- `enabled` `boolean` _(required)_: Whether the policy is enabled.
- `priority` `integer <int32>` _(required)_: Priority of the policy.
- `rules` `object[]` _(required)_: The rules that make up this policy. Rules are processed sequentially until a match occurs.
  - `id` `string` _(required)_
  - `object` `string` _(required)_
  - `createdAt` `integer <int32>` _(required)_
  - `action` `string` _(required)_: The action to take when this rule matches.
  - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
  - `criteria` `object[]` _(required)_: Array of criteria to match for this rule. All criteria must match (AND logic).

#### `400`: Bad request.

#### `401`: Unauthorized.

### Example request

```bash
curl https://api.openfort.io/v2/policies \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "scope": "project",
  "description": "Limit ETH transfers to 1 ETH to approved addresses",
  "accountId": "acc_48eeba57-2cd5-4159-a2cb-057a23a35e65",
  "enabled": true,
  "priority": 0,
  "rules": [
    {
      "action": "accept",
      "operation": "signEvmTransaction",
      "criteria": [
        {
          "type": "evmAddress",
          "operator": "in",
          "addresses": [
            "0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12"
          ]
        }
      ]
    }
  ]
}'
```

```ts
fetch('https://api.openfort.io/v2/policies', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    scope: 'project',
    description: 'Limit ETH transfers to 1 ETH to approved addresses',
    accountId: 'acc_48eeba57-2cd5-4159-a2cb-057a23a35e65',
    enabled: true,
    priority: 0,
    rules: [
      {
        action: 'accept',
        operation: 'signEvmTransaction',
        criteria: [
          {
            type: 'evmAddress',
            operator: 'in',
            addresses: ['0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12']
          }
        ]
      }
    ]
  })
})
```

## Get a policy

`GET /v2/policies/{policyId}`

Retrieves the details of a policy that has previously been created.

### Path parameters

- `policyId` `string` _(required)_: Specifies the unique policy ID (starts with ply_).

### Responses

#### `200`: Successful response.

Body (`application/json`):

- `id` `string` _(required)_
- `object` `string` _(required)_
- `createdAt` `integer <int32>` _(required)_
- `scope` `string` _(required)_: The scope of the policy.
- `description` `string | null` _(required)_: A description of what this policy does.
- `accountId` `string | null` _(required)_: The account ID for account-scoped policies.
- `enabled` `boolean` _(required)_: Whether the policy is enabled.
- `priority` `integer <int32>` _(required)_: Priority of the policy.
- `rules` `object[]` _(required)_: The rules that make up this policy. Rules are processed sequentially until a match occurs.
  - `id` `string` _(required)_
  - `object` `string` _(required)_
  - `createdAt` `integer <int32>` _(required)_
  - `action` `string` _(required)_: The action to take when this rule matches.
  - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
  - `criteria` `object[]` _(required)_: Array of criteria to match for this rule. All criteria must match (AND logic).

#### `401`: Unauthorized.

#### `404`: Not found.

### Example request

```bash
curl https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65
```

```ts
fetch('https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65')
```

## Update a policy

`POST /v2/policies/{policyId}`

Updates an existing policy.

### Path parameters

- `policyId` `string` _(required)_: Specifies the unique policy ID (starts with ply_).

### Request body (required) (`application/json`)

- `description` `string`: A description of what this policy does.
- `enabled` `boolean`: Whether the policy is enabled.
- `priority` `integer <int32>`: Priority of the policy. Higher priority policies are evaluated first.
- `rules` `object[]`: The rules that make up this policy. If provided, replaces all existing rules.
  - `action` `string` _(required)_: The action to take when this rule matches.
  - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
  - `criteria` `object[]`: Array of criteria to match for this rule. All criteria must match (AND logic).

### Responses

#### `200`: Successful response.

Body (`application/json`):

- `id` `string` _(required)_
- `object` `string` _(required)_
- `createdAt` `integer <int32>` _(required)_
- `scope` `string` _(required)_: The scope of the policy.
- `description` `string | null` _(required)_: A description of what this policy does.
- `accountId` `string | null` _(required)_: The account ID for account-scoped policies.
- `enabled` `boolean` _(required)_: Whether the policy is enabled.
- `priority` `integer <int32>` _(required)_: Priority of the policy.
- `rules` `object[]` _(required)_: The rules that make up this policy. Rules are processed sequentially until a match occurs.
  - `id` `string` _(required)_
  - `object` `string` _(required)_
  - `createdAt` `integer <int32>` _(required)_
  - `action` `string` _(required)_: The action to take when this rule matches.
  - `operation` `string` _(required)_: The operation this rule applies to. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
  - `criteria` `object[]` _(required)_: Array of criteria to match for this rule. All criteria must match (AND logic).

#### `400`: Bad request.

#### `401`: Unauthorized.

#### `404`: Not found.

### Example request

```bash
curl https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65 \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "description": "Limit ETH transfers to 1 ETH to approved addresses",
  "enabled": true,
  "priority": 0,
  "rules": [
    {
      "action": "accept",
      "operation": "signEvmTransaction",
      "criteria": [
        {
          "type": "evmAddress",
          "operator": "in",
          "addresses": [
            "0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12"
          ]
        }
      ]
    }
  ]
}'
```

```ts
fetch('https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    description: 'Limit ETH transfers to 1 ETH to approved addresses',
    enabled: true,
    priority: 0,
    rules: [
      {
        action: 'accept',
        operation: 'signEvmTransaction',
        criteria: [
          {
            type: 'evmAddress',
            operator: 'in',
            addresses: ['0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12']
          }
        ]
      }
    ]
  })
})
```

## Delete a policy

`DELETE /v2/policies/{policyId}`

Deletes a policy. This is a soft delete.

### Path parameters

- `policyId` `string` _(required)_: Specifies the unique policy ID (starts with ply_).

### Responses

#### `200`: Successful response.

Body (`application/json`):

- `id` `string` _(required)_
- `object` `string` _(required)_
- `deleted` `boolean` _(required)_

#### `401`: Unauthorized.

#### `404`: Not found.

### Example request

```bash
curl https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65 \
  --request DELETE
```

```ts
fetch('https://api.openfort.io/v2/policies/ply_48eeba57-2cd5-4159-a2cb-057a23a35e65', {
  method: 'DELETE'
})
```

## Evaluate policy

`POST /v2/policies/evaluate`

Evaluates an operation against policies without actually performing the operation.
Use this endpoint to check if an operation would be allowed before attempting it.

### Request body (required) (`application/json`)

- `operation` `string` _(required)_: The signing operation to evaluate. EVM: signEvmTransaction, sendEvmTransaction, signEvmTypedData, signEvmMessage, signEvmHash Solana: signSolTransaction, sendSolTransaction, signSolMessage
- `accountId` `string`: The account ID to evaluate policies for (starts with acc_). If not provided, only project-scoped policies are evaluated.
- `payload` `object`: The payload to evaluate against policy criteria. Structure depends on the operation type.
  - `chainId` `integer <int32>`: Chain ID for EVM operations.
  - `to` `string`: Recipient address for EVM transaction (hex with 0x prefix).
  - `value` `string`: Value in wei for EVM transaction.
  - `data` `string`: Transaction data/calldata for EVM transaction (hex with 0x prefix).
  - `verifyingContract` `string`: Verifying contract address for EIP-712 typed data.
  - `domain` `object`: EIP-712 domain object.
  - `message` `object`: EIP-712 message object.
  - `primaryType` `string`: Primary type for EIP-712 typed data.
  - `evmMessage` `string`: Message content for signEvmMessage.
  - `network` `string`: Solana network: "mainnet-beta", "devnet", "testnet".
  - `recipients` `string[]`: Recipient addresses for SOL transfers (Base58).
  - `solValue` `string`: SOL amount in lamports.
  - `splRecipients` `string[]`: Recipient addresses for SPL token transfers (Base58).
  - `splValue` `string`: SPL token amount.
  - `mintAddress` `string`: Token mint address (Base58).
  - `programIds` `string[]`: Program IDs involved in transaction (Base58).
  - `solMessage` `string`: Message content for signSolMessage.
  - `instructionData` `string`: Base64-encoded instruction data for Solana programs (includes 8-byte discriminator).

### Responses

#### `200`: Successful response.

Body (`application/json`):

- `object` `string` _(required)_: The object type.
- `allowed` `boolean` _(required)_: Whether the operation is allowed by the policy.
- `reason` `string` _(required)_: The reason for the policy decision.
- `operation` `string` _(required)_: The operation that was evaluated.
- `accountId` `string`: The account ID that was evaluated (if any).
- `matchedPolicyId` `string`: The ID of the policy that matched (if any).
- `matchedRuleId` `string`: The ID of the rule that matched (if any).

#### `400`: Bad request.

#### `401`: Unauthorized.

### Example request

```bash
curl https://api.openfort.io/v2/policies/evaluate \
  --request POST \
  --header 'Content-Type: application/json' \
  --data '{
  "operation": "signEvmTransaction",
  "accountId": "acc_48eeba57-2cd5-4159-a2cb-057a23a35e65",
  "payload": {
    "chainId": 1,
    "to": "0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12",
    "value": "1000000000000000000",
    "data": "0xa9059cbb...",
    "verifyingContract": "string",
    "domain": {},
    "message": {},
    "primaryType": "Permit",
    "evmMessage": "string",
    "network": "mainnet-beta",
    "recipients": [
      "string"
    ],
    "solValue": "1000000000",
    "splRecipients": [
      "string"
    ],
    "splValue": "string",
    "mintAddress": "string",
    "programIds": [
      "string"
    ],
    "solMessage": "string",
    "instructionData": "string"
  }
}'
```

```ts
fetch('https://api.openfort.io/v2/policies/evaluate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    operation: 'signEvmTransaction',
    accountId: 'acc_48eeba57-2cd5-4159-a2cb-057a23a35e65',
    payload: {
      chainId: 1,
      to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0aB12',
      value: '1000000000000000000',
      data: '0xa9059cbb...',
      verifyingContract: 'string',
      domain: {},
      message: {},
      primaryType: 'Permit',
      evmMessage: 'string',
      network: 'mainnet-beta',
      recipients: ['string'],
      solValue: '1000000000',
      splRecipients: ['string'],
      splValue: 'string',
      mintAddress: 'string',
      programIds: ['string'],
      solMessage: 'string',
      instructionData: 'string'
    }
  })
})
```
