A pay-per-request geocoding API for AI agents and developers using x402 V2 and USDC on Base. No API keys, no accounts, no subscriptions. Pay $0.001 USDC per request using the x402 payment protocol.
Traditional APIs require API keys, account registration, and monthly subscriptions. x402 changes this by embedding payments directly into HTTP. The server responds with HTTP 402 when payment is required, and an x402-compatible client pays automatically. This model is ideal for AI agents that need to consume services on-demand without human intervention to manage credentials.
The x402 V2 protocol uses three HTTP headers:
| PAYMENT-REQUIRED | Server → Client. Base64-encoded payment requirements returned with HTTP 402. |
|---|---|
| PAYMENT-SIGNATURE | Client → Server. Base64-encoded signed payment authorization. |
| PAYMENT-RESPONSE | Server → Client. Base64-encoded settlement confirmation after payment is processed. |
Make a normal GET request. The server returns HTTP 402 with payment requirements:
GET /api/geocode?q=1600 Pennsylvania Ave NW, Washington, DC 20500
HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Miw...
{
"x402Version": 2,
"error": "PAYMENT-SIGNATURE header is required",
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"amount": "1000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x26377E6B37A2eaDFD18d52f76e85ca59182cF6B9",
"maxTimeoutSeconds": 60
}]
}
The client signs an EIP-3009 transferWithAuthorization message for USDC and sends the signed payment in the PAYMENT-SIGNATURE header as base64-encoded JSON.
The server verifies the payment, performs the geocoding lookup, settles the payment on-chain, and returns the result with the PAYMENT-RESPONSE header:
HTTP/1.1 200 OK
PAYMENT-RESPONSE: eyJzdWNjZXNzIjp0cnVlLC...
{
"lat": 38.8976763,
"lon": -77.0365298,
"display_name": "1600 Pennsylvania Ave NW, Washington, DC 20500, USA"
}
| Protocol | x402 V2 |
|---|---|
| Version | x402Version: 2 |
| Network | Base mainnet (eip155:8453, chain ID 8453) |
| Asset | USDC |
| USDC Contract | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Price | $0.001 (1000 base units, 6 decimals) |
| Scheme | exact (EIP-3009 transferWithAuthorization) |
| Facilitator | pay.openfacilitator.io |
| Request header | PAYMENT-SIGNATURE (base64-encoded) |
| Response header | PAYMENT-RESPONSE (base64-encoded) |
Here is a complete, copy-paste-ready TypeScript example using the official @x402/fetch and @x402/evm packages to make a paid geocoding request:
// geocode-client.ts
// Install: npm install @x402/fetch @x402/evm viem
import { wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { createWalletClient, http, privateKeyToAccount } from "viem";
import { base } from "viem/chains";
// Load your private key from environment variable
const PRIVATE_KEY = process.env.PRIVATE_KEY;
if (!PRIVATE_KEY) throw new Error("Set PRIVATE_KEY environment variable");
// Create the EVM account
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
// Create a wallet client for signing EIP-712 messages
const walletClient = createWalletClient({
account,
chain: base,
transport: http(),
});
// Wrap fetch with automatic x402 payment handling
const paidFetch = wrapFetchWithPayment(
fetch,
walletClient,
new ExactEvmScheme()
);
async function geocode(address: string) {
const url = `https://geocoding-x402.royaldemocracy.workers.dev/api/geocode?q=${encodeURIComponent(address)}`;
// paidFetch automatically handles 402 → sign → retry
const response = await paidFetch(url);
if (!response.ok) {
const error = await response.json();
throw new Error(`Geocoding failed: ${JSON.stringify(error)}`);
}
const data = await response.json();
console.log("Geocoding result:", JSON.stringify(data, null, 2));
return data;
}
// Usage
geocode("1600 Pennsylvania Ave NW, Washington DC")
.then((result) => {
console.log(`Coordinates: ${result.lat}, ${result.lon}`);
console.log(`Address: ${result.display_name}`);
})
.catch(console.error);
The PRIVATE_KEY environment variable should contain the private key of a wallet funded with USDC on Base mainnet. The buyer signs the payment client-side. The seller (this API) only needs the public address to receive payment.
A plain curl request intentionally returns HTTP 402 with payment requirements:
curl "https://geocoding-x402.royaldemocracy.workers.dev/api/geocode?q=1600 Pennsylvania Ave NW, Washington, DC 20500"
This does not automatically pay. You need an x402-compatible client to sign and submit the payment. See the TypeScript example above for a complete automated implementation.
Register account → obtain API key → add key to requests → manage billing → track usage → handle rate limits → worry about key rotation.
Fund wallet with USDC → make request → pay automatically → receive response. No account. No key. No subscription. Pay only for what you use.
For AI agents, this is a significant advantage. An autonomous agent can pay for API access without requiring a human to set up an account or manage credentials. The agent simply needs a wallet with sufficient USDC balance.
This API is designed to be discoverable and usable by autonomous software. Machine-readable documentation is available at:
These endpoints enable autonomous discovery without human intervention. An AI agent can fetch the OpenAPI spec, generate a client, and start making paid requests in a single automated workflow.