HTTP 402
This runs the real handshake against the running API. Every request below is issued live, and every response is printed verbatim.
Secure micropayments between autonomous agents, settled on-chain in seconds.
Agent calls the API with no credential
POST /rag/query → expects 402 Payment Required
Server answers with a payment challenge
Destination, exact amount, and a memo that binds the payment
Agent settles on Stellar
One payment buys a bundle of query credits
Server re-reads the transaction and mints a token
Destination, amount, memo and replay are all checked
Agent retries and gets a grounded answer
One credit is debited as the answer streams back
POST https://agentic-rag-paywall-api.onrender.com/api/v1/rag/query
// Run the handshake to see the live response.// Awaiting the challenge…// Awaiting verification…Concurrency
Each lane is an independent agent running the entire x402 loop against the live API. Nothing is queued or faked — and the reconciliation at the end proves the credit ledger stayed exact under concurrent load.
Launch a swarm to see the economy run
Each agent requests a 402, settles, redeems the hash for credits, and spends one on an answer — concurrently, against the running API.
Integrate
The reference client below is the same one shipped in backend/scripts/agent_client.py — run it and it pays on the Stellar testnet for real.
import httpx
API = "https://agentic-rag-paywall-api.onrender.com/api/v1"
AGENT = "agent_my_researcher"
with httpx.Client(timeout=120) as http:
# 1 · Discover the price from the 402 itself
probe = http.post(f"{API}/rag/query",
json={"query": q, "agent_id": AGENT})
assert probe.status_code == 402
price = probe.headers["X-Payment-Amount"]
# 2 · Take the challenge (destination + binding memo)
challenge = http.post(f"{API}/payments/challenge",
json={"agent_id": AGENT}).json()
# 3 · Pay on Stellar, then redeem the hash for credits
tx_hash = pay_stellar(challenge["destination"],
challenge["amount_xlm"],
memo=challenge["memo"])
token = http.post(f"{API}/payments/verify", json={
"transaction_hash": tx_hash,
"agent_id": AGENT,
"challenge_id": challenge["challenge_id"],
}).json()["access_token"]
# 4 · Ask. One credit per answer.
answer = http.post(f"{API}/rag/query",
json={"query": q, "agent_id": AGENT},
headers={"Authorization": f"Bearer {token}"}).json()
print(answer["answer"])
for c in answer["citations"]:
if c["used"]:
print(f' [{c["marker"]}] {c["locator"]}')The reference agent generates a keypair, funds it from Friendbot, submits a real payment, and streams the answer back — end to end in about fifteen seconds.
cd backend
python scripts/agent_client.py --stream \
"Why does the x402 memo matter?"A time-boxed token lets one payment buy unlimited answers — that is a subscription wearing a paywall’s clothes. Here the token proves identity and the ledger holds value: each answer debits one credit inside the transaction that records it, and a failed generation is refunded automatically.
Full OpenAPI reference