Skip to main content

Overview

Welcome to the Bullish Deprecated Features & APIs documentation!

This documentation provides a list of Features and APIs that have been marked as deprecated, and will be decommissioned soon. You will still be able to use these Features or APIs till the stated decommission date.

Deprecated Features

List of Features that are marked for deprecation.

Bullish Key

Decommissioned: Creation of Bullish API key has been suspended as of 29 March, 2024

Deprecated: Existing Bullish API key will no longer be usable as of 28 June, 2024

  • A Bullish API key is a public/private key pair used for ECDSA based signing of trading and custody API requests
  • From here on the:
    • public key will be referred to as PUBLIC_KEY
    • private key will be referred to as PRIVATE_KEY
  • For information about the format of keys please review EOS Wallet Specification
  • Always store your private keys in a secure medium as they are used to sign your requests. Do not share your private keys in any publicly accessible areas such as code repositories, client side code, or other vulnerable areas and make sure the keys are not shipped with your mobile or web apps.

A Bullish API key additionally has a metadata string associated with it which is displayed along side the key. You must base64 decode the metadata to extract your userId (example follows). You will need the userId in the next step. Please note that the accountId field is deprecated, and will be removed along with v1/users/login API towards the end of Q4 2023. Clients should reference the userId field instead. Old metadata strings generated before the March 2023 upgrade will not contain the userId field; clients are advised to get the metadata from the Settings page on the UI again.

echo eyJwdWJsaWNLZXkiOiJQVUJfUjFfNWNpVW52TW5rVThMOVBCWnZaa1BGcjhqdkRnUHpzcHhWNGlqOThIN1JqM1FSNzJyMkEiLCJhY2NvdW50SWQiOjIyMjAwMDAwMDAwMDAwNCwiY3JlZGVudGlhbElkIjoiMTAifQ== | base64 --decode
{"publicKey":"PUB_R1_5ciUnvMnkU8L9PBZvZkPFr8jvDgPzspxV4ij98H7Rj3QR72r2A","userId":"12345","accountId":"12345","credentialId":"10"}

Signing Format (Old)

Deprecated: Please use the new Signing Format

Before signing the <COMMAND> string remove any spaces and newline characters.

The resulting value is also referred to as the request signature. Each component of the signature is detailed below:

  • <TIMESTAMP>: number of milliseconds since EPOCH
  • <NONCE>: client side incremented 64-bit unsigned integer
  • <AUTHORIZER>: JWT authorizer you obtain along with the JWT token
  • <COMMAND>: the command which is sent in the request payload, JSON encoded

How To Sign - Bullish API Key

To obtain the signature:

  1. Encode the request JSON payload, also referred to as body, with the SHA-256 hash function and take the hexdigest
  2. Sign the hexdigest from step 1 with ECDSA P-256 using your <PRIVATE_KEY>
  3. Various signing examples can be found on GitHub

How To Sign - HMAC API Key

To obtain the signature:

  1. Encode the request JSON payload, also referred to as body, with the SHA-256 hash function and take the hexdigest
  2. Sign the hexdigest from step 1 with your HMAC Secret Key.

See sign a request with HMAC for a sample Python script.

Hybrid Order Book WebSocket (unauthenticated)

Deprecated: Please use the unauthenticated multi-order book WebSocket.

Route

  • /markets/{symbol}/orderbook/hybrid
  • /v2/market-data/orderbook/hybrid/{symbol}?depth={depth}&aggregationFactor={aggregationFactor}

Additional notes:

  • Allowable depths - [ 10, 50, 100, 200 ].
  • Allowable aggregation factors - [ 1, 5, 10 ].
  • This endpoint does not require subscriptions.

On connection, the client receives a snapshot of the current hybrid order book with default depth of 10 (unless specified otherwise). Subsequently, if the order book moves, the client then receives a conflated update of the hybrid order book periodically at 300ms with standard ingress and at 100ms with Cloudflare bypass. If there is a sequence number mismatch between the conflated update and the snapshot, the server disconnects the client with the following error message - 4003 (Try Again, sequence number miss-match between snapshot and updates).

l2Snapshot response

