Use https://x402-tokens.fly.dev as an OpenAI-compatible inference endpoint. There is no API key, no account and no subscription. You pay per request, and only for requests you make. POST https://x402-tokens.fly.dev/v1/chat/completions Content-Type: application/json Body is a normal OpenAI-shaped chat completion: {"model":"google/gemini-2.5-flash","messages":[{"role":"user","content":"..."}],"max_tokens":256} IMAGE AND VIDEO ARE ALSO SERVED, on their own endpoints. /v1/chat/completions cannot emit them — do not conclude from a text response that this endpoint has no media. Same 402 and same rails; billed per image or per clip, not per token. POST https://x402-tokens.fly.dev/v1/images/generations {"model":"black-forest-labs/FLUX.1.1-pro","prompt":"...","width":1024,"height":1024} -> {"data":[{"url":"https://..."}]} POST https://x402-tokens.fly.dev/v1/videos/generations {"model":"Wan-AI/wan2.7-t2v","prompt":"...","seconds":5,"resolution":"720P"} -> {"id":"...","status":"in_progress"} resolution is "720P" or "1080P" GET https://x402-tokens.fly.dev/v1/videos/{id} -> {"status":"completed","outputs":{"video_url":"https://..."}} Polling is FREE — the render was paid for at submit. Poll until status leaves "in_progress"; a failed job explains itself in error.message. GET /v1/models lists these alongside the text models, tagged kind:"image" or kind:"video" with the per-unit price. leCore memory does NOT apply to a render (a prompt that short never spills) — do not claim it improved the output. You will get HTTP 402. That is the product, not an error. accepts[] will include one row per offered rail. Pick ONE: - USDC mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp decimals 6 0bps tax price $1 stable - TOKEN mint EVULoNF4DeMBN4dGiZiDfpiiTfNZgoCvXWWgaV3epump solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp decimals 6 0bps tax price Birdeye EVULoNF4DeMBN4dGiZiDfpiiTfNZgoCvXWWgaV3epump at the 402 - LEOS mint 5xgsnby6P9zqGK71J7H4yJLxzqPvNbC7rDZxNzjHmj7e solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp decimals 9 0bps tax price Birdeye 5xgsnby6P9zqGK71J7H4yJLxzqPvNbC7rDZxNzjHmj7e at the 402 - USDC token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 eip155:8453 decimals 6 0bps tax price $1 stable - USDG token 0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 eip155:4663 decimals 6 0bps tax price $1 stable - USDC token 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 eip155:137 decimals 6 0bps tax price $1 stable - USDC token 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 eip155:42161 decimals 6 0bps tax price $1 stable - USDC token 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 eip155:10 decimals 6 0bps tax price $1 stable - USDC token 0x79A02482A880bCE3F13e09Da970dC34db4CD24d1 eip155:480 decimals 6 0bps tax price $1 stable Every row carries its OWN network, payTo and decimals. READ THEM OFF THE ROW — they are NOT the same across rails: - network: the row's "network" (Solana CAIP-2, or eip155:) - payTo: the row's "payTo". Solana rows carry a base58 address; eip155 rows carry a 0x address. They are different addresses. Never reuse one for the other. - extra.decimals: the raw-unit exponent OF THAT ASSET. It is 6 on some rails and 18 on others. Do not assume. - maxAmountRequired: the final amount ALREADY in that asset's raw units, grossed up for its transfer tax. Do not reprice it and DO NOT multiply it by 10^decimals — that is already done. extra.decimals is for display only. - extra.feePayer: Solana rows only. - extra.pricing: "counterfactual" = a DISCOUNT off what this exact body would cost you buying direct (extra.directUsd, extra.savesVsDirect), never a markup on it. "markup" = the body was small enough that there was nothing to compress, so the price is built off our own measured cost of serving it and extra.markup names the effective multiple. Long context is cheaper HERE than direct because leCore memory means we never forward the whole body. - facilitator: https://x402.accrue.fund IF THE ROW YOU PICKED IS A SOLANA ROW — build one legacy Transaction: 1. feePayer = the row's extra.feePayer (WzMaL78srutrF6CsxEkWuhMaDF5HZA6jNRaEPengqpb) ← you do not pay SOL. 2. exactly one Token-2022 TransferChecked: your ATA of the chosen mint → payTo's ATA, amount = maxAmountRequired (raw, as given), decimals = the row's extra.decimals ← read it off the row, do not hardcode 3. you sign as the token owner. leave the feePayer signature empty. 4. serialize requireAllSignatures=false, base64 those bytes X-PAYMENT header = base64 of this JSON (utf8): {"x402Version":1,"scheme":"exact","network":"","payload":{"transaction":""}} IF THE ROW YOU PICKED IS AN eip155 ROW — sign EIP-3009, send no transaction: 1. you pay NO gas. The facilitator relays your signature and pays it. 2. EIP-712 typed-data sign TransferWithAuthorization with domain {name: extra.name, version: extra.version, chainId: , verifyingContract: the row's asset} ← name/version come off the ROW. Guessing them recovers a different address and the payment is rejected as "signature does not match payer". 3. message = {from: , to: , value: maxAmountRequired (raw uint256, VERBATIM — no decimal scaling, this is where an agent loses 10^12), validAfter: 0, validBefore: , nonce: } X-PAYMENT header = base64 of this JSON (utf8): {"x402Version":1,"scheme":"exact","network":"","payload":{"signature":"0x…","authorization":{"from":"0x…","to":"0x…","value":"","validAfter":"0","validBefore":"","nonce":"0x…"}}} POST the SAME body again with X-PAYMENT set. Do not change model/messages/max_tokens after the 402 — the quote is for that body. On 200 you get a normal chat.completion. THERE IS NO WRAP STEP ON ANY RAIL. Every accepts[] row is the asset you already hold: pay it directly, at the mint in the row. Read asset, decimals and payTo OFF THE ROW you picked — they differ per rail and LEOS is nine decimals, not six. maxAmountRequired is already in that asset's raw units; do not rescale it. On the eip155 rails you pay no gas — the facilitator relays your signature. Do not use api.cdp.coinbase.com. This service names https://x402.accrue.fund. GET https://x402-tokens.fly.dev/.well-known/x402.json and https://x402-tokens.fly.dev/prompt.txt if you want this text again.