On this page
How a decision adds upCodes that denyCodes that hold for reviewCodes that only informStatusesReference / Reason codes
Reason codes
Rules run in order. Each rule that does not pass returns a code and a plain sentence, except payee_allowlisted, which the first_time_payee sentence beside it already explains. The response lists them in the order they ran.
The sentences below are real, with example addresses and amounts. Beside each code is its name on the dashboard.
How a decision adds up
Each rule returns one of four results, and the strongest result wins.
{
"status": "denied",
"rules": [
{
"id": "payee_matches_402",
"result": "deny",
"sentence": "The payment is addressed to 0x2222…2222 but the seller's own 402 asked for 0x1111…1111."
},
{
"id": "payee_allowlisted",
"result": "info"
},
{
"id": "injection_suspected",
"result": "deny",
"sentence": "The content check flagged instructions in the page, so this payment was blocked."
},
{
"id": "first_time_payee",
"result": "review",
"sentence": "0x2222…2222 is not on your allowlist. Auto-allow is off in your policy."
}
]
}The rules that passed are left out of this sample. A real response carries every rule that ran, in order.
denyrefuses the payment. One is enough to make the decision denied.reviewsends it to a person. With no deny, one review makes the decision review.infonotes something without changing the outcome.passis silent and carries no sentence. With no deny and no review, the decision is allowed.
The proxy URL does not forward a denied payment, and the SDK hook does not sign one. The HTTP API and MCP are advisory. With them, your code must not send a denied payment. Several deny codes on one decision are one payment blocked for several reasons.
The resource rule runs only when the policy lists what the agent may buy. The wallet blocklist rule runs only when you turn it on. In observe mode, a payment goes through unless its code's entry says it blocks in observe.
Codes that deny
These codes block the payment. One is enough to deny it.
| Code | Dashboard name | Blocks in observe | Example sentence | Next step |
|---|---|---|---|---|
network_ | network | Yes | The network Base (eip155:8453) is not allowed. The policy allows Base Sepolia (eip155:84532). | Tick the network on Policy if the agent should pay there. |
asset_ | asset | Yes | The asset 0x5555…5555 on Base Sepolia (eip155:84532) is not allowed by the policy. | Pay in the network's USDC. Ticking a network allows only its USDC. |
asset_ | asset | Yes | Native currency transfers are not allowed, only the tokens the policy lists. | As above. |
payee_ | denylist | No | The payee 0x0000…0bad is on your denylist. | Remove the payee on Payees if the denial was a mistake. |
wallet_ | blocklist | No | This address matches a government-restriction record in the current blocklist. Review this restriction before deciding whether to allowlist it. | On a match, review the restriction before you pay or allowlist the payee. When screening could not finish, retry as the sentence says. |
wallet_ | blocklist | No | This address or its selected USDC token account is listed as issuer-restricted. The token contract still refuses a transfer to a frozen account, even if you allowlist the payee. | As above. |
wallet_ | blocklist | No | This address matches a risk-advisory record in the current blocklist. Review this restriction before deciding whether to allowlist it. | As above. |
wallet_ | blocklist | No | Wallet blocklist screening is enabled but could not be completed. Once the screening sources recover, retry as a new payment attempt, with a new Idempotency-Key if you send one. | As above. |
payee_ | payee vs 402 | Yes | The payment is addressed to 0x2222…2222 but the seller's own 402 asked for 0x1111…1111. | Do not pay. Check which payee the agent sent and which one the seller asked for. |
amount_ | limit | No | The amount 2.50 USDC is over the per-transaction limit of 0.10 USDC. | Raise "Per-transaction limit (USDC)" on Policy, or ask for a smaller payment. |
amount_ | daily cap | No | This payment of 2.50 USDC would bring today's total across all networks to 2.65 USDC, over the daily cap of 1.00 USDC. | Wait for midnight UTC, or raise the daily cap on Policy. |
amount_ | daily cap | No | The daily cap is a USDC budget, and 0x5555…5555 is not USDC on Base Sepolia (eip155:84532), so the payment cannot be counted against it. | Pay in USDC. The daily cap counts USDC only. |
amount_ | daily cap | No | The UTC day changed before this payment's daily budget check finished. Start a new payment attempt under today's budget. | Start a new payment attempt. |
injection_ | content check | No | The content check flagged instructions in the page, so this payment was blocked. | Read the flagged passage on the decision page. A denied payment cannot be approved. |
injection_ | content check | No | The content check flagged instructions in text the agent read. A contract call has no seller page, so that text blocked this call. | As above. |
contract_ | contract call | Unsupported calls only | The call is approve(address,uint256) with an unlimited amount for 0x4444…4444. | A denied call cannot be approved. Use a supported USDC transfer or a capped approval. |
payment_ | payment method | Yes | VulSight Guard supports only exact x402 payments, and this payment uses the upto scheme. Ask the seller for an exact payment quote before retrying. | Ask the seller for a quote the sentence names. The supported payments are on the API page. |
payment_ | payment method | Yes | VulSight Guard supports only EIP-3009 authorizations on Base, and this payment uses the permit2 transfer method. Ask the seller for an EIP-3009 quote without Permit2 or token approvals. | As above. |
payment_ | payment method | Yes | VulSight Guard supports only the authorization payment flow, and this payment uses the upfront payment flow. Ask the seller for an authorization quote instead. | As above. |
payment_ | payment method | Yes | VulSight Guard supports x402 payments on Base Sepolia, Base, Solana Devnet and Solana Mainnet, and this payment is on eip155:1. Choose a supported network in the agent and its policy. | As above. |
Codes that hold for review
These codes send the payment to a person on Review.
| Code | Dashboard name | Blocks in observe | Example sentence | Next step |
|---|---|---|---|---|
resource_ | resource | No | The agent may buy from https://merchant.example/dataset and 1 more. This payment is for https://merchant.example/addon. | Approve or deny it. Add the URL to "What the agent may buy" to allow it next time. |
amount_ | hold over | No | The amount 0.55 USDC is over your hold threshold of 0.50 USDC, so it waits for a person. | Approve or deny it on Review. |
velocity_ | hourly count | No | This agent has had 20 payments allowed, approved, or still waiting on Base Sepolia (eip155:84532) in the last hour. The policy allows 20 per hour on each network. | Approve it, wait for the hour to pass, or raise "Payments per hour per network". |
injection_ | content check | No | The page the agent read contains instructions aimed at the agent. | Read the flagged passage on the decision page, then approve or deny it. |
injection_ | content check | No | The content check did not finish, so this payment needs your review before it can proceed. | Open the decision page, which says why the check did not finish, then approve or deny it. |
injection_ | content check | No | This account filed its 16 MiB of page text for the UTC day, so the page was not checked and this payment waits for a person. Pages filed after midnight UTC are checked again. | Check the seller page yourself, then approve or deny it. Or send the page for checking again after midnight UTC. |
injection_ | content check | No | The text the agent read reached the 64 KiB limit, so the guard could not check all of it and this payment needs your review. To avoid this, file long text in parts under 64 KiB each, or under the URL it came from. | Open the decision page, which says why the check did not finish, then approve or deny it. Send long text for checking in parts under 64 KiB each. |
injection_ | content check | No | The text the agent read contains instructions aimed at the agent. A contract call has no seller page, so flagged text the agent read holds it. | As above. |
first_ | new payee | No | 0x3333…3333 is not on your allowlist. Auto-allow is off in your policy. | Approve it and add the payee to the allowlist in the same click, or deny it. |
first_ | new payee | No | 0x3333…3333 is not on your allowlist. The amount 0.02 USDC is at or over the auto-allow threshold of 0.01 USDC. | As above. |
first_ | new payee | No | 0x3333…3333 is not on your allowlist. The content check was unavailable, so this payment waits for a person. | As above. |
first_ | new payee | No | First transaction to the contract 0x4444…4444, which is not in your allowlist. | As above. |
Codes that only inform
These codes add a note and never change the outcome.
| Code | Dashboard name | Blocks in observe | Example sentence | Next step |
|---|---|---|---|---|
payee_ | allowlist | No | None. The first_time_payee sentence beside it says the payee is off your allowlist. | None. On its own it never blocks or holds a payment. |
wallet_ | blocklist | No | Your allowlist entry on this network skips optional wallet blocklist screening, including the guard's issuer freeze check. Other rules still apply, and the token contract still refuses a transfer to a frozen account. | None. Remove the allowlist entry to screen this payee again. |
first_ | new payee | No | 0x3333…3333 is not on your allowlist. The amount 0.005 USDC is under the auto-allow threshold of 0.01 USDC. | None. The amount is under the auto-allow threshold, so this rule does not hold it. |
injection_ | content check | No | The content check flagged the page the agent read. A person on this account approved a payment held for it, so it no longer holds this agent's payments. | None. The payment rules decided without a content hold. |
injection_ | content check | No | The content check was unavailable for this decision. | As above. |
injection_ | content check | No | An administrator disabled content enforcement, so the payment rules decide without it. | As above. |
Which codes you can meet depends on your policy. The fields and their defaults are on the policy page.
Statuses
Every decision has one of six statuses. Read it on the decision page in Decisions, or with GET /api/v1/decisions/{id}.
| Status | What happened | What the agent does |
|---|---|---|
allowed | No rule denied or held it. | Pay. |
denied | A rule denied it. | Do not pay. |
review_pending | A rule held it for a person. | Wait for a person to approve or deny it on Review. |
review_approved | A person approved it. | Pay. |
review_denied | A person denied it. | Do not pay. |
review_expired | Nobody answered before the review timeout. | Start a new payment attempt. |
In observe mode, status reads allowed for a payment that goes through. shadowStatus holds the status enforce mode would have given it.