Developer docs · Stellar testnet

Build agent payments, verified.

Discover paid services, verify the payment interface, route by policy, settle standard Stellar x402 payments, and keep a receipt that links all of it together.

Environment
Base URL
api.relayx402.xyz
Network
stellar:testnet
Protocol
x402 v2
Scheme
exact
Asset
USDC · 7 dp
01 · Overview

What Relay does.

Relay is the operating layer around Stellar x402 payments. It is not a wallet and not a new protocol. Payment payloads stay standard x402; Relay adds the parts an autonomous buyer needs before and after the payment.

  • Discovery — a Bazaar-compatible catalog of machine-payable resources with capability, schema, network, asset, and price metadata.
  • Verification — active probes that check liveness and whether a service returns a valid x402 challenge.
  • Routing — deterministic provider selection with explicit rejection reasons.
  • Policy — hard spend and quality limits evaluated before any payment is authorised.
  • Receipts — a signed record linking intent, route, payment, and response hash.
Env

This deployment runs stellar:testnet. Mainnet operation uses separate relayer credentials, a separate signing account, and its own USDC contract configuration.

02 · Quickstart

From zero to a paid call.

Every step below runs against the live deployment. No API key is required for discovery, routing, or policy evaluation.

1. Check health and supported payment kinds

curl https://api.relayx402.xyz/health/ready
curl https://api.relayx402.xyz/x402/supported

2. Search for a service by capability

curl -X POST https://api.relayx402.xyz/v1/search \
  -H 'content-type: application/json' \
  -d '{"capability":"rwa.asset.inspect","network":"stellar:testnet","asset":"USDC","maxPriceUsd":0.005}'
Note

Price filters compare against worst-case spend, so an upto ceiling can never slip past maxPriceUsd.

3. Route by policy

State constraints instead of hard-coding a vendor. Relay returns the selection, ranked fallbacks, and a reason code for every rejection.

curl -X POST https://api.relayx402.xyz/v1/routes \
  -H 'content-type: application/json' \
  -d '{"capability":"rwa.asset.inspect","constraints":{"networks":["stellar:testnet"],"assets":["USDC"],"maxPricePerRequestUsd":0.005,"minProviderReliability":0.99},"optimizeFor":"balanced"}'

4. Trigger a real x402 challenge

curl -i -X POST https://atlas.relayx402.xyz/atlas/v1/rwa/inspect \
  -H 'content-type: application/json' \
  -d '{"asset":"USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN"}'

# HTTP/1.1 402 Payment Required
# PAYMENT-REQUIRED: <base64-encoded x402 challenge>

Your buyer signs locally — Relay never holds a private key.

03 · Facilitator

Standard x402 endpoints.

Relay settles on-chain itself. These three routes speak stock x402 — no Relay-specific payment fields are added or required — and network fees are sponsored, so a buyer needs only the asset being paid.

Protocol correctness (authorization-entry validation, simulation-event checking, fee ceilings) is delegated to the canonical @x402/stellar implementation. Reimplementing it would add risk without adding value. What Relay adds is the operator layer: idempotency, a durable settlement journal, sponsored-fee budgets, and policy enforcement.

GET

/x402/supported

Supported x402 payment kinds and signers for the configured network.

POST

/x402/verify

Verify a payment payload without settling it.

POST

/x402/settle

Submit a verified payment for settlement.

Note

Because the payload is stock x402, any @x402/stellar client works against these endpoints unmodified.

Multiple backends, with failover

Relay does not implement verify or settle itself, so a single hard-coded facilitator would be a single point of failure. Configure several and Relay picks one that actually advertises the requested network and scheme, falling through on failure.

RELAY_FACILITATORS='[
  {"id":"openx402","url":"https://facilitator.stellarx402.xyz"},
  {"id":"openzeppelin","url":"https://channels.openzeppelin.com/x402/testnet","apiKey":"..."}
]'

/x402/supported returns the union of every healthy backend's capabilities, de-duplicated by network and scheme. An unreachable backend is marked unhealthy and skipped rather than failing the request.

04 · Enforcement

Policy that a broken agent cannot skip.

Canonical x402 invariants are per-payment and protocol-level: the recipient is bound, and for upto the settled amount cannot exceed the authorized maximum. Nothing in the protocol constrains which provider an agent pays, how much it spends in aggregate, or whether the endpoint has ever been shown to work.

Those are buyer concerns, and they are normally enforced buyer-side — which means an agent that is buggy, compromised, or prompt-injected simply skips them. Relay checks them on the settlement path instead.

POST https://api.relayx402.xyz/x402/settle
{
  "paymentRequirements": {
    "payTo": "GAYVRGN5...",
    "amountUsd": 5,
    "relayPolicy": { "maxPricePerRequestUsd": 0.005 }
  }
}

