Skip to content
LogoLogo

Wallet API Reference

All Wallet endpoints in integration order. Use https://api.sandbox.blox.my while testing and https://api.blox.my in production.

Read requests require blox-api-key. Write requests require the API key, an HTTP message signature, and—where shown—an Idempotency-Key UUID v4 persisted before the first request.

Amounts are integers in sen in request bodies and strings in responses. Every error uses { "code": "…", "message": "…", "requestId": "…" }; branch on code, never message. See Errors for shared behavior.

MethodEndpointPurpose
GET/v1/wallet/addressRead EVM and Solana deposit addresses
GET/v1/wallet/balanceRead available and pending balances
GET/v1/wallet/networksResolve active networks and token IDs
POST/v1/wallet/token/withdrawalsSend tokens to an external address
GET/v1/wallet/token/withdrawals/{id}Read one token transfer's status
GET/v1/wallet/bank-accountsList linked bank accounts
POST/v1/wallet/fiat/withdrawalsWithdraw MYR to a linked bank account
GET/v1/wallet/fiat/withdrawals/{id}Read one fiat withdrawal's status
POST/v1/wallet/bank-accounts/{bankAccountId}/addressGive a bank account a deposit trigger address
GET/v1/wallet/bank-accounts/{bankAccountId}/address/whitelistList the senders allowed to trigger it
POST/v1/wallet/bank-accounts/{bankAccountId}/address/whitelistAllow a sender
PATCH/v1/wallet/bank-accounts/{bankAccountId}/address/whitelist/{senderId}Pause a sender without losing it
DELETE/v1/wallet/bank-accounts/{bankAccountId}/address/whitelist/{senderId}Stop allowing a sender
GET/v1/wallet/deposits/{id}Read a deposit and the withdrawal it triggered
POST/v1/wallet/deposits/check-missedHave BLOX look at a transaction it never picked up
POST/v1/wallet/deposits/{id}/redriveRetry a deposit that produced no withdrawal
GET/v1/wallet/transactionsList wallet movements for reconciliation

Get wallet address

GET/v1/wallet/addressAPI key

Returns the wallet's deposit addresses. Missing addresses are created automatically.

Response — 200

{
  "evmAddress": "0x742d35Cc6634C0532925a3b333Bc9e1234f8bD21",
  "solAddress": "DRpbCBMxVnDK7maPM5tGv6MvB3v1sRMC99PZ8okm99hy"
}
FieldTypeDescription
evmAddressstringDeposit address shared by supported EVM networks
solAddressstringSolana deposit address
Error responses
StatuscodeWhen
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

401 UNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "API key is required",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Get wallet balance

GET/v1/wallet/balanceAPI key

Returns spendable and pending wallet balances.

Response — 200

{
  "walletBalance": "250000",
  "pendingWithdrawal": "0"
}
FieldTypeDescription
walletBalancestringSpendable wallet balance in sen
pendingWithdrawalstringBalance currently involved in outbound withdrawals, in sen
Error responses
StatuscodeWhen
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

401 UNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "API key is required",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Get supported networks

GET/v1/wallet/networksAPI key

Returns active networks with their active tokens. Resolve tokenId from this endpoint at runtime; IDs differ between sandbox and production.

QueryTypeRequiredDescription
idstringNoReturn one network by network ID
tokenIdstring (UUID)NoReturn the network containing this token

Each network includes id, name, type, and tokens. Use a token's id as tokenId in Wallet transfers and Onramp checkouts. Match EVM tokens to 0x addresses and Solana tokens to Base58 addresses.

Contract addresses and chain IDs also appear on Environments & Chains; prefer this endpoint at runtime.

Error responses
StatuscodeWhen
400VALIDATION_FAILEDid or tokenId is malformed
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

400 VALIDATION_FAILED

For a malformed tokenId:

