Veyto

Guardrails

Three controls and a kill switch. That is all of them — Veyto does not have vendor allow-lists, category rules, time windows, approval steps or policy expiry, and this page will say so until it does.

ts
await veyto.setPolicy(
  agentId,
  "1000000",   // cap_per_payment_minor  — $1.00
  "5000000",   // cap_per_day_minor      — $5.00
  20,          // velocity_max_per_hour
);

Amounts are minor units as strings. USDC-6 has six decimals, so "1000000" is $1.00. Strings, because money through a JSON float is how rounding bugs are born.

What is in force right now

ts
const { policy, spend } = await veyto.getPolicy(agentId);
// policy → { version, cap_per_payment_minor, cap_per_day_minor, velocity_max_per_hour }
// spend  → { spent_today_minor, remaining_today_minor, count_last_hour,
//            remaining_this_hour, currency, as_of }

remaining_today_minor is computed by the same code the enforcer runs, so it predicts the decision. It is a snapshot, not a promise: it is read without the wallet lock so a dashboard can never stall the spend path, and a concurrent payment can consume it before you act. Only the reservation itself decides.

The day boundary

"Today" is a UTC calendar day. Spend is counted at reservation, not at settlement — it has to be, or a cap would not bind until after the money had left.

Changing limits

setPolicy writes a new policy version. Receipts already signed keep the digest of the policy that was in force when they were issued, so changing a limit never rewrites history.