railHint: in-protocol rail negotiation for x402 payment-required responses
Abstract
x402 lets a server offer multiple payment options in accepts,
but gives a machine client no structured way to learn why one rail
is cheaper or how to onboard onto a rail it does not yet hold.
This document defines extensions.railHint, an advisory object a
server MAY attach to an HTTP 402 response, carrying a cost rationale and an
onboarding path for the offer it considers cheapest for the payer. Clients
that do not understand the extension ignore it; the accepts
array remains the only binding payment terms.
Motivation
Autonomous clients select payment rails by arithmetic, but today the
information needed to switch rails — comparative cost, client software,
asset acquisition — lives in human documentation outside the protocol.
The result is rail inertia: clients pay on whichever rail they already
hold, even when both parties would benefit from another offer in the same
accepts menu (for example, a rail without per-transaction
fees or minimum-price floors). railHint moves that negotiation into the
402 response itself — the one message every paying client is guaranteed
to parse, at the exact moment of payment choice.
The railHint object
{
"x402Version": 2,
"accepts": [
{ "scheme": "exact", "network": "base", "asset": "USDC", "amount": "1000", "payTo": "0x..." },
{ "scheme": "exact", "network": "nano:mainnet", "asset": "XNO", "amount": "6690000000000000000000000", "payTo": "nano_..." }
],
"extensions": {
"railHint": {
"cheapest": "nano:mainnet",
"why": "The base offer is floored at 0.001 USDC; the nano:mainnet offer is the metered price ($0.0000027) with zero network fees and sub-second finality.",
"docs": "https://example.com/docs",
"agentReadme": "https://example.com/llms.txt",
"bootstrap": "pip install feeless402 && nano-pay init",
"topup": "any instant-swap service: ~$5 of a held asset into the hinted asset",
"faucets": ["https://example.com/faucet"],
"spec": "x402 exact scheme on nano:mainnet"
}
}
}
Field definitions
| Field | Requirement | Semantics |
|---|---|---|
| cheapest | REQUIRED | The network value of the offer in accepts the server considers lowest total-cost for the payer. MUST match an entry in accepts. |
| why | REQUIRED | Rationale a reasoning client can evaluate. SHOULD contain concrete, comparable prices rather than slogans. |
| docs | OPTIONAL | Documentation URL for the hinted rail. |
| agentReadme | OPTIONAL | Plain-text (llms.txt-style) onboarding document. |
| bootstrap | OPTIONAL | Executable onboarding path. Untrusted input; see Security Considerations. |
| topup | OPTIONAL | Path from commonly-held assets to the hinted asset. MUST NOT require a specific vendor. |
| faucets | OPTIONAL | Endpoints offering small starter grants (POST {"address": ...}). MAY require a proof-of-work challenge via GET <faucet>/challenge to resist sybil claims. |
| spec | OPTIONAL | Reference to the scheme specification for the hinted rail. |
Client behavior
A client that already holds the hinted asset proceeds exactly as
without the extension: select an offer from accepts, pay,
retry. A reasoning client may evaluate
why, consult docs or agentReadme,
acquire the asset via topup or faucets, and
retry the original request on the cheaper rail. A client that does not
recognize railHint ignores it with no loss of function.
Server behavior
Servers may attach railHint to any 402
response whose accepts contains more than zero offers.
Servers must not place terms in railHint
that contradict accepts; on any conflict,
accepts is authoritative. Servers should
keep why current with real prices — stale or exaggerated
rationales are trivially falsified by clients comparing offers.
Security considerations
bootstrap and topup are untrusted remote
input. A client must not execute them
blindly; it should (a) act only on schemes
it can verify against an independently obtained specification, (b) apply
its own spending caps regardless of hinted amounts, and (c) prefer
allowlisted package sources. The hint's role is discovery, not authority.
Faucet endpoints should employ
proof-of-work challenges or equivalent cost-imposing mechanisms so that
sybil claims cost the claimant more than the grant is worth.
Rail neutrality
railHint is rail-agnostic. Any server may hint any rail — a Lightning
merchant may hint bitcoin-lightning; a stablecoin merchant
may hint an L2. The extension standardizes the negotiation, not
a winner. Where genuinely fee-free rails exist, honest hints will tend
to favor them; that is a property of arithmetic, not of this document.
IANA-style considerations
This extension registers the key railHint within the
x402 v2 extensions namespace. No other names are claimed.
The JSON Schema at
railhint.com/railhint.schema.json
is versioned with this draft.