A complete Express server that charges 0.005 per joke — settled on-chain every time a route is called. No long-lived token is issued; the route handler runs normally after payment. Source:Documentation Index
Fetch the complete documentation index at: https://docs.key0.ai/llms.txt
Use this file to discover all available pages before exploring further.
examples/ppr-embedded
What it demonstrates
- Defining top-level
routesfor pay-per-call pricing - Using
key0.payPerRequest(routeId, opts?)middleware to gate individual routes - Accessing
req.key0Payment(containingtxHash,planId,amount,challengeId) in route handlers - Discovery via
GET /discoverand agent card showing per-request skills with route metadata - Automatic
PENDING → PAID → DELIVEREDstate transitions with refund safety (pass astoreto enable)
Architecture
Key differences from subscription mode
| Subscription | Per-Request (Embedded) | |
|---|---|---|
| Response | AccessGrant (JWT) | Your route handler’s response |
| Token issued | Yes | No |
| Follow-up auth | Bearer JWT needed for each call | Each call includes PAYMENT-SIGNATURE |
| Route protection | validateAccessToken middleware | key0.payPerRequest() middleware |
| Payment metadata | In IssueTokenParams callback | In req.key0Payment |
Running locally
Prerequisites
- Bun v1.3+ or Node 18+
- Redis running locally
- A wallet address on Base Sepolia
- A gas wallet private key (ETH-funded) for self-contained settlement
Setup
http://localhost:3000.
Environment variables
| Variable | Description |
|---|---|
KEY0_WALLET_ADDRESS | Wallet that receives USDC payments |
GAS_WALLET_PRIVATE_KEY | ETH-funded wallet for settlement |
KEY0_NETWORK | "testnet" (default) or "mainnet" |
REDIS_URL | Redis connection URL (default: redis://localhost:6379) |
PORT | Server port (default: 3000) |
PUBLIC_URL | Public-facing server URL (used in agent card) |
Code walkthrough
1. Define top-level pay-per-call routes
2. Mount key0Router and gate routes
3. Discovery response
Agents callGET /discover and see pay-per-call routes directly:
/.well-known/agent.json includes these as route skills.
Testing with curl
Extending the example
- Add more routes with different plans
- Use
req.key0Payment.challengeIdfor your own audit records - Pass
storetokey0.payPerRequest()to enable refund safety on per-request routes (when settlement succeeds but the handler crashes) - Combine with subscription plans on the same server — agents can use both flows
Next Steps
PPR Standalone Example
Key0 as a gateway that proxies to a separate backend service.
Express Integration
Full reference for key0Router and payPerRequest options.
SellerConfig Reference
Routes, plans, and ProxyToConfig type definitions.
Building a Seller
End-to-end guide from install to production.

