Dwg UR-001 · General arrangement · Rev C
One API for every payment rail.
Unirail is the routing layer between apps that move money and the providers that can move it. One API quotes every route across open banking, identity, account verification and compliance providers, in every jurisdiction they cover.
01Item 1 · Yours
Platform app
Your product, your users. They approve a payment with a passkey, and that approval is bound to the quote's id and digest, so what they signed is exactly what runs.
02Item 2 · Unirail
Routing layer
One API and SDK. It quotes every route across your connected providers as Cheapest, Fastest and Recommended, each with legs, cost, ETA and custody, then runs the one you pick. Events leave on one stream, signed with Standard Webhooks.
03Items 3–6 · Providers
Provider rails
Banking first: Plaid, Yapily and Enable Banking are integrated and 10 more are listed. Identity (KYC), account verification (CoP / VoP) and compliance screening stack underneath, several providers per capability, per jurisdiction.
04Item 7 · Yours
Your vault, our trust line
Provider credentials stay in your own Infisical. Unirail reads them per call through OIDC federation and never stores them.
05Flow · A2A
A payment, leg by leg
Accounts are payto:// addresses, masked everywhere. Today's routes run account to account with no custody; meta-providers that hold money in transit only appear where your routing policy allows.
View 01 / 06 · General arrangement
Sheet 2 — Route quotes
Ask for a route and Unirail returns alternatives, each a section through the same payment: its legs, cost, ETA and custody. Your user approves one, and that approval is bound to its id and digest.
Illustrative values · a live quote supplies real legs, cost and ETA
- id
- rq_…a7f3
- digest
- sha256:9c1e…a04
- amount
- 5000 · iso4217:GBP
- from
- payto://…4821
- to
- payto://…0937
- strategy
- cheapest
- legs
- 1
- cost · eta
- £0.20 · ≈ 60 s
- custody
- none
Lowest cost across connected providers.
- id
- rq_…b7f3
- digest
- sha256:9c1e…b04
- amount
- 5000 · iso4217:GBP
- from
- payto://…4821
- to
- payto://…0937
- strategy
- fastest
- legs
- 2
- cost · eta
- £1.10 · ≈ 5 s
- custody
- provider-transit
Holds money in transit, so it only appears where your policy allows it.
- id
- rq_…c7f3
- digest
- sha256:9c1e…c04
- amount
- 5000 · iso4217:GBP
- from
- payto://…4821
- to
- payto://…0937
- strategy
- recommended
- legs
- 1
- cost · eta
- £0.25 · ≈ 10 s
- custody
- none
Best fit for your routing policy: cost, ETA and custody weighed together.
Sheet 3 — Capability matrix
Banking first, then everything next to it. Each capability can have several providers per jurisdiction, so a route can fail over or pick on price. Filled stamps are integrated, outlined stamps are listed. Hover a stamp to trace that provider across the sheet.
| Capability | GB | EEA · EUR | NO SE DK | US | SG | HK | AU | JP |
|---|---|---|---|---|---|---|---|---|
| BankingPayment initiation | PLDYAPENBTLR | ENBNEO | NEO | · | PNQ | · | · | · |
| BankingBank link / AIS | PLDYAPENBTLRWSE | ENBNEOWSE | NEO | WSE | · | · | · | MNT |
| BankingPay-in · payout · FX | AWXNIUWSEOPD | AWXWSEOPD | · | AWXWSEBRGMTR | AWXNIU | AWX | AWX | · |
| IdentityIdentity / KYC | PLD | · | · | · | · | · | · | · |
| VerificationAccount verification (CoP / VoP) | AWXNIUOPD | NEOAWXOPD | NEO | AWXMTR | AWXNIU | AWX | AWX | MNT |
| ComplianceCompliance screening | Slot open · providers being listed |
Parts list · providers
- 01Plaidpisp aggregatorintegrated
- 02Yapilypisp aggregatorintegrated
- 03Enable Bankingpisp aggregatorintegrated
- 04TrueLayerpisp aggregatorlisted
- 05Neonomicspisp aggregatorlisted
- 06Airwallexmeta providerlisted
- 07Niummeta providerlisted
- 08Wise Platformmeta providerlisted
- 09Bridgeon chainlisted
- 10Moneytreedatalisted
- 11PayNow QRbank apilisted
- 12OpenPaydmeta providerlisted
- 13Modern Treasurymeta providerlisted
Sheet 4 — Interface
import { createUnirail } from "@unirail/sdk"; const unirail = createUnirail({ apiKey: process.env.UNIRAIL_SECRET_KEY,}); const { quotes } = await unirail.routeQuotes.create({ from: payer, to: payee, amount: { value: "5000", asset: "iso4217:GBP" },}); const intent = await unirail.paymentIntents.create( { quote: quotes[0].id, digest: quotes[0].digest, returnUri }, { context: { idempotencyKey: `pay:${id}` } },);Secret key, server side
One key per environment. Test and live keys, environments and routing policy are managed in the dashboard.
payto:// addresses
Payer and payee are payto:// accounts. Unirail stores them sealed and only ever returns them masked.
Amount as value + asset
Decimal string plus an asset id such as iso4217:GBP.
Bind approval to id + digest
Your user's approval (a passkey, say) signs this exact quote. A different route needs a new approval.
Idempotent by design
Retries with the same key return the same intent. Progress arrives on the event stream.
General notes
- All accounts are
payto://addresses, never shown in full. - Provider credentials stay in the customer's Infisical vault, read per call via OIDC federation, never stored by Unirail.
- User approval is bound to a quote's
id+digest. - Custody is data. Routes today are account to account, no custody; meta-providers holding funds in transit appear only where policy allows.
- One event stream; webhooks signed per Standard Webhooks.
- Test and live environments, API keys and routing policy live in the dashboard.
- Do not scale drawing.