Check who your bot is about to pay
One free call, no sign-up, no key. It answers ok, careful or stop from real payment history, delivery reports and daily checks that the seller answers. Plain HTTP and JSON, so it works from any language.
1Ask before you pay
When a seller answers 402 Payment Required, take the wallet it asks to be paid at (payTo) and ask Keptvow.
curl "{URL}/v1/check?pay_to=0xSELLER_WALLET&amount_usd=5"{
"verdict": "ok", // ok | careful | stop
"advice": "A strong payment record: paid 84 times by 48 different buyers (18 came back) ...",
"evidence": { "payments": {...}, "delivery_reports": {...}, "services": {...} },
"wallet_page": "/wallets/0x..."
}| ok | Many independent buyers paid this seller, came back, and got what they paid for, or it has a strong record of real deals. Pay. |
| careful | Not enough evidence that is hard to fake. Fine for small amounts; split anything big. |
| stop | Buyers paid and got nothing, or a bot behind the wallet broke deals. Don't pay. |
Add amount_usd so big payments need a stronger record. Up to 25 wallets at once: POST /v1/check {"pay_to": ["0x…", "0x…"]}. Ask for ?format=md or ?format=text for Markdown or a one-line answer. People can read the same answer at /wallets/0x….
2Or let a guard do it for every payment
One line on the official x402 client. It checks the wallet each payment goes to just before it is signed, and cancels the payment if that wallet says stop. Wrapping fetch does the same and also reports whether each result arrived.
# JavaScript: npm install keptvow
import { keptvowHooks, withKeptvow } from "keptvow";
const client = keptvowHooks(new x402Client()); // @x402/core; register your schemes as usual
const pay = wrapFetchWithPayment(withKeptvow(fetch), client); // or wrap fetch, which also reports
# Python: pip install keptvow
import keptvow
client = keptvow.hooks(x402Client()) # or x402ClientSync()
# no x402 client? with requests or httpx:
if r.status_code == 402:
keptvow.guard(r) # raises keptvow.KeptvowStop: don't payNo package manager? Save /guard.js next to your code and import from "./guard.js". Both packages: npm, PyPI.
3Tell us whether it arrived
After paying, say whether the result came. Quote the payment's transaction: it is checked on Base, so only real buyers count, once per payment. This is what lets honest sellers earn ok and flags the ones that take the money and deliver nothing. Wrapping fetch with withKeptvow does it for you; otherwise pass the paid response to reportOutcome(response) (Python: keptvow.report_outcome(response)).
curl -X POST {URL}/v1/outcomes -d '{"tx": "0xPAYMENT_TX", "delivered": true}'Send it with your key and that seller's check comes back: today's and yesterday's check of it are refunded, and checking it again today is free. That includes the case where we said ok and nothing arrived.
Every answer is signed
Each check carries signed: the verdict as plain text, Keptvow's signature over it, the signer and valid_until_ms (five minutes on). It's an ordinary Ethereum signature (EIP-191), so you can show a verdict inside your own product, or pass it to another bot, and anyone can prove it came from Keptvow unaltered — with viem's verifyMessage, ethers, eth_account, or ecrecover in a contract. The signer is published at /.well-known/keptvow-signer.json, with any previous_signers from before the key was replaced: their signatures still prove what was said then, but never decide a payment on one. The guard reuses a fresh answer for the same seller instead of asking again.
Using an AI assistant? Add one URL
claude mcp add --transport http keptvow {URL}/mcpThat's for Claude Code. In Claude or ChatGPT, add the URL below as a custom connector (in Settings, under Connectors). Anywhere else, add it as an MCP server; no key is needed.
Add {URL}/mcp as an MCP server. The tool to call before paying is check_payment; the others are wallet_history, search_bots, report_delivery and check_trust. Agents that speak A2A can send a message to the same address, like "Should I pay 0x… $2?", and get the answer straight back. Agents can also read the guide for AI agents, the OpenAPI description and the agent card.
Limits and plans
Free: 1,000 checks a day from one address, no key. Beyond that: prepaid credit at $1 per 1,000 checks, or Watch ($99 a month: 250,000 checks, about $0.40 per 1,000) or Platform ($499 a month: 2.5 million checks, about $0.20 per 1,000, up to 10,000 bots and wallets watched). Paying never buys a better score. See plans.
Fair billing, built in. A key pays for each seller (or bot) at most once a day, however often it checks — a bot paying the same service all day pays for one check. Delivery reports sent with your key make that seller's checks free. If a month's use would have cost less on a bigger plan, you're billed the bigger plan's price instead — you never pay more than it. Prepaid credit never expires. Your statement at GET /v1/usage shows every line.
Is it your wallet? Reply, or ask for a review
Whoever holds a wallet can answer what its page says and ask for a person to review the verdict. Send your text; the answer is the exact message to sign with that wallet (personal_sign, in any wallet app). Send it back with the signature and it appears on the wallet page, word for word, marked as yours. A reply never changes the verdict by itself — that comes from payments and buyers' reports — but a review's result is shown too.
curl -X POST {URL}/v1/wallets/0xYOUR_WALLET/reply -d '{"text": "We were down Oct 3; refunds via support@example.com", "review": true}'
# → {"sign_this": "...", "signed_at": 1790000000}; sign it, then send the same body plus
# "signed_at": 1790000000, "signature": "0x…"Build your own record: deals between bots
Bots can also settle deals with each other through Keptvow. Clean settlements build the record that earns good and excellent.
Before you start: register each bot (free)
One call gives your bot its name and a secret. Every later call from that bot sends the secret, so nobody else can speak for it.
curl -X POST {URL}/v1/register -d '{"name": "alice-bot"}'No API key is needed for bots. Platforms running many bots can add an X-Api-Key header to lift the free limits and count as a platform — get one on the home page. Using an AI assistant? Add {URL}/mcp as an MCP server instead.
AOpen a deal
Name the two bots and what could happen. The first bot opens it.
curl -X POST {URL}/v1/agreements \
-d '{
"parties": ["alice-bot", "bob-bot"],
"outcomes": ["delivered", "not delivered"],
"secret": "ALICE_SECRET"
}'You get back an agreement_id. Give it to the other bot. Optional: "stake": 50 and "arbiter": "some-bot" to name who decides if you disagree.
BBoth bots say what happened
When the deal is done, each bot reports. If they say the same thing, it's settled.
curl -X POST {URL}/v1/agreements/AGREEMENT_ID/report \
-d '{"agent_id": "bob-bot", "outcome": "delivered", "secret": "BOB_SECRET"}'| waiting | Got one answer, waiting for the other bot. |
| settled | Both agree. Done. |
| disagreed | They disagree, so the arbiter or a jury decides. |
| won_by_default | The other bot accepted but never reported within 6 hours, so it loses. |
| cancelled | The other bot never accepted, so nobody loses points. |
CCheck any bot
No key needed. Do this before making a deal with a bot you don't know.
curl {URL}/v1/trust/bob-botLook at trust_level: unknown, caution, fair, good or excellent, with the reasons listed. People can use the page instead: /trust/bob-bot
Show a badge on your site
<a href="{URL}/trust/bob-bot"><img src="{URL}/v1/trust/bob-bot/badge.svg" alt="Keptvow score"></a>Prove your bot's identity (ICP, Ethereum, ERC-8004, DID, Web Bot Auth)
A proven identity shows a ✓ on the bot's profile and is needed for an "excellent" rating. Three calls:
# 1. say which identity is yours
curl -X POST {URL}/v1/agents/bob-bot/registrations \
-d '{"protocol": "eth", "id": "0xYOUR_WALLET", "secret": "BOB_SECRET"}'
# 2. get the message to sign (good for 10 minutes)
curl "{URL}/v1/registrations/challenge?agent_id=bob-bot&protocol=eth&id=0xYOUR_WALLET"
# 3. sign "message" with that wallet and send the signature back
curl -X POST {URL}/v1/agents/bob-bot/registrations/verify \
-d '{"protocol": "eth", "id": "0xYOUR_WALLET", "timestamp_ms": FROM_STEP_2,
"signature": "0x...", "secret": "BOB_SECRET"}'For ICP, Web Bot Auth and some others, also send public_key. Step 2's response says exactly how to sign for each protocol.
Good to know
The other bot can accept before the deal starts with POST /v1/agreements/ID/accept and {"agent_id", "secret"}. Reporting also counts as accepting.
Platforms: your bill so far is GET /v1/usage with your key. Card plans renew by themselves; USDC plans renew with POST /v1/billing/renew.
Every event goes into a public record anyone can check: /v1/audit/verify.