NameTypeDescription
symbolStringmarket symbol
bidsArrayarray of size 20 (default unless specified otherwise by the depth parameter) where even indices denote price, odd indices denote absolute quantities
asksArrayarray of size 20 (default unless specified otherwise by the depth parameter) where even indices denote price, odd indices denote absolute quantities
sequenceNumberRangeArrayarray of size 2 where first element denotes lower bound, second element denotes upper bound of sequence numbers
lower and upper bound are equal for initial snapshot; this may differ for subsequent snapshots
datetimeStringdenotes the time the update was created by the engine, ISO 8601 with millisecond as string
timestampStringdenotes the time the update was created by the engine
publishedAtTimestampStringdenotes the time the update was broadcasted to connected WebSockets
{
"type": "snapshot",
"dataType": "V1TALevel2",
"data": {
"symbol": "BTCUSD",
"bids": [
"5199.5000",
"110.92467647",
"5199.4000",
"20.92470365",
"5199.3000",
"0.92473034",
"5199.2000",
"0.92475701",
"5199.1000",
"0.92478369",
"5199.0000",
"0.92481038",
"5198.9000",
"0.92483705",
"5198.8000",
"0.92486375",
"5198.7000",
"0.92489042",
"5198.6000",
"0.92491712"
],
"asks": [
"5199.6000",
"96.37848193",
"5199.7000",
"0.92465082",
"5199.8000",
"11.04464563",
"5199.9000",
"0.92459696",
"5200.0000",
"0.92457029",
"5200.1000",
"0.92454362",
"5200.2000",
"0.92451695",
"5200.3000",
"0.92449028",
"5200.4000",
"0.92446361",
"5200.5000",
"0.92443695"
],
"sequenceNumberRange": [6, 6],
"datetime": "2020-05-13T10:23:46.000Z",
"timestamp": "1589365426000",
"publishedAtTimestamp": "1589365426100"
}
}

l2Update response

NameTypeDescription
symbolStringmarket symbol
bidsArrayeven indices denote price, odd indices denote absolute quantities
asksArrayeven indices denote price, odd indices denote absolute quantities
sequenceNumberRangeArrayarray of size 2 where first element denotes lower bound, second element denotes upper
bound of sequence numbers represented by the conflated update
datetimeStringdenotes the time the update was created by the engine, ISO 8601 with millisecond as string
timestampStringdenotes the time the update was created by the engine
publishedAtTimestampStringdenotes the time the update was broadcasted to connected WebSockets
{
"type": "update",
"dataType": "V1TALevel2",
"data": {
"symbol": "BTCUSD",
"bids": [],
"asks": ["5199.7000", "101.30313224"],
"sequenceNumberRange": [7, 10],
"datetime": "2020-06-29T06:28:55.500Z",
"timestamp": "1593412135500",
"publishedAtTimestamp": "1593412135600"
}
}

Maintaining Hybrid Order Book

  1. Connect to hybrid order book WebSocket API.
  2. Receive initial snapshot message.
  3. Record sequence number and create order book.
  4. Compare current sequence number with that of new message. If sequence number is out of order, reconnect.
  5. Receive update messages of price levels with new absolute quantity and update order book. If quantity is 0, price level is removed.
  6. Receive a subsequent snapshot message and reset existing order book. Create order book with new price levels.

See connect to hybrid order book WebSocket for a sample Python script.

Market Data WebSocket (authenticated)

Deprecated: Please use the unauthenticated multi-order book WebSocket.

Route

  • /v1/market-data | Topic | Description | Data Type | Subscription Type | |:--------------|:------------------------------------------|:-----------------|:----------------------------| | l1Orderbook | Provides updates for Level 1 market data | V1TABookLevel1 | By <TOPIC> and <SYMBOL> |

l1Orderbook response

  • Level 1 market data updates are realtime.
  • If the sequenceNumber of an incoming update is smaller than that of a previously received update, then the sequenceNumber is out of order. Terminate the WebSocket connection and reconnect. | Name | Type | Description | |:---------------|:-------|:----------------------------------------------------------------- | | sequenceNumber | String | incrementing, unique, unsigned integer that identifies a state of the L1 order book | | symbol | String | market symbol | | timestamp | String | denotes the time the update was created | | bid | Array | nested array containing price and quantity of highest bid | | ask | Array | nested array containing price and quantity of lowest ask |
{
"type": "update",
"dataType": "V1TABookLevel1",
"data": {
"sequenceNumber": "1",
"symbol": "BTCUSD",
"timestamp": "1466812800000",
"bid": [ [ "35.0000", "2.00000000" ] ],
"ask": [ [ "35.5000", "1.00000000" ] ]
}
}

