How It Works
This page follows the money end to end: how a customer's balance comes into existence, what can be done with it, and how it leaves the platform.
The sequence below is the order the calls are meant to be made in, with a link to each one. The limits at the end are the parts a client has to design around rather than discover in production.
The Model in Three Objects
| Object | What it is |
|---|---|
| Member | One end customer of the merchant, identified by a numeric id. |
| Account | One (member, asset) balance. Created for every asset when the member is created. |
| Deposit address | An address of one account on one network. May carry an expired_at. |
Lifecycle
- Check reachability.
GET /api/healthneeds no token, so it confirms the host is reachable before any credentials are involved. - Read the catalogue.
GET /api/assetsgives the asset codes, network codes, decimal precision and this merchant's fee rates. Every later call takes itsassetanddchain_idvalues from here. - Create the member.
POST /api/memberscreates the customer and one account per asset, so a balance exists in every currency immediately. Answers201. - Create a deposit address on the network the customer will pay on:
POST /api/accounts/{account_id}/deposit_addresses.expired_atis optional — supply it only if the address should stop being offered after a date. - (Optional) Add an auto-conversion rule so that what arrives on that
network is converted into another asset:
POST /api/auto_conversionswithdchain_fromandasset_to. - The customer pays to the address.
- Read the deposit.
GET /api/deposits?member_id=…— the list can be filtered bydeposit_addressordeposit_address_id, which is how a payment is tied back to the address it was made to. - (Optional) Trade or move the balance — an order against a market, or a transfer to another member of the same owner.
- Pay out. Quote first with
POST /api/withdrawals/fees_info, then create the payout withPOST /api/withdrawals, then read it back withGET /api/withdrawals/{id}.
customer's wallet
│ pays
▼
┌──────────────┐ ┌───────────────┐
│ deposit │──────────────► │ account │
│ address │ │ (balance) │
└──────────────┘ └───────────────┘
│ │ │ │
auto-conversion trade │ │ │ transfer
(dchain_from → asset_to) ▼ │ ▼
┌──────────┐ │ ┌──────────────────┐
│ orders │ │ │ another member │
│ + trades │ │ │ of the same owner│
└──────────┘ │ └──────────────────┘
│ withdraw
▼
external address
Fees
Two places give you fee information, and they answer different questions:
| Call | Answers |
|---|---|
| List Assets | This merchant's rates per network: deposit_static_fee, deposit_dynamic_fee, fee_static_withdrawal, fee_dynamic_withdrawal, and whether AML applies |
| Withdrawal Fees | The actual figures for one payout: total_fee (AML included), aml_fee on its own, total_amount = amount + total_fee, and operation_type — on-chain or off-chain |
Use the second one whenever a number is shown to a customer — it accounts for the amount and the destination, which the rate table cannot.
On a deposit the fee works the other way round: it is already deducted by the
time you see it. amount is the credited figure and the on-chain amount was
amount + fee, unless your account is configured to report the gross amount
instead. See Deposits.
amount is what the destination receives, and the balance is debited
amount + fee. A customer who asks to send their whole balance cannot: quote the
fee and send balance − total_fee instead.
The quote is also the only figure that accounts for the destination, not just the
network and the amount: pass the real address and use what comes back, rather
than computing from the rate table.
Reading lists
Every collection is paginated with page and per_page (default 20, maximum
1000) and answers with an envelope — total_count, total_pages, prev_page,
next_page and items — not a bare array. See
API Conventions.
No list has a defined order, so page through total_pages rather than assuming the
newest rows come first — and see the warning in
API Conventions.
Limits worth knowing up front
- Errors. The numeric error contract is not published yet, so do not branch on a specific code or body — handle failure by status class and retry policy instead.
- Timing. A
201means the operation was accepted, not that money has moved. A payout starts ataml_processing; an order starts atwait. - Idempotency is not enforced anywhere. See API Conventions.
- List order is undefined, which makes paging unreliable — same page.
- No minimum order size is exposed, so an order can be refused for being too small only after it is sent.