Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/bullish-exchange/api-docs/llms.txt

Use this file to discover all available pages before exploring further.

These endpoints cover the full lifecycle of moving funds into and out of your Bullish Exchange custody account. You can retrieve deposit addresses for crypto and fiat, look up your whitelisted withdrawal destinations, and submit withdrawal requests. All endpoints require authentication via a bearer token, and the withdrawal submission endpoint additionally requires an ECDSA signature in the request header.
All custody endpoints — including every endpoint on this page — require a JWT token generated with an ECDSA API key. HMAC API keys produce tokens that are only valid for trading endpoints. Requests to /wallets/* endpoints made with an HMAC-derived token will be rejected. Make sure you use an ECDSA key when generating your JWT.
All custody endpoints share a rate limit of 40 requests per IP, per minute across all /wallets/* routes.
Custody endpoints use a non-multiplied asset format for long-decimal assets. Where the Trading API uses SHIB1M or PEPE1M, custody endpoints use the real-world symbols SHIB and PEPE. See the Bullish Help Centre for full details.

GET /trading-api/v1/wallets/deposit-instructions/crypto/

Returns the on-chain deposit address (and optional memo or destination tag) for a given crypto asset. Send funds to the returned address on the correct network to credit your Bullish account.

Request parameters

Authorization
string
required
Bearer token generated with an ECDSA API key.Example: Bearer <jwt_token>
symbol
string
required
Crypto asset symbol in non-multiplied custody format.Example: BTC, ETH, USDC, SHIB

Response fields

The response is an array of deposit instruction objects. Multiple entries may be returned when an asset is supported across more than one network.
network
string
Network on which the deposit address is valid, e.g. ETH, BTC, SOL.
symbol
string
Asset symbol, e.g. USDC, BTC, ETH.
address
string
On-chain address to send funds to.Example: 0xb0a64d976972d87b0783eeb1ff88306cd1891f02
memo
string
Optional memo or destination tag required by certain networks (e.g. XRP, XLM). Include this value when sending funds or the deposit may not be credited.Example: 925891241

Example request

curl -X GET "https://api.exchange.bullish.com/trading-api/v1/wallets/deposit-instructions/crypto/USDC" \
  -H "Authorization: Bearer <jwt_token>"

Example response

[
  {
    "network": "ETH",
    "symbol": "USDC",
    "address": "0xb0a64d976972d87b0783eeb1ff88306cd1891f02"
  }
]

GET /trading-api/v1/wallets/withdrawal-instructions/crypto/

Returns the list of whitelisted crypto withdrawal destinations for a given asset. Each entry includes the destination ID, network address, and the withdrawal fee that will be charged.
All withdrawal addresses must be whitelisted via the Bullish website before any digital asset withdrawal can be processed. If you attempt a withdrawal to a non-whitelisted address, the request will fail.

Request parameters

Authorization
string
required
Bearer token generated with an ECDSA API key.Example: Bearer <jwt_token>
symbol
string
required
Crypto asset symbol in non-multiplied custody format.Example: BTC, ETH, USDC

Response fields

The response is an array of withdrawal instruction objects, one per whitelisted destination.
network
string
Network for this withdrawal destination, e.g. ETH, BTC.
symbol
string
Asset symbol, e.g. USDC, BTC.
address
string
Whitelisted on-chain address.Example: 0xb0a64d976972d87b0783eeb1ff88306cd1891f02
fee
string
Withdrawal fee charged in units of the symbol (not smaller denominations).Example: 3.00
memo
string
Optional memo or destination tag that will be included in the on-chain transaction.Example: MZAXEMRXA
label
string
User-provided descriptive label for this destination address.Example: Our cold wallet
destinationId
string
Bullish-issued identifier for this whitelisted destination. Use this value in the POST /wallets/withdrawal request body.Example: 1560ec0b406c0d909bb9f5f827dd6aa14a1f638884f33a2a3134878102e78038

Example request

curl -X GET "https://api.exchange.bullish.com/trading-api/v1/wallets/withdrawal-instructions/crypto/BTC" \
  -H "Authorization: Bearer <jwt_token>"

Example response

[
  {
    "network": "BTC",
    "symbol": "BTC",
    "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
    "fee": "0.00010000",
    "label": "Our cold wallet",
    "destinationId": "1560ec0b406c0d909bb9f5f827dd6aa14a1f638884f33a2a3134878102e78038"
  }
]

POST /trading-api/v1/wallets/withdrawal

Submits a withdrawal request for either crypto or fiat. The destination must already be whitelisted on the Bullish website. This endpoint requires both a bearer token and a BX-SIGNATURE header signed with your ECDSA private key.
Bullish requires you to whitelist a withdrawal destination address before submitting a withdrawal request. You can view, approve, and manage your list of destination addresses in Account Settings on the Bullish website. Withdrawal attempts to non-whitelisted addresses will fail.

Constructing the BX-SIGNATURE header

The BX-SIGNATURE header is an ECDSA signature over a canonical string built from the request. To construct it:
  1. Concatenate the following fields into a single string (no separators):
    • timestamp — current epoch milliseconds, e.g. 1697008474031
    • nonce — a UUID to protect against replay attacks, e.g. 255241a1-2cde-4954-87b1-13beef547960
    • request method — e.g. POST
    • request path — e.g. /trading-api/v1/wallets/withdrawal
    • request body JSON string — with all spaces and newline characters removed
  2. Hash the concatenated string using SHA-256 and sign the hexdigest with your PRIVATE_KEY.
  3. DER-encode the signature and then Base64-encode the DER-encoded result. This Base64 string is your BX-SIGNATURE.
For a complete working example see the Custody Withdrawal Example on GitHub.

Request parameters

Authorization
string
required
Bearer token generated with an ECDSA API key.Example: Bearer <jwt_token>
BX-SIGNATURE
string
required
Base64-encoded DER-encoded ECDSA signature over the canonical request string. See construction steps above.

Request body

timestamp
string
required
Current epoch time in milliseconds as a string.Example: "1697008474031"
nonce
string
required
A UUID withdrawal nonce to protect against replay attacks. It is recommended to reuse the same value as the nonce in the BX-SIGNATURE header.Example: "255241a1-2cde-4954-87b1-13beef547960"
authorizer
string
required
JWT authorizer string obtained alongside your JWT token during the login flow.
command
object
required
The withdrawal command object.

Response fields

statusReason
string
Human-readable description of the withdrawal status.Example: Withdrawal accepted
statusReasonCode
integer
Numeric status reason code. See the Error & Rejection Codes reference for the full list.Example: 1001
custodyTransactionId
string
Unique identifier for tracking this withdrawal in the transaction history.Example: DB:9e6304a08c9cc2a33e6bc6429a088eae2a6b940c8e312aede3a3780257b9b979

Example request

curl -X POST "https://api.exchange.bullish.com/trading-api/v1/wallets/withdrawal" \
  -H "Authorization: Bearer <jwt_token>" \
  -H "BX-SIGNATURE: <base64_der_ecdsa_signature>" \
  -H "Content-Type: application/json" \
  -d '{
    "timestamp": "1697008474031",
    "nonce": "255241a1-2cde-4954-87b1-13beef547960",
    "authorizer": "<authorizer_string>",
    "command": {
      "commandType": "V1Withdrawal",
      "destinationId": "1560ec0b406c0d909bb9f5f827dd6aa14a1f638884f33a2a3134878102e78038",
      "symbol": "BTC",
      "network": "BTC",
      "quantity": "0.50000000"
    }
  }'

Example response

{
  "statusReason": "Withdrawal accepted",
  "statusReasonCode": 1001,
  "custodyTransactionId": "DB:9e6304a08c9cc2a33e6bc6429a088eae2a6b940c8e312aede3a3780257b9b979"
}

Build docs developers (and LLMs) love