403 Forbidden
{
  "error": "POLICY_DENIED",
  "code": "PRICE_EXCEEDS_LIMIT",
  "message": "Worst-case spend $5 exceeds per-request limit $0.005"
}
Key

Limits are measured against worst-case spend. For an upto option that means the authorized ceiling, not the amount the seller currently claims — so a $0.005 cap can never authorize a $5.00 payment.

Refusal codes

  • PRICE_EXCEEDS_LIMIT — worst-case spend above the per-request cap.
  • WINDOW_LIMIT_EXCEEDED — aggregate spend across providers would exceed the window budget.
  • PAYEE_NOT_VERIFIED — Relay has never observed a valid payment interface at the payee.
  • NO_VERIFICATION_EVIDENCE — no probe evidence exists for this payee at all.
  • CONFIDENCE_LIMIT / VERIFICATION_TOO_OLD — evidence too thin or too stale.
  • NETWORK_NOT_ALLOWED / ASSET_NOT_ALLOWED / SCHEME_NOT_ALLOWED / PROVIDER_DENIED.

Sponsored-fee budgets

Relay pays the Stellar network fee for every settlement it submits, which is a standing invitation to drain the sponsor account. A global ceiling and a per-principal ceiling bound the damage over a rolling window, charged at the fee ceiling rather than the actual fee so the budget can never be under-counted. Exceeding it returns 429 with FEE_BUDGET_EXHAUSTED.

05 · Verification

Evidence, not listings.

A scheduler probes every catalogued resource on an interval and records what it sees. Metrics are recomputed from that history — nothing is assumed, carried over, or seeded.

What a probe checks

A healthy payment interface requires a 402 carrying a decodable x402 challenge with at least one acceptable payment option. The advertised price, asset, and network are captured from that challenge, which is what makes price-drift detection possible.

How confidence works

Confidence combines sample size with freshness. Twenty stale probes and one fresh probe are both weak evidence, for different reasons — so a resource Relay has not seen recently decays to zero rather than coasting on old data.

  • reliability — 24-hour availability multiplied by payment-interface success rate.
  • confidence — 0 until there is current evidence; approaches 1 with sustained recent probes.
  • transactionSuccessRate — economic probes only. It stays 0 rather than being back-filled from liveness data.
  • priceConsistency — how often the advertised price matches the most recent observation.

Verification levels

Levels are earned from evidence, never declared. A resource starts at DISCOVERED and cannot reach level 4 from a single successful probe — CONTINUOUSLY_VERIFIED requires sustained evidence over time.

curl https://api.relayx402.xyz/v1/resources/svc_atlas_inspect/metrics
Why

A resource with no evidence reports confidence: 0, and policies reject it with INSUFFICIENT_DATA. That is a truthful answer, not a placeholder.

POST

/v1/validate

Probe an endpoint now and record the observation.

GET

/v1/resources/:id/metrics

Metrics computed from recorded observations.

GET

/v1/resources/:id/observations

The raw evidence behind the metrics.

06 · Discovery

Find services machines can buy.

Discovery answers which resources exist and what they expose. Records carry provider, price, network, asset, input and output schema, status, and verification level.

GET

/v1/resources

List every catalog record.

GET

/v1/resources/:id

Fetch one record with its current metrics.

POST

/v1/search

Filter by capability, network, asset, and max price.

POST

/v1/validate

Probe an endpoint and record the observation.

GET

/v1/resources/:id/metrics

Reliability, confidence, latency, and success rates.

GET

/v1/resources/:id/observations

Raw probe history behind the metrics.

07 · Routing & policy

Spend limits that are enforced.

An agent states constraints instead of hard-coding a vendor. Relay filters candidates, ranks the survivors, and returns the selection alongside fallbacks and a reason code for every rejection.

Route request
{
  "capability": "rwa.asset.inspect",
  "constraints": {
    "networks": ["stellar:testnet"],
    "assets": ["USDC"],
    "maxPricePerRequestUsd": 0.005,
    "minProviderReliability": 0.99,
    "minConfidence": 0.75,
    "requireTransactionVerified": true
  },
  "optimizeFor": "balanced"
}

optimizeFor accepts balanced, cheapest, fastest, or reliable. Rejections come back as codes such as PRICE_EXCEEDS_LIMIT, RELIABILITY_LIMIT, or SERVICE_OFFLINE, so a refusal to spend is always explainable.

POST

/v1/routes

Rank eligible providers under a policy.

POST

/v1/policies/evaluate

Dry-run one policy against one resource.

08 · Receipts

An auditable paper trail.

A commerce receipt binds the request intent, the routing decision, the service that was chosen, the payment metadata, and a hash of the response. It answers “why did this agent spend this money here” after the fact.