{
  "code": "VALIDATION_FAILED",
  "message": "tokenId: Invalid UUID",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Create token transfer

POST/v1/wallet/token/withdrawalsAPI key + signature

Transfers a token from the BLOX wallet to an external address. The endpoint is limited to 30 requests per minute per account.

Header

HeaderRequiredDescription
Idempotency-KeyYesUUID v4 persisted for this transfer before the first request

Body

FieldTypeRequiredConstraintsDescription
tokenIdstring (UUID)YesActive tokenID from GET /v1/wallet/networks
addressTostringYesMust match the token networkRecipient wallet address
amountintegerYes1000100000000 senTotal wallet debit (RM10–RM1,000,000)
referencestringNoMaximum 32 charactersYour reconciliation reference

EVM addresses use 0x plus 40 hexadecimal characters. Solana addresses use Base58. Transfers to your own deposit address, a contract address, or another restricted destination are rejected.

The requested amount is the total wallet debit. Network fees, when applicable, are deducted before delivery; the response gives the net amount and separate fee.

Response — 200

{
  "id": "9b3bd9db-75d8-44dc-a74b-16fe968a01c7",
  "status": "CREATED",
  "toAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f8bD21",
  "amount": "10000",
  "fee": "0",
  "reference": "ORDER-4471",
  "source": "API",
  "tokenId": "550e8400-e29b-41d4-a716-446655440000",
  "token": {
    "symbol": "MYRC",
    "name": "MYR Coin",
    "network": { "id": "ethereum", "name": "Ethereum", "type": "EVM" }
  },
  "txHash": null,
  "confirmations": null,
  "confirmedAt": null,
  "createdAt": "2026-01-16T10:30:00.000Z",
  "updatedAt": "2026-01-16T10:30:00.000Z"
}

The initial status is CREATED for EVM transfers and PENDING for Solana transfers. See the Token transfer object for every field and status.

Persist one UUID v4 before sending. Reuse that key after no response, a timeout, 202, or 5xx. Reusing it with the same body returns the original transfer for 24 hours; a different body returns 422 VALIDATION_FAILED. After a 4xx, fix the request and use a new key.

Error responses
StatuscodeWhen
400INVALID_REQUESTThe idempotency key, token, or destination is not accepted
400VALIDATION_FAILEDThe body, address, amount, or reference is invalid
400INSUFFICIENT_BALANCEThe wallet cannot cover the requested debit
400LIMIT_EXCEEDEDA configured daily or monthly limit is reached
401UNAUTHORIZEDAPI key or request signature is missing or invalid
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_FROZENThe account is frozen
403ACCOUNT_TERMINATEDThe account is terminated
403ACCOUNT_PENDING_VERIFICATIONThe account is pending verification
422VALIDATION_FAILEDThe idempotency key was used with another body
429RATE_LIMITEDThe 30-per-minute create limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

400 INVALID_REQUEST
{
  "code": "INVALID_REQUEST",
  "message": "Missing idempotency key",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 VALIDATION_FAILED

For a request with amount: 999:

{
  "code": "VALIDATION_FAILED",
  "message": "amount: Amount can't be less than 10 MYR",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 INSUFFICIENT_BALANCE
{
  "code": "INSUFFICIENT_BALANCE",
  "message": "Insufficient MYRC balance in wallet.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 LIMIT_EXCEEDED
{
  "code": "LIMIT_EXCEEDED",
  "message": "Daily transaction limit exceeded.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
401 UNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "API key is required",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 FEATURE_DISABLED
{
  "code": "FEATURE_DISABLED",
  "message": "Feature wallet_api is not enabled for this account.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_FROZEN
{
  "code": "ACCOUNT_FROZEN",
  "message": "Your account has been frozen. Please contact support.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_TERMINATED
{
  "code": "ACCOUNT_TERMINATED",
  "message": "Your account has been terminated. Please contact support.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_PENDING_VERIFICATION
{
  "code": "ACCOUNT_PENDING_VERIFICATION",
  "message": "Your account is pending verification. This action is not allowed for this account at this time.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
422 VALIDATION_FAILED
{
  "code": "VALIDATION_FAILED",
  "message": "Idempotency key used with different request payload",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
429 RATE_LIMITED
{
  "code": "RATE_LIMITED",
  "message": "Too many token withdrawals. Please try again later.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
500 INTERNAL_ERROR
{
  "code": "INTERNAL_ERROR",
  "message": "An unexpected error occurred.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Get token transfer

GET/v1/wallet/token/withdrawals/{id}API key

Returns one token transfer from the moment it is created. Use this endpoint to monitor status.

PathTypeDescription
idstring (UUID)id returned by the create request

Response — 200: Token transfer object. Unknown and cross-account IDs return 404 NOT_FOUND.

An EVM transfer is absent from GET /v1/wallet/transactions while it remains CREATED; this resource endpoint is therefore the authoritative status from creation.

Error responses
StatuscodeWhen
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
404NOT_FOUNDThe transfer is unknown or belongs to another account
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

404 NOT_FOUND
{
  "code": "NOT_FOUND",
  "message": "Token withdrawal not found",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

List bank accounts

GET/v1/wallet/bank-accountsAPI key

Returns active bank accounts linked to the BLOX account. Use a verified account's id as bankAccountId when creating a fiat withdrawal.

QueryTypeRequiredConstraintsDescription
searchstringNoFilter by account name
limitintegerNo1–100, default 25Records per page
cursorstringNoPrevious page's last idOmit for the first page

Response — 200

{
  "data": [
    {
      "id": "6639e2e8-9d71-4a77-9fd7-34fcd0ce5355",
      "name": "Business account",
      "accountNumber": "123456789012",
      "verified": true,
      "bank": { "code": "MBBM", "name": "Maybank" },
      "createdAt": "2026-01-10T04:00:00.000Z",
      "updatedAt": "2026-01-10T04:00:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
FieldTypeDescription
idstring (UUID)Send as bankAccountId when withdrawing
namestringAccount label
accountNumberstringUnmasked bank account number
verifiedbooleanWhether BLOX has verified the account
bankobject | null{ code, name }
createdAt / updatedAtstringISO 8601 timestamps

Iterate until hasMore is false. There is no total.

Error responses
StatuscodeWhen
400VALIDATION_FAILEDA query parameter is malformed or outside its constraint
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

400 VALIDATION_FAILED

For ?limit=101:

{
  "code": "VALIDATION_FAILED",
  "message": "limit: Number must be less than or equal to 100",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Create fiat withdrawal

POST/v1/wallet/fiat/withdrawalsAPI key + signature

Withdraws MYR from the BLOX wallet to a linked bank account. The endpoint is limited to 30 requests per minute per account.

Header

HeaderRequiredDescription
Idempotency-KeyYesUUID v4 persisted for this withdrawal before the first request

Body

FieldTypeRequiredConstraintsDescription
bankAccountIdstring (UUID)YesActive linked accountID from GET /v1/wallet/bank-accounts
amountintegerYes1000100000000 senWithdrawal amount (RM10–RM1,000,000)
referencestringNoMaximum 20 charactersYour reconciliation reference

Individual accounts have an additional RM300,000 maximum; business accounts can use the full per-request range. Other account-level limits may apply.

Response — 200

{
  "id": "1de31ea3-c2b5-454b-a1f0-547c21738aef",
  "status": "PENDING",
  "amount": "50000",
  "fee": "0",
  "reference": "WD-4471",
  "refId": "FW-20260116-A1B2C3",
  "source": "API",
  "destination": {
    "name": "ADA LOVELACE",
    "accountNumber": "1234567890",
    "bank": { "code": "MBBM", "name": "Maybank" }
  },
  "confirmedAt": null,
  "createdAt": "2026-01-16T10:30:00.000Z",
  "updatedAt": "2026-01-16T10:30:00.000Z"
}

See the Fiat withdrawal object for every field and status. Idempotency and retry behavior match token transfers: persist the key before sending and reuse it for the same logical withdrawal.

Error responses
StatuscodeWhen
400INVALID_REQUESTThe idempotency key or account-specific amount is not accepted
400VALIDATION_FAILEDThe body, amount, or reference is invalid
400INSUFFICIENT_BALANCEThe wallet cannot cover the withdrawal
400LIMIT_EXCEEDEDA configured daily or monthly limit is reached
401UNAUTHORIZEDAPI key or request signature is missing or invalid
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_FROZENThe account is frozen
403ACCOUNT_TERMINATEDThe account is terminated
403ACCOUNT_PENDING_VERIFICATIONThe account is pending verification
404NOT_FOUNDThe bank account is unknown, inactive, or belongs to another account
422VALIDATION_FAILEDThe idempotency key was used with another body
429RATE_LIMITEDThe 30-per-minute create limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

400 INVALID_REQUEST
{
  "code": "INVALID_REQUEST",
  "message": "Missing idempotency key",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 VALIDATION_FAILED

For a request with amount: 999:

{
  "code": "VALIDATION_FAILED",
  "message": "amount: Amount can't be less than 10 MYR",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 INSUFFICIENT_BALANCE
{
  "code": "INSUFFICIENT_BALANCE",
  "message": "Insufficient MYRC balance in wallet.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
400 LIMIT_EXCEEDED
{
  "code": "LIMIT_EXCEEDED",
  "message": "Daily transaction limit exceeded.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
401 UNAUTHORIZED
{
  "code": "UNAUTHORIZED",
  "message": "API key is required",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 FEATURE_DISABLED
{
  "code": "FEATURE_DISABLED",
  "message": "Feature wallet_api is not enabled for this account.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_FROZEN
{
  "code": "ACCOUNT_FROZEN",
  "message": "Your account has been frozen. Please contact support.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_TERMINATED
{
  "code": "ACCOUNT_TERMINATED",
  "message": "Your account has been terminated. Please contact support.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
403 ACCOUNT_PENDING_VERIFICATION
{
  "code": "ACCOUNT_PENDING_VERIFICATION",
  "message": "Your account is pending verification. This action is not allowed for this account at this time.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
404 NOT_FOUND
{
  "code": "NOT_FOUND",
  "message": "Bank account not found",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
422 VALIDATION_FAILED
{
  "code": "VALIDATION_FAILED",
  "message": "Idempotency key used with different request payload",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
429 RATE_LIMITED
{
  "code": "RATE_LIMITED",
  "message": "Too many fiat withdrawals. Please try again later.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}
500 INTERNAL_ERROR
{
  "code": "INTERNAL_ERROR",
  "message": "An unexpected error occurred.",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Get fiat withdrawal

GET/v1/wallet/fiat/withdrawals/{id}API key

Returns one fiat withdrawal. Poll until COMPLETED, FAILED, or REJECTED.

PathTypeDescription
idstring (UUID)id returned by the create request

Response — 200: Fiat withdrawal object. Unknown and cross-account IDs return 404 NOT_FOUND.

Error responses
StatuscodeWhen
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
404NOT_FOUNDThe withdrawal is unknown or belongs to another account
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

404 NOT_FOUND
{
  "code": "NOT_FOUND",
  "message": "Fiat withdrawal not found",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Create a deposit trigger address

POST/v1/wallet/bank-accounts/{bankAccountId}/addressAPI key + signature

Gives a linked bank account an on-chain address. Tokens sent to it are withdrawn to that bank account automatically, with no create request from you. See Withdraw automatically on deposit.

The bank account must be active. Calling this again returns the same address — a bank account has one, for its lifetime — so no Idempotency-Key is needed. Limited to 20 calls per minute.

Success response (201)

{
  "address": "0x7c1a3e889d2b4f618a441f0b6d3c9a5588ab01cd",
  "network": "EVM",
  "destination": {
    "type": "BANK_ACCOUNT",
    "id": "b21f4c77-3e5a-4d90-9c18-6a2f7e0b4d31"
  }
}
FieldTypeDescription
addressstringSend supported tokens here
networkstringEVM
destination.typestringBANK_ACCOUNT
destination.idstring (UUID)The bank account that gets paid

The address ignores every deposit until you allow at least one sender.

Expected errors
StatuscodeWhen
403FEATURE_DISABLEDAutomatic withdrawal on deposit is not enabled on your account
404NOT_FOUNDUnknown bank account, one belonging to another account, or one that is not active
429RATE_LIMITEDOver 20 calls in the last minute

List allowed senders

GET/v1/wallet/bank-accounts/{bankAccountId}/address/whitelistAPI key

Returns the senders allowed to trigger this bank account's address, oldest first.

Success response (200)

[
  {
    "id": "3f8c1d02-5b47-4a6e-91cd-77e2b0a4f915",
    "address": "0x9a3f7c21b8e04d6f5a19c2e70b48d3f61a5e9d02",
    "label": "Treasury wallet",
    "active": true,
    "createdAt": "2026-08-07T09:31:05.000Z"
  }
]
FieldTypeDescription
idstring (UUID)Pass this to disable or remove the sender
addressstringStored lowercase
labelstring | nullYour own note
activebooleanOnly active senders are accepted; see disable
createdAtstringISO 8601

Disabled senders are listed too. They count toward the 50-sender limit until you remove them.

404 NOT_FOUND if the bank account has no trigger address yet.

Allow a sender

POST/v1/wallet/bank-accounts/{bankAccountId}/address/whitelistAPI key + signature

Allows one address to trigger withdrawals to this bank account. Up to 50 per address.

FieldTypeRequiredConstraintsDescription
addressstringYes0x and 40 hex charactersThe address you send from. Casing is ignored
labelstringNo1–120 charactersYour own note, returned on reads

Success response (201)

Returns the created sender in the same shape as List allowed senders.

Expected errors
StatuscodeWhen
400VALIDATION_FAILEDaddress is not a valid address, or label is longer than 120 characters
400CONFLICTThat address is already allowed here
403LIMIT_EXCEEDEDThe address already has 50 allowed senders
404NOT_FOUNDThe bank account has no trigger address, or is not yours

Disable or re-enable a sender

PATCH/v1/wallet/bank-accounts/{bankAccountId}/address/whitelist/{senderId}API key + signature

Turns a sender off without losing it. A disabled sender stops triggering withdrawals immediately, keeps its label, and stays in the list ready to be turned back on. Use this to pause a wallet you expect to send from again; use remove when you are done with it, which is also what frees its place against the 50-sender limit.

Request body

FieldTypeDescription
activebooleanfalse to disable, true to re-enable

Success response (200)

Returns the sender in the same shape as List allowed senders.

Expected errors
StatuscodeWhen
400VALIDATION_FAILEDactive is missing or is not a boolean
403ACCOUNT_FROZENThe account is frozen. Removing a sender still works
403ACCOUNT_PENDING_VERIFICATIONThe account is pending verification
404NOT_FOUNDThe sender id is unknown or belongs to a different address

Remove an allowed sender

DELETE/v1/wallet/bank-accounts/{bankAccountId}/address/whitelist/{senderId}API key + signature

Stops accepting deposits from that sender and frees its place against the 50-sender limit. Deposits already on their way are unaffected. Sign @method and @path only; no Content-Digest is required.

Success response (200)

{ "success": true }

404 NOT_FOUND if the sender id is unknown or belongs to a different address.

Get a deposit

GET/v1/wallet/deposits/{id}API key

Returns a deposit and, when it triggered one, the withdrawal it produced. This is the same payload the deposit webhook delivers.

Success response (200)

{
  "id": "5e9d0273-8a41-4c62-b0f7-1d3e8c95a460",
  "txHash": "0x5d53558791c9346d644d077354420f9a93600acf54eb806ecb9aad077c103ee3",
  "logIndex": 12,
  "chainId": 1,
  "tokenId": "a71c4e08-2f96-4b3d-85ae-6c0f7d21b943",
  "amount": "100000",
  "from": "0x9a3f7c21b8e04d6f5a19c2e70b48d3f61a5e9d02",
  "status": "COMPLETED",
  "confirmations": 24,
  "triggerAddress": "0x7c1a3e889d2b4f618a441f0b6d3c9a5588ab01cd",
  "destination": {
    "type": "BANK_ACCOUNT",
    "id": "b21f4c77-3e5a-4d90-9c18-6a2f7e0b4d31",
    "name": "ACME SDN BHD"
  },
  "result": {
    "status": "COMPLETED",
    "statusReason": null,
    "withdrawal": {
      "id": "c4a80f13-6d29-4e75-83b1-9f0c2a7e5d68",
      "amount": "100000",
      "status": "COMPLETED",
      "refId": "FW-20260807-0001",
      "reference": "ACME payout",
      "createdAt": "2026-08-07T09:31:05.000Z",
      "updatedAt": "2026-08-07T09:34:22.000Z"
    }
  },
  "createdAt": "2026-08-07T09:30:44.000Z",
  "updatedAt": "2026-08-07T09:34:22.000Z"
}
FieldTypeDescription
idstring (UUID)The deposit id
txHashstringTransaction that carried the deposit
logIndexintegerPosition of this transfer within the transaction
chainIdintegerChain the deposit arrived on
tokenIdstring (UUID)Token deposited; matches GET /v1/wallet/networks
amountstringDeposit amount in the token's smallest unit
fromstringThe address the tokens were sent from
statusstringPENDING while confirming, COMPLETED once credited, FAILED if it did not credit
confirmationsintegerConfirmations seen so far
triggerAddressstring | nullThe address that received it, or null for an ordinary deposit
destinationobject | nullThe bank account being paid, or null
resultobject | nullThe withdrawal outcome, or null when nothing was triggered
result.statusstringPENDING, PROCESSING, COMPLETED, or FAILED
result.statusReasonstring | nullWhy it failed. See Status reason values
result.withdrawalobject | nullThe fiat withdrawal object, once one exists

amount and result.withdrawal.amount use different units — the token's smallest unit and sen. Read each from its own field.

404 NOT_FOUND for an unknown deposit id, or one belonging to another account.

Deposit status reason values

result.statusReason is null unless result.status is FAILED.

ValueMeaning
sender_not_allowedThe deposit came from an address you have not allowed
inactive_destinationThe bank account was removed or deactivated
missing_destination_bank_detailsThe bank account has no bank on file
feature_disabledAutomatic withdrawal on deposit is not enabled on your account
account_frozen, account_suspended, account_terminatedYour account status blocked it
withdrawal_amount_out_of_rangeBelow the minimum or above the maximum for your account
daily_fiat_withdrawal_limit_exceededDaily limit reached
monthly_fiat_withdrawal_limit_exceededMonthly limit reached
fiat_withdrawal_rejected, fiat_withdrawal_failed, fiat_withdrawal_cancelledThe bank transfer did not complete
provider_errorAnything else the rail reported. Contact BLOX with the deposit id

The tokens stay credited to your wallet in every case. Where the cause is yours to fix — an address you had not allowed, a bank account you reactivated, a limit that has since rolled over — fix it and retry the deposit.

Check for a missed deposit

POST/v1/wallet/deposits/check-missedAPI key + signature

Asks BLOX to look at a transaction it never picked up. Use it when you sent tokens and nothing arrived.

This is the only endpoint that takes a transaction hash. When the transaction turns out to be known already, the response carries the deposit ids — use those with Get a deposit and Retry a deposit. Limited to 30 calls per minute.

FieldTypeRequiredConstraintsDescription
txHashstringYes0x and 64 hex charactersTransaction that carried the deposit
chainIdintegerYesAn active BLOX networkChain the transaction is on

Success response (201)

{
  "status": "ALREADY_DETECTED",
  "depositIds": ["5e9d0273-8a41-4c62-b0f7-1d3e8c95a460"]
}
FieldTypeDescription
statusstringQUEUED if the transaction is now being picked up, ALREADY_DETECTED if BLOX had it
depositIdsstring[]The deposits in that transaction. Populated on ALREADY_DETECTED, empty on QUEUED

Check status before reading depositIds: an empty array on QUEUED means the deposits do not exist yet, not that none were found. One transaction can carry several deposits. On QUEUED, wait for the webhook rather than calling again.

Expected errors
StatuscodeWhen
400VALIDATION_FAILEDtxHash is not a valid hash, or chainId is not a positive integer
403FEATURE_DISABLEDAutomatic withdrawal on deposit is not enabled on your account
404NOT_FOUNDNo active BLOX network matches chainId
429RATE_LIMITEDOver 30 calls in the last minute

Retry a deposit

POST/v1/wallet/deposits/{id}/redriveAPI key + signature

Re-evaluates a deposit that was credited but produced no bank transfer. Use it after fixing the cause — allowing the sender, reactivating the bank account, or waiting for a limit to roll over.

Safe to call more than once. A deposit that already paid out returns its existing withdrawal, and no second transfer is created. Limited to 60 calls per minute.

No request body. Sign @method and @path only.

Success response (201)

The deposit, in the same shape as Get a deposit, read back after the retry.

Expected errors
StatuscodeWhen
400INVALID_REQUESTThe deposit has not finished confirming, so there is nothing to retry
403FEATURE_DISABLEDAutomatic withdrawal on deposit is not enabled on your account
404NOT_FOUNDUnknown deposit, one belonging to another account, or one that did not arrive on a trigger address
429RATE_LIMITEDOver 60 calls in the last minute

List wallet transactions

GET/v1/wallet/transactionsAPI key

Returns wallet movements newest first. Use it for history and reconciliation; use the resource-specific read endpoints to monitor one withdrawal.

QueryTypeRequiredConstraintsDescription
startDtstringNoISO 8601 datetimeCreated on or after this time
endDtstringNoISO 8601 datetimeCreated on or before this time
typestringNoIN or OUTDirection
modestringNoFIAT or TOKENTransaction mode
limitintegerNo1–100, default 25Records per page
cursorstringNoPrevious response's nextCursorOmit for the first page

Response — 200

{
  "data": [
    {
      "transactionId": "9b3bd9db-75d8-44dc-a74b-16fe968a01c7",
      "type": "OUT",
      "mode": "TOKEN",
      "status": "PENDING",
      "amount": "-10000",
      "fee": "0",
      "effectiveAmount": "-10000",
      "beneficiary": "0x742d35Cc6634C0532925a3b844Bc9e7595f8bD21",
      "reference": "ORDER-4471",
      "refId": "",
      "source": "API",
      "networkId": "ethereum",
      "createdAt": "2026-01-16T10:30:00.000Z",
      "confirmedAt": null
    }
  ],
  "hasMore": true,
  "nextCursor": "MjAyNi0wMS0xNlQxMDozMDowMC4wMDBafDliM2Jk…"
}

Pass nextCursor back as cursor until hasMore is false. There is no total; cursors are opaque. Rows in CREATED status are omitted until the status advances.

FieldTypeDescription
transactionIdstring (UUID)Wallet transaction identifier
typestringIN or OUT
modestringFIAT or TOKEN
statusstringCurrent transaction status
amountstringSigned amount in sen
feestringFee in sen
effectiveAmountstringNet signed wallet movement in sen
beneficiarystring | nullDestination address, bank account, or other recipient label
referencestring | nullYour reconciliation reference
refIdstringBLOX reference when available
sourcestringOrigin of the transaction, such as API
networkIdstring | nullBlockchain network for token movements
createdAtstringISO 8601 creation timestamp
confirmedAtstring | nullISO 8601 completion timestamp
Error responses
StatuscodeWhen
400VALIDATION_FAILEDA query parameter is malformed or outside its constraint
401UNAUTHORIZEDAPI key is missing, unknown, or inactive
403FEATURE_DISABLEDWallet API is not enabled for the account
403ACCOUNT_TERMINATEDThe account is terminated
429RATE_LIMITEDThe route or account rate limit is exceeded
5xxINTERNAL_ERRORUnexpected BLOX failure; report requestId

Error examples

400 VALIDATION_FAILED

For ?limit=101:

{
  "code": "VALIDATION_FAILED",
  "message": "limit: Number must be less than or equal to 100",
  "requestId": "9f21ab04-6c3e-4d90-b1a7-8e5f2c0d4416"
}

Shared response schemas

Token transfer object

FieldTypeDescription
idstring (UUID)Unique transfer identifier
statusstringCREATED, PENDING, PROCESSING, COMPLETED, or FAILED
toAddressstringRecipient wallet address
amountstringNet amount delivered, in sen
feestringFee deducted from the requested amount, in sen
referencestring | nullYour reconciliation reference
sourcestringAPI for API-created transfers
tokenIdstring (UUID)Selected token identifier
tokenobject{ symbol, name, network: { id, name, type } }
txHashstring | nullOn-chain transaction hash after broadcast
confirmationsnumber | nullConfirmations observed so far
confirmedAtstring | nullISO 8601 completion time
createdAt / updatedAtstringISO 8601 timestamps

Fiat withdrawal object

FieldTypeDescription
idstring (UUID)Unique withdrawal identifier
statusstringPENDING, PROCESSING, COMPLETED, FAILED, or REJECTED
amountstringWithdrawal amount in sen
feestringWithdrawal fee in sen
referencestring | nullYour reconciliation reference
refIdstringBLOX withdrawal reference to quote to support
sourcestringAPI for API-created withdrawals
destinationobject | null{ name, accountNumber, bank: { code, name } }
confirmedAtstring | nullISO 8601 completion time
createdAt / updatedAtstringISO 8601 timestamps