Skip to main content
Four ideas carry the whole API. Learning them takes about five minutes and makes everything else predictable.

A rail is a rail

A rail is how value moves. A blockchain and a bank network are the same kind of object: both have an address format, a settlement time, a fee model, and a set of failure modes.
GET /rails returns the live set. Rail identifiers are open strings, not a fixed enum, and new rails appear without an SDK release. Any switch you write over a rail needs a default.
Some rails support only one direction. Check directions before using a rail as a destination.

An endpoint describes both ends

One shape covers a blockchain address, a bank account, a card, and an internal balance. Sources and destinations use the same type: direction is a property of the transfer, not of the type.
The practical consequence: once you can accept money, you can send it. Paying out is the same call with the endpoints the other way round.

Assets are namespaced

crypto:USDC, fiat:NGN, credit:acme:ai_tokens. An asset is a symbol at the model layer, resolved to a contract address, issuer, or mint by the registry per rail. That is what lets one intent quote across eight chains without eight asset identifiers.
The same symbol has a different scale on different rails. USDC is 6 decimals on EVM and 7 on Stellar. Never hardcode a scale: take it from the registry.
Amounts are always decimal strings, always paired with an asset. Never a float, never a bare number.

Two funding primitives

Funding intent

One funding event. Has an amount or is open, expires, and terminates. Use for checkout and anything invoice shaped.

Funding address

A persistent, reusable receive endpoint bound to a destination. Any deposit creates an intent automatically. Use for user deposit addresses.
They share one settlement path, so everything downstream behaves identically.

Legs and routes

A route is an ordered list of legs. Each leg has a kind describing what it does, separate from the provider performing it. You never choose a provider. You can express preference through policy, and if we cannot satisfy it we return an error rather than silently ignoring it.