Wire protocol

HTTP 402 guide (proxy)

Decode PAYMENT-REQUIRED, sign an XRPL Payment, retry with PAYMENT-SIGNATURE, then read PAYMENT-RESPONSE. Default proxy: ledger before origin. Example path /api/v1/investor-demo. This page is the exact XRP Payment path. PayChan, allowlisted RLUSD, and Base USDC: /developers#schemes and /terms#rail. Facilitator contrast: /legal#trust.

Back to Developers →

Step 1

Unpaid request

Expect status 402, header PAYMENT-REQUIRED (base64 JSON, not a signature), and SLUZEN-CALL-ID when present. Body: { error, message, callId? }.

curl -sS -D - -o /dev/null "https://api.sluzen.network/api/v1/investor-demo"

Step 2

Decode the challenge

npm i @sluzen/sdk, then decodeChallenge(headerValue). Read amount (drops), destination (r…), nonce, expiration (~15 min TTL), currency/network, optional accepts[] and callId.

import { decodeChallenge } from "@sluzen/sdk";
const challenge = decodeChallenge(process.env.ENCODED!);

Step 3

Sign with AgentClient

Production path: AgentClient. Env: CLIENT_WALLET_SEED, XRPL_NODE. Memo type sluzen/challenge-nonce. Seeds stay on your machine.

import { AgentClient } from "@sluzen/sdk";

const client = new AgentClient({ baseUrl: "https://api.sluzen.network" });
const res = await client.request("/api/v1/investor-demo");

Step 4

Paid retry

Same URL, header PAYMENT-SIGNATURE = signed tx blob. Success: 200, PAYMENT-RESPONSE = ledger tx hash, SLUZEN-CALL-ID stable for this challenge.

Failures

Challenge vs settle-fail

402 with PAYMENT-REQUIRED: new quote; sign this one. 402 without that header: bind/settle failure; do not blindly re-sign the same blob. Also 409 replay, 429 issuer quota, challenge expired (~15 min). New unpaid GET → new nonce + callId; paid retry reuses the challenge until consumed or expired. Facilitator settle posts once; a lost timeout after the handler is ambiguous, confirm via callId before a fresh challenge (same signature again is 409, not a soft retry).

Evidence

Verify settlement

Use Proof or the XRPL explorer for a full 64-hex hash (livenet.xrpl.org / testnet.xrpl.org). Paying agents can also call verifyBuyerPayment in @sluzen/sdk against their own XRPL_NODE (see /developers).

Observability

callId

callId is PaymentChallenge.id; wire header SLUZEN-CALL-ID. Issuers: export events by callId via GET /admin/calls (Bearer, out of band). Proxy records delivery; facilitator does not. Not the public rail OpenAPI.

CALL_OBSERVABILITY.md →