Veyto

Blocked

A blocked payment is not an error. It is the product working.

When a guardrail stops a payment, Veyto did the thing you configured it to do, and no money moved. Nothing is reserved, nothing is signed, nothing reaches the chain.

ts
import { VeytoDeniedError } from "@veyto/sdk";

try {
  await agent.payingFetch(url);
} catch (e) {
  if (e instanceof VeytoDeniedError) {
    console.log(e.reason);   // "exceeds per-payment cap"
  } else {
    throw e;                 // a real failure — network, service, something broke
  }
}

VeytoDeniedError and a thrown exception are different things, and your code should treat them differently. A denial is an answer. An exception is a problem.

The reasons

reasonwhat to do
exceeds per-payment capask for less, or raise cap_per_payment_minor
exceeds daily capwait for the UTC day to roll, or raise cap_per_day_minor
velocity limitslow down, or raise velocity_max_per_hour
agent frozenunfreeze it, or leave it stopped

Do not retry

A denial is terminal for that request. Retrying the identical payment produces the identical answer, and a retry loop against a cap is just a busier way of being refused. Change the request, or change the policy.

Reading them back

ts
const { items } = await veyto.listIntents({ status: "denied", limit: 50 });
// each carries decision.reason and decision.reason_basis: "policy_evaluation"

Most of what a governed payer does is refuse. Those refusals are recorded, not discarded — a blocked payment nobody can read leaves "why did my agent stop paying?" unanswerable.