Skip to content
How it worksDevelopersDocsProtocol

Documentation

Receipts & webhooks

What a settled payment hands back, and how to receive events when value moves.

Every settled payment produces a signed, on-chain receipt. Webhooks push those events to your backend so you can react the moment value moves. Payloads below are conceptual shapes with placeholder values.

The receipt object

A receipt is the canonical record of a payment. It links the amount and recipient back to the policy that authorized it, which is what makes spend auditable.

ParamTypeDescription
idstringStable receipt id, e.g. "rcpt_8fK2c9Qd".
agentaddressThe paying agent's wallet address.
tostringDestination service:// or agent:// address.
amountstringSettled amount, in the receipt's currency.
currencystringSettlement asset, e.g. "USDC".
policyIdstringThe policy that authorized this payment.
settledbooleanTrue once value has settled on-chain.
txstringOn-chain transaction hash.
signaturestringSignature over the receipt contents.
receipt.json
{
  "id": "rcpt_8fK2c9Qd",
  "agent": "0xAgent7d2…",
  "to": "service://api.search",
  "amount": "0.02",
  "currency": "USDC",
  "network": "solana",
  "policyId": "pol_2u9X…",
  "settled": true,
  "tx": "0x9b1f…c20a",
  "signature": "0xsig…",
  "createdAt": "2025-01-01T00:00:00Z"
}

Event types

Railo emits a small set of events over the lifecycle of a payment:

  • payment.settled - a payment passed the gate and settled successfully.
  • payment.rejected - a payment was denied at the policy gate (with the failing rule).
  • policy.updated - an agent's policy was changed by its owner.

Webhook payload shape

Each event is delivered as a JSON envelope with a type, an event id, and a data object carrying the relevant record.

event.json
{
  "type": "payment.settled",
  "id": "evt_3aZ…",
  "data": {
    "receiptId": "rcpt_8fK2c9Qd",
    "agent": "0xAgent7d2…",
    "to": "service://api.search",
    "amount": "0.02",
    "currency": "USDC",
    "tx": "0x9b1f…c20a"
  },
  "createdAt": "2025-01-01T00:00:00Z"
}

Verifying webhooks

Every delivery is signed. Verify the railo-signature header against your endpoint secret before trusting an event - this prevents spoofed deliveries.

webhook.ts
import { Railo } from "@railo/sdk";

// Verify the signature before trusting an event.
export function handler(req: Request, body: string) {
  const ok = Railo.webhooks.verify({
    payload: body,
    signature: req.headers.get("railo-signature") ?? "",
    secret: process.env.RAILO_WEBHOOK_SECRET!,
  });
  if (!ok) return new Response("bad signature", { status: 400 });
  // …handle event
  return new Response("ok");
}
Always verify before acting
Treat an unverified payload as untrusted input. Confirm the signature, then look up the receipt on-chain if you need an authoritative source of truth.