Skip to content

Quickstart

On this page

Put VulSight Guard in front of an agent that already pays with x402, the open standard for agent payments. About ten minutes, no wallet changes, test money on a test network until you switch a policy to Base or Solana Mainnet.

1. Get an API key

Sign up, and the dashboard home shows your first key once. Copy it then, it is not shown again. It comes with a default policy in enforce mode, the demo seller on your allowlist (the Payees page), a limit of 0.10 USDC per payment and 1.00 per day, on Base Sepolia with test USDC. Base and Solana Mainnet move real USDC once you switch the policy. For Solana, register your own Solana signer on the x402 client; the SDK page says how.

Read your policy back to check the key works.

Terminal
export VULSIGHT_API_KEY="<your key>"

curl -s -H "authorization: Bearer $VULSIGHT_API_KEY" \
  https://vulsight-guard.vercel.app/api/v1/policy

A 401 with unknown_api_key means the key is mistyped or was rotated, and one with revoked_api_key means it was revoked. Rotate it or make a new key on the Keys page. The policy page explains every field this prints.

2. Choose a way in

You are on the buyer's side. Your agent pays, and the guard decides. The seller you pay changes nothing, and the guard reads the 402 it already sends.

The proxy needs no code. Prefix the seller's URL with your proxy token. The token authorizes checks, not payments, so it is safe in a URL and it is not your API key.

// The seller's URL you already call, with the guard in front of it.
// Everything after the token is the seller's URL, its own scheme left out.
const url = "https://vulsight-guard.vercel.app/p/vsp_test_xxxxxxxx/vulsight-guard.vercel.app/merchant/dataset";

// The first request and the seller's 402 pass through untouched.
// The retry that carries the signed payment is checked before it is forwarded.
// fetchWithPayment is your existing x402 client.
const res = await fetchWithPayment(url);

For the SDK tab, install the packages first:

bun add @vulsight/guard @x402/fetch @x402/evm viem

The SDK accepts any 2.x release of @x402/core from 2.24 on, so the install line carries one copy of it beside the x402 client.

Since @x402/core 2.23.0 the client refuses any payment over one dollar by default before the guard's hook runs, so keep that cap or call .setSpendControls(false) on the client to make the guard's policy the only limit.

A denied payment comes back with its reasons as sentences. A held payment waits for you in the dashboard for two minutes by default. With the SDK and the MCP tool an agent that stops waiting first has signed nothing. Pick Approve and always allow this payee, and the agent's next payment to that seller skips the first-payment review. The guard keeps a short excerpt of what the agent read, to explain the decision.

All three are live, and the same checks run through the API. Each way in has its own page: proxy URL, SDK, and MCP and skills.

3. Watch the first decision

No wallet yet? Ask the guard for a verdict directly.

Terminal
curl -s -X POST https://vulsight-guard.vercel.app/api/v1/decisions \
  -H "authorization: Bearer $VULSIGHT_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "kind": "x402_payment",
    "payTo": "0x1111111111111111111111111111111111111111",
    "amountAtomic": "1000",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "network": "eip155:84532",
    "scheme": "exact",
    "resourceUrl": "https://vulsight-guard.vercel.app/merchant/weather",
    "observed402PayTo": "0x1111111111111111111111111111111111111111",
    "sessionId": "sess_1",
    "contextExcerpt": "Current conditions for Seoul as JSON. Price 0.001 USDC per request."
  }'

The SDK and the proxy sign a real payment, so on Base Sepolia the buyer wallet must hold test USDC from the Circle faucet (USDC, Base Sepolia). EVM_PRIVATE_KEY in the SDK snippet is a throwaway wallet's key; the SDK page says how to make one. The wallet needs no Base Sepolia ETH: the seller's facilitator, the service that puts an x402 payment on chain for the seller and pays the gas, submits the transfer the wallet signed.

Through the SDK the payment call throws with the reasons. Through the proxy your client gets them in a 403 body. The MCP tool answers in sentences. In every case the dashboard has the decision with the policy it was checked against.

What your terminal prints when the guard refuses a payment. Recorded from a real run, test USDC on Base Sepolia.
The dashboard after two test payments: the key row, the ways in, and the approved and denied rows in Recent decisions
Your decisions land in the dashboard, newest first. Open a row for its reasons. The review page works from a phone.

The same rows come back over the API with GET /api/v1/decisions, each with its status and every rule that ran. An empty array means nothing has been decided under this account yet, so run one call or one payment from above.