This guide walks through an LLM agent that autonomously pays for a paywalled API call using the x402 protocol shape — with Tally providing the wallet + permission layer. By the end you’ll have a working agent that:Documentation Index
Fetch the complete documentation index at: https://docs.tallyforagents.com/llms.txt
Use this file to discover all available pages before exploring further.
- Receives a natural-language task (“what’s the weather in Tokyo?”)
- Decides on its own to call a paid tool
- Handles an HTTP
402 Payment Requiredresponse by paying with Tally - Verifies the payment landed on-chain before being served the data
- Returns the answer to the user
paying-weather-agent/ directory — clone it to follow along,
or read on for the inline walkthrough.
What you’ll build (and why)
Most “agent” demos today either fake the payment side (no real money moves) or use a bespoke integration (only works with one vendor). This example uses two pieces of real infrastructure:- Tally for the wallet + permission layer. The agent is granted scoped spending authority (per-tx max, daily cap, optional recipient allowlists) on a wallet, and Tally enforces it server- side. No keys on the agent’s box.
- x402 protocol shape for how the receiver communicates “you owe me $X.” Coinbase’s x402 standard is the closest thing to a protocol for agentic payments. The same flow works with any service that follows it.
Prerequisites
In the Tally dashboard
This setup is identical to the Quickstart; the short version is:- Sign in at app.tallyforagents.com.
- Fund your Main Wallet with Base Sepolia USDC + ETH.
~$1 USDC + ~0.01 ETH is plenty:
- USDC: Circle’s faucet → Base Sepolia → paste your wallet address
- ETH: Alchemy’s faucet
- Register an agent named
weather-agent(Dashboard → Agents → Register agent).weather-agentis the example’s default; if you pick a different name you’ll setTALLY_AGENT_IDin.env.locallater. - Grant a permission to that agent on your Main Wallet. Defaults (100/day) are more than enough — the mock weather service charges $0.05 per query.
- Create an API key (Dashboard → API keys → Create). Copy the plaintext (shown once).
For the LLM side
One of:- Anthropic API key
- OpenAI API key
ANTHROPIC_API_KEY for a run to force OpenAI.
For the code
Clone the example repo OR install the deps in your own project:The agent + mock server
The runnable example splits across four files:server.ts— reference x402 weather service (HTTP server with on-chain verification). The agent doesn’t need this to run — by default it talks to Tally’s hosted demo endpoint athttps://app.tallyforagents.com/api/demo/x402-weather. The local server is here as a reference implementation you can read, modify, or self-host if you want.tools.ts— theget_weathertool definition + payment-and-retry logicagent-claude.ts/agent-openai.ts— provider-specific agent loops (pick whichever matches your API key)index.ts— entry point that auto-detects which model SDK is available and dispatches
What’s actually happening
The agent has access to one tool,get_weather. The LLM’s system
prompt is implicit — Claude / GPT both recognize that paywalled
APIs are a real thing — but the tool’s description spells it out:
The server side (mock x402)
The includedserver.ts is a ~150-line Node HTTP server that
follows the x402 response shape:
X-Payment: <tx-hash>, the server uses
viem to verify on-chain:
What this teaches
Three concepts compound in the example:- The LLM doesn’t see money. Tools take amounts as decimal strings; the LLM sees “this costs 0.05 USDC” but never touches keys or moves funds directly. Your code is the only thing that can call Tally — and Tally’s policy is the only thing that can move funds.
- The x402 protocol is just HTTP. No special SDK on the
receiver side, no chain RPC from the agent’s process, no Web3
wallet to integrate. The agent makes a normal
fetch()and reacts to the 402 response. - Multi-layered enforcement. Even if the LLM hallucinated a payment 100x bigger than expected, Tally would reject it (per-tx cap exceeded). Even if the agent’s auth key were compromised, the most damage possible is bounded by the cap.
Pointing at a real x402 service
The example’sWEATHER_SERVICE_URL defaults to http://localhost:4242
(the mock server). When you want to talk to a real x402 service:
- Find one that accepts Base Sepolia (most are mainnet-only today, but the ecosystem is growing).
- Set
WEATHER_SERVICE_URLto its URL. - Update the agent’s permission to allow that service’s wallet as a recipient (or leave the allowlist empty to allow any).
Limitations of the demo
The mock server intentionally cuts corners that a real x402 implementation needs:- Bare tx hash in
X-Payment(real x402 uses a base64-encoded full payment payload) - No replay protection — the same tx hash works repeatedly
- No request-window check — the tx could be hours old
- Single payment scheme — real x402 supports multiple
Where to go next
- Read Build a paying agent for the more generic “agent + tool use + Tally” pattern (no x402)
- See the SDK reference for full
tally.payments.create()options - Check the Permissions concept doc for how to set up tighter caps (e.g., a recipient allowlist that pins the weather service’s wallet)
- File issues or improvements at github.com/pkohler95/tally-v2