Skip to main content
A complete walkthrough for building a production exchange on Bitnob Enterprise, from customer onboarding to policy-governed withdrawals. This guide covers the full integration lifecycle: finding your vault topology, onboarding customers, detecting deposits, setting up gas sponsorship, processing withdrawals, and locking down the system with a policy.
You need a Bitnob Enterprise API key with permission to manage wallets, transactions, gas stations, and policies. All requests go to https://api.platform.bitnob.com/v1 with the X-API-Key header, and every write takes an Idempotency-Key header. See Authentication and Making requests.

Step 1: Find your pool vault

Customer deposit wallets live in a pool vault, which holds an unlimited number of wallets. Vaults are created in the Bitnob dashboard. Find yours with List vaults, filtered by type:
Store the vault id. Get vault reads one back. List chains returns the chains you can create wallets on.

Step 2: Onboard customers

For each customer and chain, create a wallet in the pool vault. Set customer_ref_id to your internal customer ID. The chain’s primary address is created with the wallet, so there’s no second call.
Show the customer primary_address as their deposit address, and store the wallet id against their account. On account-based chains (EVM chains, Solana, Tron, TON) a wallet has exactly one address, and it receives every token on that chain. Only Bitcoin wallets can derive more addresses. Don’t send network. It is deprecated: your API key decides it, with live keys on mainnet and sandbox keys on testnets.

Step 3: Detect deposits

Subscribe to each deposit address with Create subscription, so Bitnob posts on-chain events to your endpoint as they happen:
Leave event_type empty to receive every on-chain event type, or set one, such as incoming_token_tx or confirmation_threshold_met, to receive only that. Webhooks covers verifying deliveries. As a fallback, and for reconciliation, poll List transactions:
Credit the customer when a deposit reaches completed. Reconcile on amount and asset, and use id or tx_hash to make sure each deposit is credited once.

Step 4: Set up gas stations

Customer wallets hold tokens, not the native asset for gas. Create a gas station for each chain, so withdrawals can be sponsored:
threshold and refill_amount are in the native asset, ETH here. Read a station with Get gas station and alert when health_status is low, or subscribe to the gas_station.low_balance and gas_station.critical_balance events. Top up by hand with Refill gas station. Set up a gas station covers sizing the threshold and refill amount.

Step 5: Process withdrawals

When a customer requests a withdrawal, create a transaction from their wallet with sponsor: true, so the gas station pays the network fee. Use your withdrawal ID as the Idempotency-Key.
The response tells you what happened:
  • 201 Created: the policy allowed it. It is signed and submitted, and sponsored is true.
  • 202 Accepted with status pending_authorization: your policy requires approval. It executes once approvers approve.
  • 202 Accepted with status delayed: a policy time lock holds it until execute_at.
In every case, wait for completed, by webhook or with Get transaction, before you finalize the customer’s ledger entry. Handle held and rejected transactions covers the 202 cases.

Step 6: Configure your policy

Your organization enforces one policy at a time: an ordered list of rules, where the first rule that matches decides the outcome. Build it from the most restrictive rule down. First, set up the quorum. Configure your organization’s quorum in the Bitnob dashboard, with at least two approvers. The quorum approves every policy activation, so no single API key or person can weaken your controls. Without it, Activate policy returns 422. Then draft the policy. This one blocks anything from a treasury wallet to an address you don’t list, blocks withdrawals over $50,000, and holds withdrawals over $10,000 for one approval:
Test it, then activate it. Dry-run sample withdrawals against the draft with Dry-run policy evaluation and its policy_id. Then call Activate policy, which sends it to your quorum. It becomes enforced once approved. Write and activate your first policy walks through every call, and Require approval for high-value transfers shows tiered approvals.

Step 7: Monitor and reconcile

Run daily reconciliation against your internal ledger:
  • Transactions. Page through List transactions for the day with created_at[gte] and created_at[lte]. Match each one to your withdrawal records by the transaction id you stored from Create transaction, and check amount and asset.
  • Stuck withdrawals. Alert on any transaction in pending_authorization or delayed beyond your SLA, and confirm its state with Get transaction.
  • Gas stations. Check health_status with List gas stations, and refill before it reaches low.
  • Notification health. Review List subscription delivery events for failures, and retry them with Retry subscription delivery.