Developers
A payment API is judged entirely on its failure cases
Everyone’s happy path looks the same. What separates a payment interface you can build on from one you will fight is what happens on the retry, the timeout and the response that never arrived.
See it live
One state machine, one set of typed errors
Every request and response shape is documented the way it actually behaves in production, including the idempotency key and the code a decline returns.

Four guarantees
The properties that decide whether an integration stays stable
Idempotency is required, not optional
Every mutating request carries a key. Send it twice and you get one payment and two identical responses. This is a requirement rather than a convenience because a payment API without it will eventually double-charge somebody.
State is explicit and finite
A payment is in exactly one named state, and the transitions between them are documented. There is no state that means roughly in progress, and none that requires interpretation.
Errors are typed and stable
Failures return a machine-readable code and a human-readable reason. Codes do not change meaning between versions, so your own logic can branch on them without brittle string matching.
Versioned, and old versions keep working
Schemas carry a version and existing ones continue to be served. A payment integration should never break because something shipped on a Tuesday afternoon.
No privileged interface
The console calls exactly what you call
There is no internal path with capabilities the published interface lacks. It keeps us honest, and it means the endpoints you depend on are exercised continuously rather than only by integrators.
Creating and querying deposits
Initiating and approving withdrawals
Reading balances and treasury positions
Fetching settlement and fee records
Managing client accounts and destinations
Rates
A conversion rate your checkout can actually rely on
Rates endpoint
Current conversion rates for every supported pair from a single call, so a checkout or a quote screen does not have to guess what a conversion will settle at.
Quote validity is explicit
Each rate comes with the moment it was struck and how long it holds. A rate without an expiry is a rate somebody will eventually dispute.
Built for polling
The endpoint is designed to be called frequently — cached server-side, cheap against your rate limit, and separate from the endpoints that move money.
FAQ
Payments API: common questions
6 short answers to what teams ask before a demo.
No. The console is built on the same interface you get, so there is no privileged internal path. If an operation exists, it is callable — which also means the interface is exercised continuously rather than only by integrators.
You get one payment and two identical responses, provided both requests carried the same idempotency key. This is why the key is required rather than optional: a payment interface without it will eventually double-charge somebody.
Every failure returns a stable machine-readable code alongside a human-readable reason. Codes keep their meaning across versions, so your logic can branch on them rather than matching on message text that might be reworded.
Schemas are versioned and existing versions continue to be served. You move when you choose to, not when we deploy. Deprecation is announced with a timeline rather than applied.
Yes, published per endpoint, with headers on every response telling you where you stand. Being throttled should never be a surprise you discover from a failed payment.
Scoped API credentials, so a key that only needs to read balances cannot initiate a withdrawal. Keys are rotatable without downtime, and every call is attributable to the key that made it.
Still have a question?
A specialist will answer it directly, with your set-up in mind.
Ask a specialistBring an engineer to this conversation
We will go through the interface, the state model and the failure cases with someone who has integrated it rather than through a deck.