A modern C++ SDK for interacting with the Coinbase Advanced API, providing both REST and WebSocket functionality for trading, market data, and account management.
- REST API Support: Complete implementation of Coinbase Advanced API endpoints for accounts, orders, products, trades, and more
- WebSocket Support: Real-time market data streaming with level2, ticker, market trades, and user data channels
- Connection lifecycle callbacks for connect/disconnect events
- Per-client sequence number tracking for multiple concurrent connections
- Explicit shutdown control with
stop()method
- Shared Multiplexer: Multiple
WebSocketClientinstances share oneslick::stream_buffer_multiplexer— unified lock-free ring-buffer allocation and a single fan-in queue across all symbols - Cross-process IPC: Producer buffers and the fan-in queue can be placed in named shared memory; a second process can attach and read the same raw JSON stream without an extra network connection
- Comprehensive Order Types: Support for market, limit, stop limit, bracket, and TWAP orders
- Type Safety: Full C++ type definitions for all API responses with JSON serialization/deserialization
- Modern C++: Uses C++20 features, RAII, smart pointers, and modern C++ best practices
- Async/Await Support: Built-in async support using C++ coroutines
- Thread-Safe: Designed for multi-threaded applications with lock-free data structures
The SDK is organized into several key components:
include/coinbase/
├── account.hpp # Account and balance management
├── auth.hpp # Authentication utilities
├── candle.hpp # Candlestick data
├── common.hpp # Common types and enums
├── convert.hpp # Currency conversion (Convert) data models
├── fill.hpp # Fill data
├── futures.hpp # Futures (CFM) data models
├── key_permissions.hpp # API key permissions (Data API) data models
├── logging.hpp # Logging utilities
├── market_data.hpp # Market data structures
├── order.hpp # Order management
├── payment_method.hpp # Payment methods data models
├── perpetuals.hpp # Perpetuals (INTX) data models
├── portfolio.hpp # Portfolios data models
├── position.hpp # Position management
├── price_book.hpp # Price book data
├── product.hpp # Product information
├── rest.hpp # REST client implementation
├── rest_awaitable.hpp # Async REST operations
├── side.hpp # Order side definitions
├── trades.hpp # Trade data
├── utils.hpp # Utility functions
└── websocket.hpp # WebSocket client implementation
- C++20 compatible compiler (GCC 10+, Clang 10+, MSVC 2019+)
- CMake 3.20+
- OpenSSL
- nlohmann/json (JSON library)
- jwt-cpp (JSON Web Token library)
- slick-net (networking library - automatically fetched via CMake)
- vcpkg (optional, dependency management)
mkdir build
cd build
cmake ..
cmake --build . --config Release
cmake --install . --prefix /usr/local # or your preferred install locationThe library is built as a static library for optimal compilation performance in downstream projects.
This repo includes a vcpkg.json manifest. If you use vcpkg, dependencies are installed automatically via the toolchain file. If a vcpkg port for slick-net is available, it will be used; otherwise CMake falls back to FetchContent.
cmake -S . -B build \
-DCMAKE_TOOLCHAIN_FILE=C:/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build#include <coinbase/rest.hpp>
// Create client
coinbase::CoinbaseRestClient client;
// Get server time
auto timestamp = client.get_server_time();
// List accounts
auto accounts = client.list_accounts();
// Get product information
auto product = client.get_product("BTC-USD");
// Create order
auto response = client.create_order(
"client_order_id_123",
"BTC-USD",
coinbase::Side::BUY,
coinbase::OrderType::LIMIT,
coinbase::TimeInForce::GOOD_UNTIL_CANCELLED,
0.001,
50000.0,
true // post_only
);
// Cancel order
auto cancel_response = client.cancel_orders({"order_id_123"});
// Portfolios
auto portfolios = client.list_portfolios();
auto breakdown = client.get_portfolio_breakdown(portfolios.front().uuid);
// Convert (quote only - commit_convert_trade executes a real conversion)
auto quote = client.create_convert_quote(from_account_uuid, to_account_uuid, 10.0);
// Futures (CFM)
auto balance_summary = client.get_futures_balance_summary();
auto positions = client.list_futures_positions();CoinbaseAwaitableRestClient mirrors every CoinbaseRestClient method as a C++20 coroutine returning asio::awaitable<T>, so the same endpoints (including all of the ones listed in API Endpoints) can be awaited from coroutine-based code:
#include <coinbase/rest_awaitable.hpp>
coinbase::CoinbaseAwaitableRestClient client;
asio::awaitable<void> run() {
auto accounts = co_await client.list_accounts();
auto portfolios = co_await client.list_portfolios();
auto permissions = co_await client.get_api_key_permissions();
// ...
}The SDK provides two callback mechanisms for handling WebSocket data:
-
WebsocketCallbacks: Callbacks are invoked directly on the WebSocket thread. Use this for simple applications or when you want immediate processing. -
UserThreadWebsocketCallbacks: Callbacks are invoked on your own thread. The WebSocket data is queued in a lock-free queue, and you control when to process it by callingprocessData(). Use this for better control over threading and to avoid blocking the WebSocket thread.
#include <coinbase/websocket.hpp>
class MyCallbacks : public coinbase::WebsocketCallbacks {
public:
// Connection lifecycle callbacks
void onMarketDataConnected(coinbase::WebSocketClient* client) override {
// Handle market data connection established
}
void onMarketDataDisconnected(coinbase::WebSocketClient* client) override {
// Handle market data disconnection
}
void onUserDataConnected(coinbase::WebSocketClient* client) override {
// Handle user data connection established
}
void onUserDataDisconnected(coinbase::WebSocketClient* client) override {
// Handle user data disconnection
}
// Data callbacks
void onLevel2Snapshot(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& snapshot) override {
// Handle level2 snapshot
}
void onLevel2Updates(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& updates) override {
// Handle level2 updates
}
void onMarketTrades(coinbase::WebSocketClient* client, uint64_t seq_num,
const std::vector<coinbase::MarketTrade>& trades) override {
// Handle market trades
}
// Error callbacks
void onMarketDataError(coinbase::WebSocketClient* client, std::string&& err) override {
// Handle market data errors
}
void onUserDataError(coinbase::WebSocketClient* client, std::string&& err) override {
// Handle user data errors
}
// ... other callback methods
};
// Create WebSocket client
MyCallbacks callbacks;
coinbase::WebSocketClient client(&callbacks);
// Subscribe to channels
std::vector<std::string> product_ids = {"BTC-USD", "ETH-USD"};
std::vector<coinbase::WebSocketChannel> channels = {
coinbase::WebSocketChannel::LEVEL2,
coinbase::WebSocketChannel::TICKER
};
client.subscribe(product_ids, channels);
// Explicitly stop WebSocket connections when done
client.stop();#include <coinbase/websocket.hpp>
class MyCallbacks : public coinbase::UserThreadWebsocketCallbacks {
public:
// Same callback signatures as WebsocketCallbacks
void onMarketDataConnected(coinbase::WebSocketClient* client) override {
// Handle market data connection established
}
void onLevel2Snapshot(coinbase::WebSocketClient* client, uint64_t seq_num,
const coinbase::Level2UpdateBatch& snapshot) override {
// Handle level2 snapshot
}
// ... other callback methods
};
// Create callbacks and WebSocket client
MyCallbacks callbacks;
coinbase::WebSocketClient client(&callbacks);
// Subscribe to channels
client.subscribe({"BTC-USD", "ETH-USD"}, {
coinbase::WebSocketChannel::LEVEL2,
coinbase::WebSocketChannel::TICKER
});
// In your main loop or dedicated thread, process queued data
while (running) {
// Process up to 100 queued messages per call
callbacks.processData(100);
// Your other application logic here
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
client.stop();Key Differences:
WebsocketCallbacks: Immediate processing on WebSocket I/O thread. Simple but can block WebSocket operations if callbacks are slow.UserThreadWebsocketCallbacks: Deferred processing on your thread. Better performance and control, but requires callingprocessData()regularly. Uses lock-free queues for efficient data transfer between threads.
Multiple WebSocketClient instances can share one slick::stream_buffer_multiplexer. Each client is assigned a non-overlapping range of producer IDs via producer_offset. A single processData() drains messages from all symbols in arrival order.
slick::stream_buffer_multiplexer mux(1u << 17);
// BTC uses producer IDs 0–3, ETH uses 4–7
coinbase::WebSocketClient ws_btc(&callbacks, mux, MD_URL, "", 0);
coinbase::WebSocketClient ws_eth(&callbacks, mux, MD_URL, "",
coinbase::ProducerType::_PRODUCER_TYPE_COUNT_);
while (running) {
callbacks.processData(200); // drains both symbols
}Passing md_read_buffer_shm_name to the WebSocketClient constructor places the MD_DATA producer buffer in named shared memory. Combining this with a shared-memory fan-in queue lets a second process attach and read the same raw JSON stream — no extra network connection required.
// Process A — producer
slick::stream_buffer_multiplexer mux(1u << 17, "my_mux_queue");
coinbase::WebSocketClient ws(&callbacks, mux, MD_URL, "", 0,
1u << 26, 1u << 16, "my_btc_md_buf");
// Process B — reader (no WebSocket, no coinbase parsing)
slick::stream_buffer_multiplexer reader_mux("my_mux_queue");
reader_mux.add_producer(0 /*MD_DATA producer_id*/, "my_btc_md_buf");
uint64_t cursor = reader_mux.initial_reading_index();
while (running) {
if (auto rec = reader_mux.read(cursor)) {
// rec.data points to raw JSON bytes; rec.length is the frame size
std::cout.write(reinterpret_cast<const char*>(rec.data), rec.length);
}
}See examples/multi_websockets_ws_callbacks.cpp (producer) and examples/multi_websockets_ws_callbacks_reader.cpp (cross-process reader) for a complete two-symbol demo.
- Accounts: List accounts, get account details
- Products: List products, get product details
- Orders: Create, list, get, modify, and cancel orders
- Fills: List fills
- Fees: Get taker and maker fee rates
- Market Data: Get best bid/ask, price book, market trades, candles
- Time: Get server time
- Portfolios: List portfolios, create/edit/delete a portfolio, get portfolio breakdown, move funds between portfolios
- Convert: Create a convert quote, get a convert trade, commit a convert trade
- Payment Methods: List payment methods, get payment method details
- Data API: Get API key permissions
- Futures (CFM): Get balance summary, list/get positions, schedule/list/cancel sweeps, get/set intraday margin settings, get current margin window
- Perpetuals (INTX): Allocate portfolio, get portfolio summary, list/get positions, get portfolio balances, opt in/out of multi-asset collateral
All REST endpoints are available on both the synchronous CoinbaseRestClient and the coroutine-based CoinbaseAwaitableRestClient (see Async REST Client).
- Level2: Order book updates
- Ticker: Price updates
- Market Trades: Trade updates
- User: User-specific data (orders, positions)
- Candles: Candlestick data
- Status: Product status updates
The SDK supports multiple order types:
- Market Orders: Execute immediately at market price
- Limit Orders: Execute at specified price
- Stop Limit Orders: Execute when stop price is hit, then as limit order
- Bracket Orders: Place both stop loss and take profit orders
- TWAP Orders: Split order execution over time
The SDK handles JWT authentication automatically using the coinbase::generate_coinbase_jwt function. You need to provide your API key and secret.
The examples/ directory contains five self-contained programs. Build them with -DBUILD_COINBASE_ADVANCED_EXAMPLES=ON:
| Executable | Description |
|---|---|
market_data_ws_callbacks |
Single-client market data with WebsocketCallbacks (I/O thread) |
market_data_user_thread_callbacks |
Single-client market data with UserThreadWebsocketCallbacks; also queries REST endpoints |
multi_websockets_ws_callbacks |
BTC-USD + ETH-USD, one WebSocketClient each, shared mux; callbacks on I/O thread; mux and MD buffers in named shared memory |
multi_websockets_user_thread_callbacks |
BTC-USD + ETH-USD, shared mux, single processData() loop; per-symbol order books printed every 5 s |
multi_websockets_ws_callbacks_reader |
Cross-process reader — attaches to the shared memory written by multi_websockets_ws_callbacks and logs raw JSON; start the producer first |
All examples require no API credentials for public market-data channels (TICKER, LEVEL2, MARKET_TRADES).
The SDK includes comprehensive unit tests using Google Test. To run tests:
cd build
cmake -DBUILD_COINBASE_ADVANCED_TESTS=ON ..
cmake --build .
cd tests
./coinbase_advance_testsMIT License - see LICENSE file for details.
Contributions are welcome! Please submit a pull request with your changes.
For issues and questions, please open an issue on the GitHub repository.