Common Integrations
These patterns cover what most operators build first. They use hollaex-node-lib with an admin key. Every call maps to an endpoint in the Admin API reference, so you can do the same from any language.
Most of these recipes move funds or change users. Build them against a test account and enable write permission on the key only when you're ready.
Onboard a user from your own app
Use this when you sign users up in your own product (for example a fintech app or a partner portal) and want each one to have an exchange account.
// 1. Create the account. The response is only {"message":"Success"}
await client.createExchangeUser(email, password, { referral: 'PARTNER1' });
// 2. Look up the new user's id
const { data } = await client.getExchangeUsers({ search: email });
const user = data.find((u) => u.email === email);
if (!user) throw new Error(`User ${email} not found after creation`);
// 3. Store user.id in your own database, then link it back to your system
await client.updateExchangeUser(user.id, { meta: { external_id: 'cus_123' } });
Use meta to keep your own identifiers on the HollaEx user. The meta key has to exist in your exchange's user meta configuration before you can write to it. To add a key, open any user in Operator Controls, go to the Metadata tab, click Configure Meta Fields and use Add New Meta Field.
Generate a deposit address
await client.createExchangeUserWallet(user.id, 'usdt', { network: 'trx' });
const wallets = await client.getExchangeUserWallet({ userId: user.id, currency: 'usdt' });
console.log(wallets.data.map((w) => `${w.network}: ${w.address}`));
Credit or debit a balance (mint / burn)
Manual deposits and withdrawals are for fiat and for assets you created on your exchange. They don't touch a blockchain. Use them to credit a bank transfer you've confirmed, pay a reward, or make an accounting adjustment.
// Credit 100 USD after your bank confirms a wire
await client.mint(user.id, 'usd', 100, {
transactionId: 'wire-2026-000123', // your reference, used to avoid double credits
description: 'Bank wire deposit',
email: true, // notify the user
});
// Debit (e.g. a fiat payout you've sent)
await client.burn(user.id, 'usd', 50, { transactionId: 'payout-2026-000045' });
Always pass your own transactionId and check getExchangeDeposits({ transactionId }) before retrying. A failed network call doesn't mean the credit didn't go through.
Move funds between users
await client.transferExchangeAsset(fromUserId, toUserId, 'usdt', 25, {
description: 'Referral bonus',
email: false,
});
Transfers are internal and instant, and don't touch a blockchain.
React to deposits and withdrawals in real time
Subscribe to the admin channel once and you get deposit, withdrawal and stake events for every user. You can use this to send notifications, sync your CRM, run compliance checks or update accounting.
client.connect(['admin']);
client.ws.on('message', async (raw) => {
const msg = JSON.parse(raw);
if (msg.topic === 'deposit' && msg.data.status) {
await handleConfirmedDeposit(msg.data); // must be idempotent: key on msg.data.transaction_id
}
});
If your listener was offline, catch up afterwards with getExchangeDeposits({ startDate }) and getExchangeWithdrawals({ startDate }).
Reporting and reconciliation
| Need | Call |
|---|---|
| New sign-ups in a period | getExchangeUsers({ startDate, endDate }) (paginate through count) |
| All balances, or one coin across users | getExchangeUserBalances({ currency }) |
| One user's balance | getExchangeUserBalance(userId) |
| Deposits and withdrawals for accounting | getExchangeDeposits(...), getExchangeWithdrawals(...) with format: 'csv' for exports |
| Trading volume and fees | getExchangeTrades({ startDate, endDate }) |
| Exchange-wide holdings | getExchangeBalance() |
Trading bots and market making
Use a user key on a dedicated account, not an admin key:
- Read pair limits from
getConstants()and round price and size toincrement_priceandincrement_size. - Keep a local order book from the
orderbookWebSocket channel, and track your own orders from theorderandusertradechannels. - Use
cancelAllOrders(symbol)as a kill switch when you shut down or detect an error. - CCXT users can point the
hollaexexchange class at your own API URL.
For a turnkey option, a market-making bot powered by OctoBot is included with your exchange.