Every authenticated request to the Bullish Trading API requires three additional headers beyond theDocumentation 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.
Authorization bearer token: BX-TIMESTAMP, BX-NONCE, and BX-SIGNATURE. Together these headers prove that a specific request body was sent at a specific time by the holder of the API key, and that it has not been replayed or tampered with.
The
BX-NONCE used in authenticated API requests (orders, commands, etc.) is a separate concept from the nonce field in the JWT login payload. The login nonce is an epoch timestamp in seconds; the BX-NONCE is a client-managed monotonically increasing counter. They are completely independent.BX-NONCE Header
TheBX-NONCE value is a unique client-side 64-bit unsigned integer. Each request you send must use an incrementing BX-NONCE value.
Characteristics
- Each request must carry an incrementing
BX-NONCEvalue. - The exchange only accepts nonces within a permitted range to prevent exhaustion of the 64-bit unsigned integer space.
- The valid nonce range is updated daily.
- The
lowerBoundof the range is the start-of-day UNIX timestamp in microseconds. - The
upperBoundof the range is the end-of-day UNIX timestamp in microseconds.
Fetching the Nonce Range
Retrieve the current valid nonce bounds from:lowerBound as the starting point for your nonce counter. Increment it with each subsequent request.
Numeric (i64) identifiers such as
nonce and handle must not have leading zeros. For example, 009990822212000000 is invalid; 9990822212000000 is valid.BX-TIMESTAMP Header
TheBX-TIMESTAMP header is the number of milliseconds since the UNIX epoch at the time of the request. It is included in the signature string to prevent replay attacks.
Constructing the BX-SIGNATURE Header
TheBX-SIGNATURE is computed by building a canonical string from the request parameters, hashing it, and signing the result.
Signing Format
This signing format applies to:POST /trading-api/v2/ordersPOST /trading-api/v2/amm-instructionsPOST /trading-api/v2/command- All Custody API endpoints
- Null fields do not need to be included in the HTTP request body.
- Fields do not need to be strictly ordered in the HTTP request body.
Step 1 — Build the Canonical String
Concatenate the following fields in order (no separator):| Component | Description |
|---|---|
BX-TIMESTAMP | The value sent in the BX-TIMESTAMP header. |
BX-NONCE | The value sent in the BX-NONCE header. |
HTTP_METHOD | The HTTP method in uppercase, e.g. POST. |
REQUEST_PATH | The full request path, e.g. /trading-api/v2/orders. |
REQUEST_BODY | The JSON request body with all spaces and newline characters removed. |
Step 2 — Sign the String
- ECDSA API Key
- HMAC API Key
- Hash the canonical string using SHA-256 and take the hexdigest.
- Sign the hexdigest with your ECDSA
PRIVATE_KEY. - DER-encode the resulting signature.
- Base64-encode the DER-encoded signature.
BX-SIGNATURE value.See sign a request with ECDSA for a sample Python script.BX-RATELIMIT-TOKEN Header
Each trading account has a unique rate limit token that is used to access higher rate limit tiers.- Without a
BX-RATELIMIT-TOKENheader, the default rate limit of 50 messages per second applies. - To access higher tiers, include the
BX-RATELIMIT-TOKENheader with the token for the relevant trading account.
Obtaining Your Rate Limit Token
Retrieve rate limit tokens from:BX-RATELIMIT-TOKEN request header.
For more information on increasing your rate limits beyond the available tiers, contact your sales representative.
Ensuring the Order of Create Order / Cancel Order Requests
To guarantee that create order and cancel order requests are processed in the intended sequence, wait for the acknowledgement response — which contains the server-generatedorderId — before sending the next request.
The nonce for these requests must be a unique, monotonically increasing integer. If multiple requests are dispatched simultaneously without waiting for acknowledgements:
- Requests are processed in parallel by the exchange.
- Validation of each request’s
nonceoccurs at the time it arrives, which may differ from the order sent. - Any request with a
noncelower than the most recently validatednonceis considered invalid and dropped. - In the worst case, the request with the highest
nonceis validated first, causing all earlier requests to be rejected.
orderId acknowledgement before proceeding.
Out-of-Order Processing with BX-NONCE-WINDOW-ENABLED
For use cases that require concurrent order submission, theBX-NONCE-WINDOW-ENABLED header enables out-of-order processing:
| Header | Value |
|---|---|
BX-NONCE-WINDOW-ENABLED | "true" or "false" (string representation of a boolean) |
"true", the strict incrementing requirement is relaxed: nonces are only required to be unique (not strictly ordered), within a window of 100 from the highest previously used nonce value (inclusive).
For example, with BX-NONCE-WINDOW-ENABLED: true, you can send nonce values 1 through 100 in any order and all will be accepted.
How EMS/Brokers Flag Their Executions
EMS platforms and brokers can flag their executions sent to Bullish using theBX-REFERRER header:
| Header | Description |
|---|---|
BX-REFERRER | A unique identifier assigned to your EMS or broker by Bullish. |
- Create Order —
POST /trading-api/v2/orders - Create OTC Trade —
POST /trading-api/v2/otc-trades
Code Examples
Sample Python scripts are available in the official api-examples repository:create_order_ecdsa.py— Sign and create an order using ECDSAcreate_order_hmac.py— Sign and create an order using HMAC