POST /v1/probe

Read a paid endpoint's 402 offer. Never pays it.

POST https://api.x402spend.dev/v1/probe
Content-Type: application/json

An x402 seller answers an unpaid request with 402 Payment Required and a body describing what it would cost. That body is public by construction — it is an offer, addressed to anyone — so reading it needs no key, no account and no wallet.

Try it in the browser.

Request

FieldTypeRequiredNotes
urlstringyesAbsolute http or https URL, max 2048 chars
{ "url": "https://api.onesource.io/api/chain/block-number" }

Response

{
  "ok": true,
  "url": "https://api.onesource.io/api/chain/block-number",
  "status": 402,
  "paid": true,
  "x402Version": 2,
  "resource": {
    "url": "https://api.onesource.io/api/chain/block-number",
    "description": "Latest Ethereum block height",
    "mimeType": "application/json"
  },
  "offers": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "1000",
      "payTo": "0x52E29e0d2Aa49bfBfC548C0A9F2196F4aa51f3ea",
      "maxTimeoutSeconds": 3600,
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ]
}
FieldNotes
urlThe URL actually read, after any redirect
statusThe HTTP status the endpoint returned
paidtrue exactly when status is 402
x402VersionAs published by the endpoint
resourceDiscovery metadata, when the endpoint publishes it
offersEvery entry in accepts[], capped at 20
notePresent when the body could not be read as x402

amount is read from amount (x402 v2) or maxAmountRequired (v1), so both generations parse. Amounts stay in atomic units: how many decimals that is belongs to the asset contract, which a probe does not read.

An endpoint that is not paid is reported as it answered rather than as an error — status: 200, paid: false — because "this URL is not behind a paywall" is a useful answer.

Refusals

A URL that will not be fetched comes back 200 with ok: false:

{ "ok": false, "reason": "refusing to probe a private or loopback address" }
Reason
only http and https URLs can be probedA file: or other scheme
refusing to probe a private or loopback addressLoopback, link-local, RFC 1918, or the metadata address
refusing to probe a URL carrying credentialsCredentials embedded in the URL
redirect <reason>A redirect pointed somewhere refused for one of the above
more than 1 redirect followedToo many hops
could not reach <host>: <message>Transport failure or timeout

A malformed url is 422 before any of this.

What it will not do

This route takes a URL from an unauthenticated caller and fetches it, which makes it a request forwarder and it is treated as one:

  • It never pays. One unauthenticated GET, no payment header, no signer, and no code path that could construct a payment.
  • It refuses private space — loopback, link-local, RFC 1918 and the cloud metadata address — by name, rather than leaving it to whatever the runtime happens not to route.
  • It re-checks redirects against the same rule. A redirect is the obvious way to walk a probe from a public host onto a private one.
  • It follows one hop, then stops.
  • It reads 64 KiB and then stops, so a large body cannot exhaust the isolate.
  • It stores nothing.