VetoVetoDocs
Hosted REST API

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.

AuthAPI key · scope policy:read
Querymerchant_id (optional)
200 — an active policy exists
{
  "id": "pol_01J…",
  "version": 3,
  "body": { /* MerchantPolicy */ },
  "hash": "9f2c…",
  "active": true
}
200 — no active policy yet
{ "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.

AuthAPI key · scope policy:write

Request

{
  "body": {
    "requireMandateOverUsd": 20,
    "maxPerTransactionUsd": 500,
    "maxPerAgentPerDayUsd": 2000,
    "minReputationTier": "standard",
    "allowedRails": ["x402"]
  },
  "note": "raise daily cap for Q3"
}
FieldRequiredNotes
bodyA MerchantPolicy object — see Policy fields.
noteoptionalA 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

StatusReason codeMeaning
201New version staged (inactive).
400VALIDATION_FAILEDbody missing or not an object.
404NOT_FOUNDMerchant not found in this project/mode.
stage a policy version
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" } }'