Skip to main content

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.

How to read this page

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​

ObjectWhat it is
MemberOne end customer of the merchant, identified by a numeric id.
AccountOne (member, asset) balance. Created for every asset when the member is created.
Deposit addressAn address of one account on one network. May carry an expired_at.

Lifecycle​

  1. Check reachability. GET /api/health needs no token, so it confirms the host is reachable before any credentials are involved.
  2. Read the catalogue. GET /api/assets gives the asset codes, network codes, decimal precision and this merchant's fee rates. Every later call takes its asset and dchain_id values from here.
  3. Create the member. POST /api/members creates the customer and one account per asset that exists at that moment, so a balance exists in every currency immediately. An asset added later is provisioned to existing members automatically — see Members. Answers 201.
  4. Create a deposit address on the network the customer will pay on: POST /api/accounts/{account_id}/deposit_addresses. expired_at is optional — supply it only if the address should stop being offered after a date.
  5. (Optional) Add an auto-conversion rule so that what arrives on that network is converted into another asset: POST /api/auto_conversions with member_id, dchain_from and asset_to.
  6. The customer pays to the address.
  7. Read the deposit. GET /api/deposits?member_id=… — the list can be filtered by deposit_address or deposit_address_id, which is how a payment is tied back to the address it was made to.
  8. (Optional) Trade or move the balance — an order against a market, or a transfer to another member of the same owner.
  9. Pay out. Quote first with POST /api/withdrawals/fees_info, then create the payout with POST /api/withdrawals, then read it back with GET /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:

CallAnswers
List AssetsThis merchant's rates per network: deposit_static_fee, deposit_dynamic_fee, fee_static_withdrawal, fee_dynamic_withdrawal, and whether AML applies
Withdrawal FeesThe 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.

On a payout, the fee is charged on top of the amount

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​

Collections are paginated with page and per_page (default 20, maximum 1000) and answer with an envelope — total_count, total_pages, prev_page, next_page and items — not a bare array. The exceptions are the direct lookups listed in 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 carry a numeric code — branch on that, not on the message. See Errors, which also says which codes are worth retrying.
  • Timing. A 201 means the operation was accepted, not that money has moved. A payout starts at aml_processing; an order starts at wait.
  • A retry is only safe if you send your own id — see API Conventions. A transfer has no such field at all.
  • List order is undefined, which makes paging unreliable — see API Conventions.