BUILD / GUIDE
For agents
Verifiable random numbers over HTTP for 0.05 USDC per call, paid with x402.
View the OpenAPI specThe API
https://api.d20dao.org sells verifiable random results. Each paid call opens a D20DAO VRF request on Arc Mainnet and returns the result with its request and fulfillment transactions. No contract needed.
Price and payment
0.05 USDC per call over x402, settled through Circle Gateway. Pay from a Gateway USDC balance on any of 12 networks: Ethereum, Base, Avalanche, Arbitrum, Optimism, Polygon, Unichain, Sonic, World Chain, Sei, HyperEVM and Arc. The payment settles before the request opens. 400, 402, 409, 429 and 503 answers are not charged.
Endpoints
Base URL https://api.d20dao.org.
- POST /v1/random: draw a result (0.05 USDC).
- GET /v1/payments/{paymentId}: status and result of a paid call (free).
- GET /v1/random/{requestId}: a request, read from the chain (free).
- GET /openapi.json: the OpenAPI 3.1 spec (free).
- GET /health: service status (free).
Operations
Send operation and only the fields it uses; ask for every value in one call. An optional seed of up to 64 bytes is bound into the request. items are labels: only their count goes on chain, so the proof covers the indices.
- raw: one 256-bit word.
- coinFlip: 0 (tails) or 1 (heads).
- dice: count rolls (1 to 128) of 1 to sides.
- range: one integer from min to max.
- chooseOne: one index below population (1 to 256), or one of items.
- chooseMany: count distinct indices from population or items.
- shuffle: every index of population or items, once.
Unpaid call
Without a Payment-Signature header, the call answers 402 with one accepts[] option per network. amount is in USDC with 6 decimals.
curl -i https://api.d20dao.org/v1/random \
-H "Content-Type: application/json" \
-d '{"operation":"dice","sides":20,"count":2}'HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi…
{
"x402Version": 2,
"accepts": [
{ "scheme": "exact", "network": "eip155:8453", "amount": "50000", "payTo": "0x…", … },
…
]
}Pay with GatewayClient
GatewayClient.pay() from Circle's @circle-fin/x402-batching signs an accepts[] option and resends the call. 200 carries the result; 202 carries statusUrl, free to read until status is fulfilled. Resending the same payment returns the same result.
npm install @circle-fin/x402-batchingimport { GatewayClient } from "@circle-fin/x402-batching/client";
const client = new GatewayClient({ chain: "base", privateKey: process.env.PRIVATE_KEY as `0x${string}` });
await client.deposit("1"); // once: move 1 USDC into Gateway
const { data } = await client.pay("https://api.d20dao.org/v1/random", {
method: "POST",
body: { operation: "dice", sides: 20, count: 2 },
});
console.log(data); // result, randomness, requestId, requestTx, fulfillmentTx, linksVerify a result
No trust in the API is needed.
- paymentId = keccak256(abi.encode(uint256 chainId, address payer, bytes32 nonce)) of the x402 authorization you signed.
- clientSeed = keccak256(abi.encode(bytes32 paymentId, string seed)) equals getRequest(requestId).clientSeed on the coordinator. A replacement request, opened if the first expires, uses keccak256(abi.encode(bytes32 ref, uint256 1)), where ref is the first clientSeed.
- getMappedResult(requestId) on the coordinator equals result.
- replayCoordinator in @d20dao/vrf-sdk re-derives randomness from the proof. links.proof opens the same replay in the Explorer.
Spec and contact
The OpenAPI 3.1 spec has every request and response schema, x-payment-info and x-guidance. POST https://api.d20dao.org/v1/random is the only paid route. Contact: contact@d20dao.org.
Work with your agents
Copy a task-specific prompt with the protocol references and integration rules.
View prompt
Get verifiable random numbers for my agent or application from the D20DAO agent API. Read these first; do not guess fields, prices or networks: - OpenAPI 3.1 spec: https://api.d20dao.org/openapi.json (the same document is at https://d20dao.org/openapi.json) - Guide: https://d20dao.org/docs/agents - Circle Gateway client: the @circle-fin/x402-batching package and its README POST https://api.d20dao.org/v1/random costs 0.05 USDC per call over x402, paid through Circle Gateway. Use GatewayClient.pay() from @circle-fin/x402-batching/client; the paying wallet needs a Gateway USDC balance on the network it pays from. Send operation and only the fields it uses, and ask for every value in one call. Never pay again to re-roll a result: resending the same payment returns the same result. On 202, read statusUrl (free) until status is fulfilled. Keep requestId, paymentId, seed, requestTx and fulfillmentTx with each result so it can be verified with getMappedResult on the coordinator and replayCoordinator from @d20dao/vrf-sdk. Keeper completion times on Arc Testnet are published at https://d20dao.org/benchmarks; they are observations, not an SLA. Do not create keys, deposit or spend funds without my explicit authorization. Report changed files, the calls made and anything unverified.