Documentation
SDK reference
The core methods, their parameters, and the shapes they return. All values are illustrative placeholders.
The SDK is intentionally small: create an agent, pay, update policy, fetch a receipt. Each method is documented with its signature, parameters, and an example response.
railo.createAgent()
Creates an agent - a wallet plus an on-chain policy. Returns an Agent with its address and a bound pay() method.
| Param | Type | Description |
|---|---|---|
| policy.dailyLimit* | string | Rolling 24h spend ceiling, in USDC (e.g. "50.00"). |
| policy.perCall* | string | Hard cap on any single payment, in USDC. |
| policy.allow* | string[] | Allowlist of service:// and agent:// addresses. |
| label | string | Optional human-readable name for the agent. |
const agent = await railo.createAgent({
// The owner sets the policy; the contract enforces it.
policy: {
dailyLimit: "50.00", // USDC, rolling 24h
perCall: "0.05", // hard ceiling per payment
allow: [
"service://api.search",
"service://api.embed",
],
},
});
console.log(agent.address); // 0xAgent… (the agent's on-chain wallet)agent.pay()
Submits a payment from the agent to a destination. The policy gate validates the rules on-chain; on success it resolves to a settled Receipt, and on a rule violation it throws a RailoPolicyError.
| Param | Type | Description |
|---|---|---|
| to* | string | Destination service:// or agent:// address. Must be in the policy allowlist. |
| amount* | string | Amount in USDC (e.g. "0.02"). Must be ≤ perCall and within the daily limit. |
| memo | string | Optional note recorded alongside the receipt. |
const receipt = await agent.pay({
to: "service://api.search",
amount: "0.02", // a fraction of a cent, in USDC
});
// Settled instantly, signed, and traceable to the policy that allowed it.
console.log(receipt.id); // rcpt_8fK2c…
console.log(receipt.settled); // trueReceipt object - see railo.getReceipt() below for the full shape.agent.policy.update()
Updates an agent's policy. Requires the owner key - an agent cannot raise its own limits. Only the fields you pass are changed.
| Param | Type | Description |
|---|---|---|
| dailyLimit | string | New rolling 24h ceiling, in USDC. |
| perCall | string | New per-payment cap, in USDC. |
| allow | string[] | Replacement allowlist of destinations. |
// Only the owner key can change policy. Agents cannot raise their own limits.
await agent.policy.update({
dailyLimit: "120.00",
allow: [
"service://api.search",
"service://api.embed",
"service://api.rerank",
],
});railo.getReceipt()
Fetches a receipt by id. Receipts are immutable and on-chain - this is a read.
| Param | Type | Description |
|---|---|---|
| id* | string | The receipt id, e.g. "rcpt_8fK2c9Qd". |
const receipt = await railo.getReceipt("rcpt_8fK2c9Qd");
console.log(receipt.to); // service://api.search
console.log(receipt.amount); // "0.02"
console.log(receipt.settled); // trueExample response:
{
"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"
}Policy errors
When a payment violates policy, agent.pay() throws a typed RailoPolicyError with a stable code you can branch on. Common codes:
| Param | Type | Description |
|---|---|---|
| policy/service_not_allowed | code | Destination isn't in the allowlist. |
| policy/per_call_exceeded | code | Amount is above the per-call cap. |
| policy/daily_limit_exceeded | code | Payment would exceed the rolling daily limit. |
| policy/unsigned | code | Policy isn't signed by the owner key. |
// A call that violates policy never settles - it reverts at the gate.
try {
await agent.pay({ to: "service://api.unknown", amount: "0.02" });
} catch (err) {
// RailoPolicyError: service not in allowlist
console.error(err.code); // "policy/service_not_allowed"
}