Deposit addresses & arrivals
We watch addresses you control and report what arrives on them. Registering or deriving an address gives us no key: the coins stay yours to spend. Scopes: deposits:write to register, deposits:read to read.
Network names: tron, bsc, ethereum, base, bitcoin, stellar. Detection is switched on per asset; we confirm which assets are on for you before you send.
Register addresses you control
POST /v1/deposit-addresses
Authorization: Bearer <your key>
Idempotency-Key: <uuid>
Content-Type: application/json
{
"addresses": [
{"network": "tron", "address": "T...", "reference": "your-user-42"},
{"network": "tron", "address": "T...", "reference": "your-user-43"}
]
}
| Field | Required | |
|---|---|---|
network | yes | One of the network names above |
address | yes | As the chain writes it. EVM addresses are stored lowercase |
reference | yes | Your id for whoever the address belongs to. 1–200 printable ASCII characters, no space. Returned on every arrival |
watch_from | no | Ignore arrivals before this instant. Must carry a timezone and may not be in the future. Defaults to now |
watch_from_block | no | The same bound as a block number |
Up to 500 addresses per call. Each item succeeds or is refused on its own, so read every status, not only the HTTP code:
status | |
|---|---|
registered | New |
existing | Already yours, with the same reference |
refused | error.code says why |
Item codes: unsupported_network, invalid_address, invalid_reference, invalid_watch_from, address_registered (already yours under another reference: an address belongs to one of your users for good), address_unavailable (not registrable by you).
An address is never deleted. Stop watching it with POST /v1/deposit-addresses/{address_id}/retire.
Or give us an xpub
POST /v1/deposit-xpubs
{"network": "tron", "xpub": "xpub...", "index_from": 0, "index_to": 100000}
POST /v1/deposit-addresses/derive
{"network": "tron", "reference": "your-user-44", "count": 1}
- The xpub must be an account-level key, depth 3 (for TRON, the key for
m/44'/195'/0'), not a master key. Anything else is422 invalid_xpub; a private key is422 private_key_refused. - We derive the external chain,
.../0/i. Every derived address carries itsderivation_index, so you can check it against your own key. - One live xpub per network.
countis 1–100, all or none, and every derived address gets the onereferenceyou sent. - Both calls take an
Idempotency-Key.
Read addresses back
GET /v1/deposit-addresses?network=tron&reference=your-user-42&after=<id>&limit=200
{"addresses": [...], "next_after": "<id>" | null}. limit defaults to 200, maximum 500. Page with after=<next_after> until next_after is null. include_retired=true adds retired addresses.
Arrivals
GET /v1/deposits?after=0&limit=200
{
"deposits": [
{
"id": "3f1c2a9e-...",
"network": "tron",
"address": "T...",
"reference": "your-user-42",
"amount": {"amount": "1000", "currency": "USDT_TRC20"},
"amount_units": "1000000000",
"tx_hash": "4b1e0c9a...",
"transfer_index": 0,
"from_address": "T...",
"block_number": 76312455,
"confirmations": 41,
"required_confirmations": 20,
"status": "CONFIRMED",
"historical": false,
"detected_at": "2026-09-26T08:20:11Z",
"confirmed_at": "2026-09-26T08:22:48Z",
"reorged_at": null,
"change_seq": 184
}
],
"next_after": 184
}
statusisDETECTED,CONFIRMEDorREORGED.REORGEDmeans the block that carried it was replaced: those coins are not there.required_confirmationsis the depth for that asset.- A transfer is identified by
(tx_hash, transfer_index), not bytx_hashalone. amount_unitsis the same amount in the asset's base units, as an integer string.historical: truemeans the block is older than the moment you registered the address, for example after awatch_fromin the past. Do not credit your user from it without asking us.- Filter one user with
?reference=.
Paging. Rows are ordered by change_seq, which increases when a row is created and when its status changes. Poll with after=<last next_after> and no row escapes you. Stop when deposits is empty: next_after echoes your after on an empty page and is never null here. Two statuses can collapse between polls; if you need every transition, read the deposit.* events.
An arrival on an address you control does not change your balance with us. It is the fact that money reached that address.
Read cadence
We read watched addresses in passes, one a minute. An address is read every minute for 7 days after you register it and for 30 days after its last arrival, and every 10 minutes otherwise, least recently read first. A pass reads at most 50 addresses per asset.
Read an address now
When your user says they have paid, ask for that address to be read now:
POST /v1/deposit-addresses/{address_id}/watch-now
Authorization: Bearer <your key>
No body and no Idempotency-Key. Answers the address object with watch_now_until set.
- The address is read in the next pass, for every watched asset of its network, then every minute until
watch_now_until: 60 minutes after your call. - Asked-for addresses go ahead of the queue in up to half of each pass (25 of 50), least recently read first.
- A repeat sets the window to 60 minutes from the repeat. It does not add up.
404 not_found: not your address.409 state_conflict: the address is retired.- Counts as one write against your rate limit.
Addresses whose keys we hold
POST /v1/deposit-addresses/issue issues addresses from our own seed, and POST /v1/deposit-keys hands us a wrapped private key for an address you registered. Both make us the custodian of what arrives there. issue needs the deposits:issue scope, which is in no bundle and is granted only by agreement; deposit-keys is also signed. If you do not need custody, you do not need either.