Verifiable without trusting Relay

Receipts are signed with an Ed25519 Stellar keypair over the canonical JSON of the receipt body. The signing public key travels with the receipt, so anyone holding one can verify it offline — no shared secret, no call back to Relay.

import { Keypair } from "@stellar/stellar-base";

// Deterministic serialization: keys sorted, undefined dropped.
const canon = (v) =>
  v === null || typeof v !== "object"
    ? JSON.stringify(v ?? null)
    : Array.isArray(v)
      ? "[" + v.map(canon).join(",") + "]"
      : "{" + Object.entries(v)
          .filter(([, x]) => x !== undefined)
          .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
          .map(([k, x]) => JSON.stringify(k) + ":" + canon(x))
          .join(",") + "}";

const { relaySignature, relaySigner, signatureAlgorithm, ...body } = receipt;

const valid = Keypair.fromPublicKey(relaySigner).verify(
  Buffer.from(canon(body), "utf8"),
  Buffer.from(relaySignature, "base64")
);
Note

Deployments without a signer key fall back to HMAC. Those receipts are attestations, not proofs — only Relay can check them. /v1/receipts/signer tells you which mode a deployment is in.

POST

/v1/receipts

Create a signed receipt for a completed purchase.

GET

/v1/receipts/:id

Fetch a receipt by id.

GET

/v1/receipts/:id/verify

Check a receipt's signature.

GET

/v1/receipts/signer

The Ed25519 public key receipts are signed with.

09 · Atlas

The first paid vertical.

Atlas is x402-gated Stellar RWA intelligence — the reference implementation of a service that is discoverable, verifiable, routable, and payable through Relay.

POST

/atlas/v1/rwa/inspect

Asset identity, issuer signals, metadata, and technical state.

POST

/atlas/v1/rwa/changes

Recent observable changes for an asset.

POST

/atlas/v1/rwa/compliance

Observable technical restrictions, without legal conclusions.

POST

/atlas/v1/rwa/eligibility

Technical wallet eligibility signals.

10 · MCP

Discovery for agents.

The MCP server mirrors the public HTTP surface so an MCP client can find and qualify a paid service without bespoke integration code.

Tools
search_resources
get_resource
validate_endpoint
route_resource
get_resource_health
get_resource_metrics
10 · Evidence

Claims you can check.

Relay settles real payments. These are the transactions, on a public explorer, produced by the harness in the repository rather than by hand.

SETTLED

8b5e7f01dc…b25aa2

Issued asset (USDC)
0.001 USDC · ledger 4103178 · trustline path exercised

SETTLED

2b090d7bbb…c1c5fc

Public deployment
Settled through api.relayx402.xyz · ledger 4102990

SETTLED

e748998671…82f37d

First settlement
Ledger 4102795 · fee paid by the facilitator

SETTLED

6a9f2043ba…bfcfc7

Repeatability
Ledger 4102861 · same harness, second run

Balance deltas confirm both the transfer and fee sponsorship: the seller gained exactly the amount paid, and the buyer lost exactly that amount with no fee deducted. The buyer was the canonical @x402/fetch client with no Relay-specific code, so these are wire-compatibility results too.

Gaps

upto, pubnet settlement, and a security audit are not demonstrated. Authorization-required, clawback-enabled, and paused assets are untested. The repository's EVIDENCE.md lists every gap explicitly.

11 · API reference

Every public endpoint.

Generated from the same OpenAPI 3.1 document the API serves, so this table cannot drift from the implementation.

Health

GET

/health/live

Check liveness

GET

/health/ready

Check readiness

GET

/health/dependencies

Inspect backing services

Facilitator

GET

/x402/supported

List supported payment kinds

POST

/x402/verify

Verify a payment payload

POST

/x402/settle

Settle a verified payment

GET

/x402/facilitators

Inspect facilitator health

Discovery

GET

/v1/resources

List catalogued resources

GET

/v1/resources/{id}

Resolve one resource

POST

/v1/search

Search resources

Verification

POST

/v1/validate

Probe an endpoint

GET

/v1/resources/{id}/metrics

Get resource metrics

GET

/v1/resources/{id}/observations

List raw probe observations

Routing

POST

/v1/routes

Route by policy

POST

/v1/policies/evaluate

Dry-run a policy against one resource

Receipts

POST

/v1/receipts

Create a commerce receipt

GET

/v1/receipts/signer

Get the receipt signing key

GET

/v1/receipts/{id}

Fetch a receipt

GET

/v1/receipts/{id}/verify

Verify a receipt signature

13 · Protocol links

Protocol references.

Use these docs for Relay's hosted infrastructure and product APIs. Use upstream documentation for protocol-level semantics and SDK behaviour.