The API, written out.
Everything the console does is one HTTPS call. Base URL
https://api.rion.dev/v1, bearer token in the Authorization header.
Sandbox
Every account starts in sandbox. Sandbox keys move fake money on real rails' timing models, so a payout that would take two days in production takes two days in sandbox — you can fast-forward it, but only deliberately.
# sandbox keys are prefixed, so they can never be confused for live ones export RION_KEY=sk_sandbox_8f2a...
Authentication
Bearer tokens, scoped per environment and per capability. A token with
read scope cannot move money, which is the token you want in anything that only
builds reports.
curl https://api.rion.dev/v1/accounts \ -H "Authorization: Bearer $RION_KEY"
Creating accounts
An account belongs to an entity and a currency. Sub-accounts nest by passing
parent; the ledger keeps the tree, you do not have to.
curl https://api.rion.dev/v1/accounts \
-H "Authorization: Bearer $RION_KEY" \
-d '{"entity":"ent_4Kd","currency":"EUR","name":"Escrow — Kestrel"}'
{ "account": "acc_7Qm2", "iban": "DE89 3704 0044 0532 0130 00", "balance": 0 }
Sending a payout
Pass an amount and a destination; the rail is chosen for you. Always send an
Idempotency-Key: a retried payout is the one mistake that is expensive to
undo.
curl https://api.rion.dev/v1/payouts \
-H "Authorization: Bearer $RION_KEY" \
-H "Idempotency-Key: 7c1f9a2e" \
-d '{"from":"acc_7Qm2","to":"ben_2Lp","amount":1840000,"currency":"EUR"}'
{ "payout": "po_9Kd2Ra", "rail": "sepa_instant", "state": "pending" }
Amounts are integers in the currency's minor unit. There are no floats anywhere in this API, for the reason you would expect.
Webhooks
Events are signed with HMAC-SHA256 over the raw body. Verify before you parse, and return a 2xx quickly, because anything slower than 5 s is retried with backoff for 24 hours.
payout.settled: the money actually landed, not merely accepted.payout.failed: carries the bank's own reason code.card.authorisation: fires before the decision; you may decline.ledger.entry: one per side of every double entry.
API reference
| Method | Path | Scope |
|---|---|---|
| GET | /v1/accounts | read |
| POST | /v1/accounts | write |
| GET | /v1/accounts/:id/balance | read |
| POST | /v1/payouts | move |
| GET | /v1/payouts/:id | read |
| POST | /v1/cards | write |
| GET | /v1/ledger/entries | read |
Errors
Errors carry a stable code, a human message, and where relevant the
upstream bank's reason. Never branch on the message.
{ "error": { "code": "beneficiary_iban_mismatch",
"message": "The IBAN does not match the beneficiary name on file.",
"bank_reason": "AC03" } }
Security
Keys are scoped per environment and revocable individually. Ledger entries are immutable; a correction is a new pair of entries, never an edit. Auditor access is read-only and scoped to a date range.
Status & uptime
Scale carries a 99.95% commitment and Enterprise 99.99%, measured on the payout API rather than on the marketing site. Incidents are posted before they are resolved, not after.