Evaluate a request against policies
The core of the policy engine (deny-overrides):
- All of the user's policies in the Vault are collected (through group memberships)
- Filter: enabled=true and actionType = action
- Applicability: a single boolean condition tree (and/or/not/leaf). condition=null → the policy always applies
- Resolution (Phase 2): block → violated limit (denial or escalation to signing) → signature requirements → allow → deny (default-deny). Requirements are COLLECTED from all applicable policies (requirements[]) rather than choosing the single one with the highest threshold; this is how "CFO AND compliance" is expressed
Called internally from createAddress/createTransaction, but also available directly for dry-run checks from the UI.
curl -X POST "https://policy-engine-rest.ezig.workers.dev/api/v1/evaluate" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"vaultId": "example_string",
"userId": "user-1",
"action": "transfer",
"context": {
"derivationPath": "m/44/195/0/0/1/1/0",
"destinationAddress": "123 Main St",
"destinationNetwork": "tron",
"amount": {
"value": "1.5",
"asset": "usdt"
},
"totalSpent": {
"value": "example_string",
"asset": "example_string"
},
"tokenCode": "example_string",
"signersConfig": {
"mode": "example_string"
}
}
}'
import requests
import json
url = "https://policy-engine-rest.ezig.workers.dev/api/v1/evaluate"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"vaultId": "example_string",
"userId": "user-1",
"action": "transfer",
"context": {
"derivationPath": "m/44/195/0/0/1/1/0",
"destinationAddress": "123 Main St",
"destinationNetwork": "tron",
"amount": {
"value": "1.5",
"asset": "usdt"
},
"totalSpent": {
"value": "example_string",
"asset": "example_string"
},
"tokenCode": "example_string",
"signersConfig": {
"mode": "example_string"
}
}
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://policy-engine-rest.ezig.workers.dev/api/v1/evaluate", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"vaultId": "example_string",
"userId": "user-1",
"action": "transfer",
"context": {
"derivationPath": "m/44/195/0/0/1/1/0",
"destinationAddress": "123 Main St",
"destinationNetwork": "tron",
"amount": {
"value": "1.5",
"asset": "usdt"
},
"totalSpent": {
"value": "example_string",
"asset": "example_string"
},
"tokenCode": "example_string",
"signersConfig": {
"mode": "example_string"
}
}
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"vaultId": "example_string",
"userId": "user-1",
"action": "transfer",
"context": {
"derivationPath": "m/44/195/0/0/1/1/0",
"destinationAddress": "123 Main St",
"destinationNetwork": "tron",
"amount": {
"value": "1.5",
"asset": "usdt"
},
"totalSpent": {
"value": "example_string",
"asset": "example_string"
},
"tokenCode": "example_string",
"signersConfig": {
"mode": "example_string"
}
}
}`)
req, err := http.NewRequest("POST", "https://policy-engine-rest.ezig.workers.dev/api/v1/evaluate", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://policy-engine-rest.ezig.workers.dev/api/v1/evaluate')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"vaultId": "example_string",
"userId": "user-1",
"action": "transfer",
"context": {
"derivationPath": "m/44/195/0/0/1/1/0",
"destinationAddress": "123 Main St",
"destinationNetwork": "tron",
"amount": {
"value": "1.5",
"asset": "usdt"
},
"totalSpent": {
"value": "example_string",
"asset": "example_string"
},
"tokenCode": "example_string",
"signersConfig": {
"mode": "example_string"
}
}
}'
response = http.request(request)
puts response.body
{
"decision": "example_string",
"matchedPolicyIds": [
"example_string"
],
"trace": [
{
"policyId": "example_string",
"policyCode": "example_string",
"policyName": "John Doe",
"effect": "example_string",
"applied": true,
"skipReason": "excluded",
"failedSelector": {
"conditionType": "example_string",
"selectorType": "example_string",
"detail": "initiator's spending over 24 h including the current operation is 11000 usdt, limit 10000 usdt"
}
}
]
}
{
"decision": "example_string",
"reason": "AMOUNT_EXCEEDED",
"policyId": "example_string",
"policyCode": "example_string",
"trace": [
{
"policyId": "example_string",
"policyCode": "example_string",
"policyName": "John Doe",
"effect": "example_string",
"applied": true,
"skipReason": "excluded",
"failedSelector": {
"conditionType": "example_string",
"selectorType": "example_string",
"detail": "initiator's spending over 24 h including the current operation is 11000 usdt, limit 10000 usdt"
}
}
]
}
{
"decision": "example_string",
"policyId": "example_string",
"policyCode": "example_string",
"approvers": [
"example_string"
],
"threshold": 42,
"adminBypass": true,
"allowInitiatorApproval": true,
"trace": [
{
"policyId": "example_string",
"policyCode": "example_string",
"policyName": "John Doe",
"effect": "example_string",
"applied": true,
"skipReason": "excluded",
"failedSelector": {
"conditionType": "example_string",
"selectorType": "example_string",
"detail": "initiator's spending over 24 h including the current operation is 11000 usdt, limit 10000 usdt"
}
}
]
}
{
"decision": "example_string",
"reason": "example_string",
"trace": [
{
"policyId": "example_string",
"policyCode": "example_string",
"policyName": "John Doe",
"effect": "example_string",
"applied": true,
"skipReason": "excluded",
"failedSelector": {
"conditionType": "example_string",
"selectorType": "example_string",
"detail": "initiator's spending over 24 h including the current operation is 11000 usdt, limit 10000 usdt"
}
}
]
}
{
"error": "Bad Request",
"message": "The request contains invalid parameters or malformed data",
"code": 400,
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
{
"error": "Unauthorized",
"message": "Authentication required. Please provide a valid API token",
"code": 401
}
{
"error": "Internal Server Error",
"message": "An unexpected error occurred on the server",
"code": 500,
"requestId": "req_1234567890"
}
/api/v1/evaluate
Target server for requests. Edit to use your own host.
Session token. Mobile/services. The web uses a cookie.
API key (sent in cookie)
The media type of the request body
The action type the policy applies to. Member visibility is NOT part of this: it's a grant (/vaults/:code/visibility-grants), not a policy
Request context: only the fields relevant to the action are filled in. Which ones production calls set is pinned by the tests/selectorContextParity.test.ts metatest: a selector can't be allowed if the context doesn't feed it (otherwise the policy silently stops applying)
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Session token. Mobile/services. The web uses a cookie.
API Key for authentication. Provide your API key in the cookie.
Body
user-1The action type the policy applies to. Member visibility is NOT part of this: it's a grant (/vaults/:code/visibility-grants), not a policy
transfercreate_addresscounterparty_createcounterparty_updatecounterparty_archivecounterparty_group_createcounterparty_group_updatecounterparty_group_archivecounterparty_group_addcounterparty_group_removeRequest context: only the fields relevant to the action are filled in. Which ones production calls set is pinned by the tests/selectorContextParity.test.ts metatest: a selector can't be allowed if the context doesn't feed it (otherwise the policy silently stops applying)