See connect to market data WebSocket for a sample Python script.

Spot Account

Deprecated: Spot Account will be replaced by Asset Account which provides a more granular view of the assets in your trading account

spotAccounts response

The Formula colummn below shows how the fields in V1TASpotAccount are calculated.

NameTypeDescriptionFormula
(expressed in assetAccounts response fields)
accountIdStringunique spot account ID
symbolStringasset symbol
typeStringtype of account
totalStringtotal is free + used assets within the account, see asset value format=max(0, availableQuantity - borrowedQuantity) + lockedQuantity
freeStringrefers to the assets that are available to use on the account excluding borrowed assets, see asset value format.=max(0, availableQuantity - borrowedQuantity)
usedStringrefers to the assets that are locked in orders, see asset value format=lockedQuantity
updatedAtDatetimeStringdenotes the time the spot account was updated by the exchange, ISO 8601 with millisecond as string
updatedAtTimestampStringdenotes the time the spot account was updated by the exchange
publishedAtTimestampStringdenotes the time the update was broadcasted to connected WebSockets
{
"tradingAccountId": "1111",
"type": "snapshot",
"dataType": "V1TASpotAccount",
"data": [
{
"accountId": "1",
"type": "spot",
"symbol": "BTC",
"total": "4.00000000",
"free": "4.00000000",
"used": "0.00000000",
"updatedAtDatetime": "2021-12-30T07:36:35.918Z",
"updatedAtTimestamp": "1640849795918",
"publishedAtTimestamp": "1640849795920"
}
]
}

Anonymous Trades WebSocket (unauthenticated)

Route

  • /v1/market-data/trades/{symbol}

Note: This endpoint does not require subscriptions.

On connection, the client receives a snapshot of the latest 100 trades, in descending order. Subsequently, the client receives real-time updates of trades that have been executed. If the tradeId of an incoming update is smaller than that of a previously received update, then the tradeId is out of order. Terminate the WebSocket connection and reconnect.

Trades response

NameTypeDescription
tradeIdStringunique trade ID
symbolStringmarket symbol
priceStringprice, see asset value format
quantityStringquantity, see asset value format
sideStringorder side
isTakerBooleandenotes whether this is a taker's trade
createdAtTimestampStringdenotes the time the order was ACK'd by the exchange
createdAtDatetimeStringdenotes the time the order was ACK'd by the exchange, ISO 8601 with millisecond as string
publishedAtTimestampStringdenotes the time the update was broadcasted to connected WebSockets
{
"type": "update",
"dataType": "V1TAAnonymousTrade",
"data": {
"tradeId": "100000000000001050",
"symbol": "BTCUSD",
"price": "11528.2203",
"quantity": "1.00000000",
"side": "BUY",
"isTaker": true,
"createdAtTimestamp": "1662453438774",
"createdAtDatetime": "2022-09-06T08:37:18.774Z",
"publishedAtTimestamp": "1662453438780"
}
}

See connect to trades WebSocket for a sample Python script.

Decommissioned Features

List of Features that have been decommissioned and no longer usable.

Changelog

2025 Changes

  • May
    • Deprecated Features:
      • Anonymous Trades WebSocket (unauthenticated)

2024 Changes

  • April
    • Deprecated Features:
      • Bullish API Key
      • Signing Format (Old)
      • Hybrid OrderBook WebSocket (unauthenticated)
      • Market Data WebSocket (authenticated)
      • Spot Account
    • Deprecated APIs for end of Q3 2024:
      • REST - GET | POST | DELETE /trading-api/v1/orders
      • REST - GET /v1/orders/{orderId}
      • REST - POST /v1/command?commandType=V1CancelAllOrders
      • REST - POST /v1/command?commandType=V1CancelAllOrdersByMarket
      • REST - POST /v1/command?commandType=V1DelayedCancelAllOrders
      • REST - POST /v1/command?commandType=V1UnsetDelayedCancelAllOrders
      • REST - GET | POST | DELETE /v1/amm-instructions
      • REST - GET /v1/amm-instructions/{liquidityId}
    • Deprecated APIs:
      • REST GET /accounts/spot
      • REST GET /accounts/spot/asset