Policy
The acceptance policy is immutable and versioned — one active version per merchant per mode. PUT creates a new version; it goes live only on publish.
The acceptance policy is the rule set the gate runs before taking money. It is immutable
and versioned: PUT /v1/policy always creates a new version and never mutates an
existing one. A new version is created inactive — it goes live only when you
publish.
Why versions are immutable
The policy hash is sha256(canonicalJson(policy)) — the same hash a merchant receipt
embeds. So a receipt provably names the exact stored policy version that was in force when
the order settled. Mutating a version in place would break that proof.
For the full set of editable fields, see Policy fields.
GET /v1/policy
Return the active policy for the resolved merchant.
| Auth | API key · scope policy:read |
|---|---|
| Query | merchant_id (optional) |
{
"id": "pol_01J…",
"version": 3,
"body": { /* MerchantPolicy */ },
"hash": "9f2c…",
"active": true
}{ "active": null, "version": 0, "body": null, "hash": null }curl "https://api.veto-ai.com/v1/policy?merchant_id=mrch_01J…" \
-H "Authorization: Bearer veto_test_8f2c…"PUT /v1/policy
Create a new policy version (inactive). The next version number is max(version) + 1 for
this merchant; the hash is computed server-side and returned.
| Auth | API key · scope policy:write |
|---|
Request
{
"body": {
"requireMandateOverUsd": 20,
"maxPerTransactionUsd": 500,
"maxPerAgentPerDayUsd": 2000,
"minReputationTier": "standard",
"allowedRails": ["x402"]
},
"note": "raise daily cap for Q3"
}| Field | Required | Notes |
|---|---|---|
body | ✅ | A MerchantPolicy object — see Policy fields. |
note | optional | A human change note stored with the version. |
Response — 201
{ "id": "pol_01J…", "version": 4, "hash": "a1b2…", "active": false }New versions are inactive.
PUT /v1/policy stages a version; it does not take effect. Run
POST /v1/publish to validate and activate the newest version.
Status codes
| Status | Reason code | Meaning |
|---|---|---|
201 | — | New version staged (inactive). |
400 | VALIDATION_FAILED | body missing or not an object. |
404 | NOT_FOUND | Merchant not found in this project/mode. |
curl -X PUT "https://api.veto-ai.com/v1/policy?merchant_id=mrch_01J…" \
-H "Authorization: Bearer veto_test_8f2c…" \
-H "Content-Type: application/json" \
-d '{ "body": { "requireMandateOverUsd": 20, "maxPerTransactionUsd": 500, "minReputationTier": "standard" } }'Receiving
The merchant's pay_to destination(s). Validated loud and early at write time so an agent never hits a broken receiving config at runtime.
Validate & publish
The publish gate. Validate runs the SDK's pure config validator over your draft; publish validates, then activates the newest policy version and rebuilds the manifest.