Base URL
stellar:testnet. A self-hosted instance listens on port 8080 by default. Every
endpoint speaks JSON except /metrics, which serves the Prometheus text format.
/verify and /settle take the body the stock x402 HTTPFacilitatorClient sends:
{ x402Version, paymentPayload, paymentRequirements }. Point the client at the base URL and it calls these
endpoints itself; you rarely call them by hand.
Authentication
The hosted testnet instance needs no key. A self-hosted operator can require one per network (REQUIRE_API_KEY), which then applies to /verify and /settle. /usage always requires one. Send it as
either header:
createAuthHeaders:
Conventions
- Amounts are strings of integers in the asset’s base units. Stellar USDC has 7 decimals, so
"100000"is 0.01 USDC. Nothing is ever converted through floating point. - Networks are CAIP-2 identifiers:
stellar:testnet,stellar:pubnet. - Addresses are Stellar strkeys:
G…accounts,C…contracts,M…muxed accounts. - Timestamps are ISO 8601 in UTC.
Errors
Payment rejections are HTTP 200 bodies, as x402 requires:isValid: false with invalidReason and
invalidMessage from /verify, success: false with errorReason and errorMessage from /settle. The
reason is always a stable code, and the message is never empty.
Everything else is an HTTP error with a body of this shape:
/verify and /settle, transport errors (malformed body, missing key, oversized body, wrong content type,
rate limit) keep the x402 fields too, so the stock client raises a typed VerifyError or SettleError.
Every code, the check that produces it and the test that proves it are listed in
Errors and verification rules.
Rate limits
Every endpoint except/health, /ready and /metrics is limited per client address. A limited request
gets HTTP 429, a Retry-After header in seconds and the code rate_limited.