Guide: Buy a call (pay a paid endpoint)
For a buyer agent. No account, no API key. You need a funded wallet (USDC on the endpoint’s network) able to sign.
Prefer the connector? If you’ve connected the management MCP (Connect in Claude), you can discover and buy right there — it pays from a managed wallet so you never build an
X-PAYMENTby hand. See Buying with the connector.This page is the raw x402 flow for accountless agents that hold their own wallet and sign payments directly.
1. Find an endpoint
- Browse the machine-readable marketplace:
GET /discover.json - One provider’s endpoints:
GET /u/{provider}.json - A listing + its input/output schema:
GET /e/{provider}/{endpoint}andGET /e/{provider}/{endpoint}/schema.json
Each listing gives you a relay URL (/r/{provider}/{endpoint} for an API
relay, or /m/{provider}/{server} for an MCP wrapper).
1.5 See the data shape before paying (free)
You don’t have to pay to learn what an endpoint returns. Every listing exposes a free, unauthenticated data sample — a JSON Schema plus an example — so an agent can decide if the endpoint fits.
GET /e/{provider}/{endpoint}/schema.json:
{
"name": "Weather",
"method": "GET",
"input_schema": { "city": "SF" },
"output_schema": {
"type": "object",
"properties": {
"tempC": { "type": "integer", "minimum": -40, "maximum": 50 },
"city": { "type": "string" },
"updated":{ "type": "string", "format": "date-time" }
}
},
"example": { "tempC": 12, "city": "string", "updated": "2024-01-15T09:30:00Z" },
"sample": { "protection": "synthetic", "provenance": "live", "freshness": "fresh" }
}
How an agent should read it:
output_schemais standard JSON Schema — validate/plan against it directly.exampleshows a concrete row. By defaultsample.protectionissynthetic: the values are fabricated, only the structure is real. Don’t treat the example values as real data.sampleaxes let you weigh trust: preferfreshness: "fresh"; aprovenance: "declared"schema came from the provider’s word rather than a live call, so it’s lower-confidence;protection: "real"means the example is the real response (open-data endpoints).- Need to see real data to decide? Use a free trial (next section) if the endpoint offers one.
2. Make the unpaid request → get a 402
The same sample travels in the 402 body, alongside any free-trial offer, so an agent that just hits the relay gets everything it needs in one response.
GET /r/acme/weather HTTP/1.1
Host: api.datapoint.market
Response: HTTP 402 with an accepts array. Each entry tells you, for one
(scheme, network):
scheme:exactnetwork: e.g.eip155:8453(Base mainnet),stellar:pubnet, orsolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpasset: the USDC contract/asset id on that networkmaxAmountRequired: total in atomic units (price + fee; 6 dp on Base and Solana, 7 on Stellar)payTo: the splitter address (you pay the splitter, not the provider)- plus the resource id and a per-payment nonce/validity window
The body also carries:
endpoint— the sample “what you get” block:name,description,outputSchema,example,exampleSource,sample(the protection/provenance axes), andverified.freeTrial— present when the endpoint offers unpaid trial calls:{ "available": true, "remaining": 3, "total": 5 }.
Pick the option for a network you can pay on — or take a free trial first.
1.9 Request a free trial (real data, no payment)
If the 402 body shows freeTrial.available: true, you can get real data for
free, up to the offered quota — no wallet, no signature. You request a trial
simply by making the unpaid call: when a trial is available the relay forwards
one real call and returns the origin’s actual response instead of a 402, with:
X-Datapoint-Trial: trueX-Datapoint-Trial-Remaining: <n>— trials left for you (metered per IP)
When your quota is spent (or the endpoint’s daily cap is hit), the same unpaid
call returns the normal 402 and you pay from there. Trials are a discovery aid,
offered only on live, side-effect-free endpoints — treat them as best-effort,
not guaranteed.
GET /r/acme/weather HTTP/1.1
Host: api.datapoint.market
Response: HTTP 402 with an accepts array. Each entry tells you, for one
(scheme, network):
scheme:exactnetwork: e.g.eip155:8453(Base mainnet),stellar:pubnet, orsolana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpasset: the USDC contract/asset id on that networkmaxAmountRequired: total in atomic units (price + fee; 6 dp on Base and Solana, 7 on Stellar)payTo: the splitter address (you pay the splitter, not the provider)- plus the resource id and a per-payment nonce/validity window
Pick the option for a network you can pay on.
3. Build and sign the X-PAYMENT
The authorization you sign differs by chain family (the payload binds you to the exact amount, splitter, provider, and nonce so it can’t be replayed or altered):
- Base / EVM: sign an EIP-3009
receiveWithAuthorizationover the USDC EIP-712 domain (mainnet name"USD Coin", version2). Gasless for you — the relayer submits it. - Stellar: sign a Soroban authorization entry for the splitter’s
settleinvocation (simulate with the relayer as source to obtain the entry, then sign).
Base64url-encode the envelope ({x402Version, scheme, network, payload}) into the
X-PAYMENT header. (See scripts/live_settle_base_mainnet.py and
scripts/live_settle_stellar_testnet.py in the repo for exact, working
constructions — these are the reference buyer implementations.)
4. Resend with the header
GET /r/acme/weather HTTP/1.1
X-PAYMENT: <base64url envelope>
The relay verifies your signature, settles on-chain (the splitter pays the provider + fee atomically), forwards to the origin, and returns:
- the origin’s response body + status
X-PAYMENT-RECEIPTheader — base64 JSON with the on-chaintx_hashand block
Parameterized endpoints
Pass inputs as query parameters on the relay URL — they reach the origin: they
fill any {placeholder} in the origin’s path and pass through as query string. For
example GET /r/acme/country-profile?iso3=USA calls the origin’s
/countries/USA/profile. The endpoint’s sample (schema.json / the 402 body)
shows the example input, so an agent knows which params to send. The same query
goes on the unpaid call (for the 402 and for a free trial) and the paid call.
Errors you may see
| Status | Meaning | What to do |
|---|---|---|
| 400 | your request is missing a param the origin needs | fix the request — see help below |
| 402 | payment required / your payment was rejected | (re)build a valid X-PAYMENT |
| 403 | origin auth / SSRF guard | not payable as configured; contact provider |
| 409 | replay — this authorization was already settled | build a fresh one (new nonce) |
| 503 | that network isn’t configured for settlement | use a different network from accepts |
| 502 | settled but origin failed | retry; settlement is idempotent per nonce |
Errors are self-healing. Origin/param failures (and 404s) carry a help
block so you can recover without leaving the response:
{ "detail": "your request is missing a parameter the origin needs: iso3",
"origin_status": "bad_request",
"help": {
"input_example": { "iso3": "USA" },
"schema": "https://api.datapoint.market/e/{provider}/{endpoint}/schema.json",
"listing": "https://datapoint.market/u/{provider}/{endpoint}",
"docs": "https://datapoint.market/docs/guides/buying" } }
Diff your request against help.input_example (the exact params a known-good
call uses), or fetch help.schema for the full input/output contract.
origin_status distinguishes YOUR error (bad_request — fix and retry) from
origin trouble (unavailable — back off and retry later). Failed trial calls
never consume trial quota.
Tips for agents
- Decide on the schema, not the example values. When
sample.protectionissynthetic/redacted, the example values are fabricated/masked — only the shape is real. - Try before you pay. If
freeTrial.available, make the unpaid call to get real data and checkX-Datapoint-Trial-Remaining; pay once you’re satisfied. - Always read
acceptsfresh before signing — price/nonce can change between calls. - Match decimals to the chain (6 Base, 7 Stellar) or you’ll be off by 10×.
- One authorization = one call. Reusing it returns 409.