The problem with "free" AI APIs for agents
Most AI APIs want an account, an API key, and a billing relationship before you can call them. That works for a human with a credit card. It does not work for an autonomous agent that needs to pay for a single summarization and move on.
There is a standard for exactly this: HTTP 402 Payment Required. The server refuses the request, tells you what it costs and where to pay, you pay, and you retry with proof. No signup, no dashboard, no approval queue.
I built Hermes Micro-Agent on that model. This is what it looks like from the outside.
What it does
Twenty tasks across four categories, each priced per call in USDC on Base:
| Category | Tasks | Price |
|---|---|---|
| Text | summarize, extract, keywords, sentiment, translate, rewrite, proofread | $0.10 |
| Code | python_debug, code_lint, code_explain, code_refactor, code_review | $0.15–0.25 |
| Data | json_minify, json_query, csv_to_json, hash, base64, convert | $0.10–0.15 |
| Media | describe_image, probe_media | $0.15 |
The price list is free to read: GET /tasks. Discovery is free too: GET /.well-known/x402.
The payment flow
Step one — ask, and get told what it costs:
POST /task
{"task": "summarize", "prompt": "..."}
HTTP/1.1 402 Payment Required
{
"error": "Payment Required",
"accepts": [{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "10",
"asset": "USDC",
"payTo": "0x078fE079A9440631Bc6AD722D7143dC382b4ea4f",
"resource": "/task?task=summarize"
}]
}
Step two — pay USDC on Base, and resend with the transaction hash:
POST /task
X-Payment: 0x<tx_hash>
{"task": "summarize", "prompt": "..."}
Step three — the server verifies the transfer log on-chain before doing any work. If the payment is not there, the request is refused. Not delayed, not queued. Refused.
Why verify on-chain instead of trusting a header
A header saying X-Payment: 0xabc proves nothing. Anyone can type that. So the server reads the actual Transfer events for the USDC contract on Base and confirms that the amount reached our address inside that specific transaction. That is the only claim the header makes that is worth anything.
The consequence is honest: if the RPC is unreachable, the server returns 503 and does no free work. Better to be unavailable than to give away the product.
Discovery: the manifest that makes it findable
The most important part of a pay-per-call service is not the payment logic. It is that a client can find it without being told.
That is what /.well-known/x402 is for. x402 clients, the x402 Bazaar, and the MCP Registry all probe these paths before falling back to a root document. Ours returns the whole service in one read:
GET /.well-known/x402
{
"x402Version": 2,
"service": "hermes-micro-agent",
"receiver": "0x078fE079A9440631Bc6AD722D7143dC382b4ea4f",
"network": "eip155:8453",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"protocol": "exact",
"facilitator": "self",
"tasks": [ ... 20 entries with prices ... ],
"endpoints": [
{"path": "/task", "method": "POST", "scheme": "exact"},
{"path": "/rpc", "method": "POST", "scheme": "exact"},
{"path": "/tasks", "method": "GET"},
{"path": "/health","method": "GET"}
]
}
The facilitator: "self" line is the part that surprises people. Self-facilitated settlement means our receiver address is also the settlement address — there is no third party taking a cut of the verification step.
JSON-RPC for agent-to-agent calls
Some callers already speak JSON-RPC and do not want to learn a bespoke envelope:
POST /rpc
{"jsonrpc":"2.0","id":1,"method":"summarize","params":{"text":"..."}}
Same payment flow as /task. Same 402, same header, same verification.
Refusing what is not implemented
The discovery document lists what exists. Anything else is refused with a clear message, not approximated. A task that is listed but not implemented would be a lie; a task that is not listed at all is simply not for sale. That distinction matters when the caller is an agent that cannot ask a human what went wrong.
Where it runs
Oracle Cloud Always Free — eu-frankfurt-1, Ubuntu, VM.Standard.E2.1.Micro. One OCPU and 1 GB of RAM is genuinely enough for this: the tasks are small, the payment check is a single RPC read, and the whole service is stateless.
The one thing that took real effort was the port. Oracle's Ubuntu images ship an nftables ruleset whose REJECT rule sits before every UFW rule, so sudo ufw allow 8000 succeeds and prints ALLOW while the port stays dead. The accept rule has to be inserted above the reject, and the only honest way to confirm it is by reading the packet counters — not by trusting ufw status.
Try it
The price list and manifest are free to read:
curl https://92.5.95.177.sslip.io/tasks
curl https://92.5.95.177.sslip.io/.well-known/x402
Only paid calls cost anything. If you build against HTTP 402 and have hit the same account-and-API-key wall, this is the shape of the way around it.
Receiver: 0x078fE079A9440631Bc6AD722D7143dC382b4ea4f · USDC on Base · self-facilitated settlement.
Top comments (0)