Orders and Trading
Overview
Bakkt supports REST-based order management APIs for digital asset trading. Clients integrate via REST to access all order types, time-in-force options, and order lifecycle management.
Bakkt's suite of RESTful APIs tied to order management are used to submit orders, cancel orders, and track order status through either the order retrieval endpoint or AWS SQS event notifications.
Note: For the current list of supported digital assets and their symbols, refer to the Request the Instruments List API endpoint and AWS S3 resources, where these symbols are integrated into various lists, reports, and notifications. This list is subject to change at Bakkt's discretion at any time.
Order Types and Time-in-Force
Order Types
- Market Order: Executes immediately at the current market price.
- Limit order: Will only execute at a specified price.
- Stop limit: Executes (becomes a limit order) when the stop price is reached.
Time-in-Force (TIF)
Time in force is how long the order stays live.
- Immediate or Cancel (IOC): Executes all or part of the order immediately, with unfulfilled parts canceled. The rapid execution of IOC orders means cancellation requests cannot be processed by the system, making all market orders effectively immediate or cancel.
- Good Till Canceled (GTC): Each order remains active for up to 90 days or unless specified otherwise by the client's implementation via Bakkt's API. To maintain market efficiency, Bakkt only accepts those GTC orders that are within a predefined percentage near the market price.
- Day: Orders stay in force until the next maintenance window, but this TIF order is being deprecated in favor of GTC orders, which accommodate longer durations.
Notional vs. Quantity
Orders can be specified in terms of notional value (in dollars) or quantity (in digital asset units). When liquidating an entire position, specifying the order in quantity is recommended to avoid leaving residual amounts of digital assets ("dust") in the account.
Order Samples
| Order Type | TIF | Sample Curl |
|---|---|---|
| Market | IOC | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "MARKET","symbol": "BTCUSD","account": "ABC123","side": "BUY","timeInForce": "IOC","notional": "5","clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f"}' |
| Limit | DAY | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "LIMIT","symbol": "BTCUSD","account": "ABC123","side": "BUY","timeInForce": "DAY","quantity": "5","clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f","price": "0.5"}' |
| Limit | IOC | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "LIMIT","symbol": "BTCUSD","account": "ABC123","side": "BUY","timeInForce": "IOC","quantity": "5","clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f","price": "0.5"}' |
| Limit | GTC | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "LIMIT","symbol": "BTCUSD","account": "9YN05004","side": "BUY","timeInForce": "GTC","quantity": "5","clientOrderId": "e4dc05d9-e15d-47ec-8ee2-7b3a269f0666","price": "0.5"}' |
| Stop Limit | Day | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "STOP_LIMIT","symbol": "BTCUSD", "account": "ABC123","side": "BUY","stopPrice": "0.4","timeInForce": "DAY","quantity": "5","clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f","price": "0.5"}' |
| Stop Limit | GTC | bash curl --request POST \ --url https://api.bakkt.com/apex-crypto/api/v2/orders \ --header 'accept: application/json' \ --header 'Authorization: API-Key <YOUR_API_KEY>' \ --header 'Content-Type: application/json' \ --data '{"type": "STOP_LIMIT","symbol": "BTCUSD","account": "ABC123","side": "BUY","timeInForce": "GTC","notional": "5","clientOrderId": "e4dc05d9-e15d-47ec-8ee2-7b3a269f0625","price": "0.5"}' |
Placing an Order (REST)
To place an order, use the Submit an Order to Buy or Sell Digital Assets (submitOrder) API endpoint. This is the first step in initiating a trade via REST.
curl --request POST \
--url https://api.bakkt.com/apex-crypto/api/v2/orders \
--header 'Authorization: API-Key <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{
"type": "MARKET",
"symbol": "BTCUSD",
"account": "ABC123",
"side": "BUY",
"timeInForce": "IOC",
"notional": "5",
"clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f"
}'Expected Response (200 OK):
{
"orderId": "ord_123",
"clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f",
"status": "accepted",
"type": "MARKET",
"symbol": "BTCUSD",
"side": "BUY",
"timeInForce": "IOC",
"notional": "5"
}Order Lifecycle
Orders progress through several states from submission to settlement:
- Accepted — The order has been received and validated by the system.
- Acknowledged — The order is confirmed and entered into the market.
- Filled — The order or a portion of it has been executed at the market price.
- Partially Filled — The order has been partially executed; the remainder remains open (for GTC or Day TIF only).
- Canceled — The order has been canceled before execution, or unfilled portions have been canceled.
- Rejected — The order was rejected due to validation or business logic failures.
Bakkt leverages the AWS SQS messaging event queue to communicate with clients about the status of their orders, including details about order types, time-in-force parameters, and notional or quantity-based orders.
Retrieving Orders
To retrieve order information, use the Retrieve an Order by Client Order ID (getOrder) API endpoint. This endpoint retrieves a single order by its client-assigned order ID.
curl --request GET \
--url https://api.bakkt.com/apex-crypto/api/v2/orders/{clientOrderId} \
--header 'Authorization: API-Key <YOUR_API_KEY>'Expected Response (200 OK):
{
"orderId": "ord_123",
"clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f",
"account": "ABC123",
"type": "MARKET",
"symbol": "BTCUSD",
"side": "BUY",
"timeInForce": "IOC",
"notional": "5",
"status": "filled",
"filledQuantity": "0.0001234",
"averagePrice": "40500.00"
}Note: The deprecated
getOrdersandgetOrderEntryEventsendpoints have been removed. Use thegetOrderendpoint with a specific clientOrderId to retrieve order details. For event-driven order updates, subscribe to AWS SQS notifications.
Cancelling an Order
Orders can be cancelled if they have not been executed using the Submit a Request to Cancel an Order (cancelOrder) API. Only limit and GTC orders can be cancelled. Market and IOC orders either execute or are rejected immediately, so cancellation is not applicable.
curl --request POST \
--url https://api.bakkt.com/apex-crypto/api/v2/orders/{clientOrderId}/cancel \
--header 'Authorization: API-Key <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{}'Expected Response (200 OK):
{
"orderId": "ord_123",
"clientOrderId": "d3adb33f-some-guid-here-fcaf3b33f",
"status": "canceled"
}Warning: The process for cancellation depends on the order type and timing of the cancellation request. Cancellation requests received during the maintenance window (4:30 PM-5:05 PM CT) will be rejected.
Reject Reasons
Orders may be rejected if they fail validation or business rule checks. The following table lists common rejection reasons:
| Reject Reason | Description |
|---|---|
| unknown: empty quotes | You may get this when trying to place orders when the digital asset system does not have a price for the symbol in your order. |
| unknown: trade quantity exceeds position side | You will get this when you try to sell more coin than what the BFS system believes you have. |
| internal: Could not retrieve jurisdiction status for correspondent account | When an account does not have a valid jurisdiction (e.g., state of ZZ) or the jurisdiction status is not referenced in BFS systems. |
| price too far through market | When you try to place an order more than 10% away from the market we will reject it. For example, you can't place a limit sell that's 10% lower than the current bid and can't place a limit buy that's 10% higher than the current ask. |
| invalid_argument: live_till Order expired | When you try to place an order during the BFS maintenance window (16:30-17:05 CT) you will receive these. |
| failed_precondition: unable to trade due to 'NY' allowing CLOSE only | Attempting to place a Buy order from a jurisdiction that is not enabled for purchasing digital assets on that symbol. |
| invalid_argument: price may not place orders of XLMUSD with more than 4 decimal places, had 6 | The order placed has too many decimal places for the price for the specified symbol. |
| invalid_argument: quantity order notional must be more than $1.00 unless selling out entire position | This happens when you try to buy or sell less than $1 of coin. BFS only allows below that limit when you are selling an entire position. |
Updated 3 days ago
