Skip to main content

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.

Test with write access off first

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​

NeedCall
New sign-ups in a periodgetExchangeUsers({ startDate, endDate }) (paginate through count)
All balances, or one coin across usersgetExchangeUserBalances({ currency })
One user's balancegetExchangeUserBalance(userId)
Deposits and withdrawals for accountinggetExchangeDeposits(...), getExchangeWithdrawals(...) with format: 'csv' for exports
Trading volume and feesgetExchangeTrades({ startDate, endDate })
Exchange-wide holdingsgetExchangeBalance()

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 to increment_price and increment_size.
  • Keep a local order book from the orderbook WebSocket channel, and track your own orders from the order and usertrade channels.
  • Use cancelAllOrders(symbol) as a kill switch when you shut down or detect an error.
  • CCXT users can point the hollaex exchange class at your own API URL.

For a turnkey option, a market-making bot powered by OctoBot is included with your exchange.