Webhooks
Event Types

Event Types

1. DEPOSIT

Sent when a user's deposit is confirmed on-chain and funds have been swept to the bankroll.

Delivery: Fire-and-forget. Failures are logged but do not affect deposit processing.

Payload fields:

FieldTypeDescription
eventstringDEPOSIT
depositIdnumberInternal deposit ID
idempotencyKeystringUUID for deduplication
externalUserIdstringThe user identifier you provided when creating the deposit ticket
amountstringNet raw amount that reached the bankroll (gross − fee), token's smallest unit
amountInDollarstring | nullNet USD value — credit this to the user
grossAmountstringRaw amount the user actually sent on-chain
feeAmountstringRaw fee deducted on settlement ("0" when no fee)
feeInDollarstring | nullUSD value of the fee ("0.000000" when no fee)
typestringERC20 or NATIVE
contractAddressstring | nullToken contract address (null for native transfers)
transactionHashstring | nullInbound (deposit) transaction hash
chainIdnumberChain ID where the deposit occurred
confirmedAtstringISO 8601 timestamp

Amounts: amount / amountInDollar are the net credited to you (fee already deducted). Reconciles as amount + feeAmount = grossAmount. With no fee configured, feeAmount = "0" and grossAmount = amount. Credit amountInDollar, not the raw amount.

Expected response:

{
  "error": 0,
  "description": "ok",
  "transactionId": "your-internal-id"
}

Idempotency: Use idempotencyKey to deduplicate. You may receive the same deposit event more than once.


2. WITHDRAW_REQUEST

Sent before a withdrawal is processed, requesting your approval. The withdrawal will only proceed if you return error: 0.

Delivery: Synchronous. The system waits for your response before continuing.

Payload fields:

FieldTypeDescription
eventstringWITHDRAW_REQUEST
withdrawRequestIdstringWithdraw request UUID (may be empty for initial requests)
externalUserIdstringThe user identifier
typestringDIRECT_TRANSFER or OFF_RAMP
addressstringDestination wallet address
cryptoCurrencyCodestringe.g. USDT, ETH
fiatCurrencyCodestringe.g. USD, EUR
fiatAmountstringFiat amount of the withdrawal
cryptoAmountstring | nullCrypto amount (if specified by the user)
amountInUsdstring | nullUSD value — check this against the user's balance
requestedAtstringISO 8601 timestamp

To approve - return:

{
  "error": 0,
  "description": "ok"
}

To deny - return a non-zero error code:

{
  "error": 5,
  "description": "Daily withdrawal limit exceeded"
}

Error codes:

CodeMessage Shown to User
0(approved)
1Withdrawal request declined by operator
2Insufficient balance for withdrawal
3Withdrawal temporarily unavailable
4User is not eligible for withdrawal
5Daily withdrawal limit exceeded
6Withdrawal amount too low
7Withdrawal amount too high
8Account verification required
9Withdrawal suspended for this account

Any other non-zero code will show the description field from your response as the error message.


3. WITHDRAW_COMPLETE

Sent after a withdrawal has been completed (status changed to COMPLETED by an admin).

Delivery: Fire-and-forget. Failures are logged but do not affect the withdrawal status.

Payload fields:

FieldTypeDescription
eventstringWITHDRAW_COMPLETE
withdrawRequestIdstringWithdraw request UUID
externalUserIdstringThe user identifier
typestringDIRECT_TRANSFER or OFF_RAMP
statusstringCOMPLETED
addressstringDestination wallet address
cryptoCurrencyCodestringe.g. USDT, ETH
fiatCurrencyCodestringe.g. USD, EUR
fiatAmountstring | nullFiat amount
cryptoAmountstring | nullCrypto amount
amountInUsdstring | nullUSD value of the withdrawal
completedAtstringISO 8601 timestamp

Expected response:

{
  "error": 0,
  "description": "ok"
}