Inspiration
An AI agent today can only call APIs someone wired into it months earlier. It cannot go looking for a capability it lacks, compare what is on offer, or transact with a service it has never met. Every integration is a human decision made in advance. wo things are missing. A way to discover — services need to publish what they do, what they charge, how fast they are, and how well they have performed, in a registry an agent can read and rank at request time. And a way to pay — discovery is worthless if settlement needs a signup form and a corporate card.
402 Payment Required has sat unused in the HTTP spec for thirty years. It turns out to be exactly the right primitive once the client is software with a wallet and no patience for onboarding. The server quotes the price in the response, the client pays, the client retries. On Stellar the fee is about 0.00001 XLM and the ledger closes in five seconds, so a $0.001 purchase is economically real rather than a rounding error swallowed by payment processing.
What it does
An agent arrives with a question and no configured endpoint. It reads a live marketplace of eleven knowledge providers, each publishing its own price, latency, capability tags and earned reputation. It filters to the ones that can actually answer, ranks the survivors against a selected objective, settles an HTTP 402 micropayment with the winner, invokes it, and returns a cited answer.
Ask "Does a conference paper count as prior art?" and the network:
lists 11 providers, filters to the 2 with matching capability ranks them in ~7ms and explains the choice in plain language selects PriorArt Search AI at 4 credits / 0.035 XLM settles a 402, debits the ledger, invokes the provider returns a grounded answer with 4 retrieved passages and inline citations Other pieces worth clicking:
Semantic answer cache — repeat a question and it is served from cache at zero credits (2478ms → 445ms). Paraphrases are still charged, because they are genuinely different retrievals. Corpus atlas — all 84 indexed passages projected into 2D, with your query placed among them. Ledger — every credit movement is an auditable entry. Balance and ledger reconcile exactly. Demo Mode — press D anywhere and four distinct agents run the whole loop autonomously across the product.
How we built it
Backend — FastAPI on Python 3.12. ChromaDB for vectors, SQLite for the registry and ledger. Gemini gemini-3.1-flash-lite for generation and gemini-embedding-001 for retrieval. The lite model is deliberate: reasoning models spend 20+ seconds "thinking" before the first token, which makes a streamed answer feel broken, and extraction from supplied context is exactly what a lite model does well.
Routing — providers are ranked on capability, reputation, price and latency, with weights that shift by objective (balanced / best answer / cheapest / fastest). The decision streams to the client over SSE stage by stage, so the reasoning is visible rather than asserted.
Payments — the real x402 handshake. POST /payments/challenge returns destination, amount, memo and expiry. Payment is verified against the memo that binds it to that challenge, and settlement issues a scoped access token. Retrieval task types are split (RETRIEVAL_DOCUMENT vs RETRIEVAL_QUERY), which measurably improves recall and costs nothing.
Frontend — Next.js 16 and React 19, streaming the routing decision live.
Deployment — split by necessity. The frontend is on Vercel. The backend cannot be: SQLite and ChromaDB both need a filesystem, and serverless has none. It runs as a container on Render instead.
Challenges we ran into
A newline cost us an afternoon. Production seeding hung at "core corpus 1/4" while logs repeated plugin_credentials.cc:82 Plugin added invalid metadata value and INTERNAL:Illegal header value. The API key was valid — it authenticated fine by hand. The value stored in the host's dashboard had a trailing newline from a copy-paste, and gRPC refuses to place whitespace in the x-goog-api-key header. It then retried beneath our error handling until the client timed out, so nothing surfaced as a failure.
The trap was subtler than the typo. Our config computed gemini_enabled as bool(key.strip()) — stripping to test the value but storing it raw. The check and the use disagreed, so a broken key sailed past the boot guard. Worse, the run ended by reporting "seeded 0 passages — corpora missing from the image", which named entirely the wrong cause. Fix: strip credentials once, at the config boundary, for all four pasted secrets.
The demo walled itself off. Free agents started with 3 credits while the priciest provider charged 4. Any visitor asking a patents question hit the paywall before ever seeing an answer, on a balance that could never buy that provider.
The paywall lied about money. Sandbox settlement walked the same five stages as a real payment and displayed "Signing the payment → Submitting to Stellar → Verifying on-chain". None of that happens in sandbox — no key signs, no transaction is sent, no ledger is read. Testers reasonably concluded the demo was about to charge their wallet.
No disk on the free tier. The container filesystem is wiped on every restart, so the API rebuilds its corpus and registry on boot. Cold start to fully seeded is about 71 seconds.
Accomplishments that we're proud of
The money path is real and auditable end to end, not a mock. Credits reconcile against the ledger exactly. 128 backend tests pass, and a standalone verification script drives the live public deployment from outside — all six pages, then challenge → settlement → token → paid query → cache hit → ledger reconciliation, plus a scan of the shipped bundle for leaked keys and localhost URLs. 20 of 20 checks pass against production.
We also kept the failure modes honest. The app says when it has no backend rather than rendering empty panels, and it refuses to report success it has not verified.
What we learned
A green build is not a working product. Almost every problem we hit was a configuration problem that type checks, linters and unit tests are structurally incapable of catching — a trailing newline, a free-credit allowance below the dearest provider, a stage label describing something that never happened. The tests were green throughout all three.
We also learned to distrust our own error messages. The one that cost the most time was confidently wrong about its own cause.
What's next for Agentic RAG Paywall
Real settlement is already implemented alongside the sandbox path; the demo defaults to sandbox so visitors need no wallet. Beyond that: provider-side SDKs so any service can list itself, reputation that decays with age, and multi-hop routing where an agent buys from a provider that itself buys from another.
Log in or sign up for Devpost to join the conversation.