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.
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
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.