Integrating Coinbase Advanced Trade API with Node.js: A 2026 Engineering Guide
A 2026 guide to the Coinbase Advanced Trade API Node.js integration. Learn to simplify auth, JWT signing, and awaitable WebSocket patterns with a typed SDK.
Overview
Most teams underestimate the overhead of a handmade Coinbase Advanced Trade integration until a production WebSocket goes quiet during a volatile session. CDP keys need JWT signing on every request. Market data and user fills arrive on two different sockets. Order entry is still REST.
You start with one public GET, then you are writing JWT claims, tracking nonces, and wiring event listeners. That is busywork. It is not your trading logic.
This guide shows how to use the Coinbase Advanced Trade API from Node.js with the coinbase-api package. That SDK is the REST and WebSocket client for Advanced Trade (plus App, Exchange, International, Prime, and Commerce). You get typed clients, automatic JWT signing, heartbeats, and reconnect-then-resubscribe. You still own rate limiting.
We will go from client setup to public market data, authenticated orders, and live WebSocket streams.
Key Takeaways
- Advanced Trade auth is Coinbase Developer Platform (CDP) keys. The SDK signs JWTs with ES256 (ECDSA) or EdDSA (Ed25519) and detects the key type for you.
- Use
CBAdvancedTradeClientfor REST. Public calls work with an empty constructor. Private calls takeapiKey(key name) andapiSecret(private key). - Place and cancel orders over REST (
submitOrder,cancelOrders). Current Advanced Trade WebSockets do not take order-entry commands. - Use
WebsocketClientfor public market data (advTradeMarketData) and private user/futures streams (advTradeUserData). The SDK keeps the socket alive, reconnects, and resubscribes. - Coinbase rate limits are on you. REST is 600 reads and 500 writes per rolling 10-second window. Unauthenticated WebSocket messages are 8 per second per IP.
What is the Coinbase Advanced Trade API for Node.js?
The Coinbase Advanced Trade API is the v3 brokerage interface for spot and US derivatives on Coinbase. Node.js fits this well: non-blocking I/O, one process can sit on REST and two WebSocket feeds without extra thread machinery.
As of August 2026, Coinbase is splitting that surface. Spot and US futures stay on the current brokerage v3 REST API and the existing Advanced Trade WebSocket hosts. That gateway is a different protocol. coinbase-api today wraps current Advanced Trade REST and WebSockets (CBAdvancedTradeClient, WebsocketClient). It also has CBInternationalClient for current INTX REST. It does not wrap the new drb.coinbase.com JSON-RPC API yet. Plan that cutover as its own work.
The npm package is still the right Node.js layer for everything that is live now: Advanced Trade, Coinbase App, Exchange, International, Prime, and Commerce.
Key Interfaces: REST vs. WebSocket
Two channels, different jobs.
REST is the source of truth for accounts, orders, candles, and anything you need a request/response for. Coinbase CDP REST limits are a rolling 10-second window: 600 reads (GET) and 500 writes (POST, PUT, DELETE). Hit the wall and you get 429.
WebSockets are for live data. Public market data lives on wss://advanced-trade-ws.coinbase.com. Private user data lives on wss://advanced-trade-ws-user.coinbase.com. Typical setup: WebSockets for the book, trades, and your fills. REST for placing orders and for periodic reconciliation.
That split is not a style choice. Current Advanced Trade does not offer a trading WebSocket API. You cannot await an order ack on the Advanced Trade socket the way you can on Binance, Bybit, or OKX.
Why Developers Avoid Raw API Integrations
Raw CDP auth is JWT, not HMAC. You build a token per request with issuer cdp, a uri claim, nbf/exp, and a unique nonce. Keys are either ECDSA (PEM, ES256) or Ed25519 (base64, EdDSA). Clock skew on nbf/exp is a common 401.
Other recurring pain:
- Connection health: the socket can look open while the server has stopped sending. You need ping/pong and a teardown if pong never comes.
- Resubscribe: after a drop you must subscribe again, or you sit on a live socket with no data.
- Book state:
level2starts with a snapshot, then deltas. After a disconnect, throw the local book away and wait for a new snapshot.
coinbase-api signs JWTs, opens the right host per feed, heartbeats, reconnects, and resubscribes. It does not throttle you. Stay inside Coinbase's 10-second REST windows and the unauthenticated WebSocket cap of 8 messages per second yourself.
Securing Coinbase API Authentication with CDP Keys
Legacy Advanced Trade keys (key, secret, passphrase) are gone. CDP keys are a key name plus a private key. Every REST call and private WebSocket subscribe carries a JWT.
The SDK uses the jose library, sets iss: 'cdp', sub to your key name, a short expiry (default 120 seconds), and a nanoid nonce. Pass the key name as apiKey and the private key as apiSecret. ECDSA keys keep the full PEM block, including the BEGIN/END lines. Ed25519 keys are the base64 secret Coinbase gives you. The client detects both.
You can also pass the JSON object Coinbase lets you download as cdpApiKey. Same result.
Imported example
const { CBAdvancedTradeClient } = require("coinbase-api");
// import { CBAdvancedTradeClient } from 'coinbase-api';
const client = new CBAdvancedTradeClient({
apiKey: process.env.API_KEY_NAME,
apiSecret: process.env.API_PRIVATE_KEY,
});
The SDK does not rate-limit. It only signs and sends.
Managing Secrets and API Keys Safely
Do not put the private key in source. Use env vars or a secret manager. In CDP, drop withdrawal permission on automation keys. Add IP allowlisting so a leaked key is useless off your network. For rotation, run two keys for a short overlap, then retire the old one.
Handling Timestamps and Nonces
JWT nbf and exp come from the local clock. If that clock is wrong, Coinbase rejects the token. Keep NTP honest. The SDK does not sync time for you. It does mint a fresh nonce per JWT, which blocks replay.
If you want a latency/skew check, CBAdvancedTradeClient has fetchLatencySummary(). That is a diagnostic helper, not something you need on every request.
For a longer walkthrough of client setup, use the coinbase-api tutorial.
Using WebSockets for Market Data and Account Updates
Current Advanced Trade WebSockets are streams, not a command API. You subscribe to channels. The server pushes events. Confirmations for orders you placed on REST show up on the user channel. They are not a reply to a WebSocket "place order" call, because that call does not exist here.
That is different from other Siebly SDKs (Binance, Bybit, OKX, and others) that wrap a real WebSocket API with WebsocketAPIClient and let you await an order. Coinbase Advanced Trade does not have that surface, so coinbase-api does not ship that client.
Use REST for submitOrder. Use WebsocketClient for the book, tickers, trades, and your order updates.
Public feeds need no keys:
Imported example
const { WebsocketClient } = require("coinbase-api");
// import { WebsocketClient } from 'coinbase-api';
const client = new WebsocketClient();
client.on("update", (data) => {
console.info(new Date(), "data received:", JSON.stringify(data));
});
client.on("exception", (data) => {
console.error("exception:", data);
});
client.subscribe(
{
topic: "ticker",
payload: {
product_ids: ["ETH-USD", "BTC-USD"],
},
},
"advTradeMarketData",
);
client.subscribe(
[
{ topic: "heartbeats" },
{
topic: "level2",
payload: { product_ids: ["ETH-USD", "BTC-USD"] },
},
{
topic: "market_trades",
payload: { product_ids: ["ETH-USD", "BTC-USD"] },
},
],
"advTradeMarketData",
);
The second argument is the WS key. advTradeMarketData is the public Advanced Trade feed. advTradeUserData is the private one. The client opens and tracks those connections for you.
Event-Driven vs. Request/Response
WebsocketClient is event-driven: open, update, response, reconnect, reconnected, close, exception. Filter update events by channel and product. Do not build a fake request/response mapper on top and call it an "awaitable WebSocket order API". That is not how this exchange works today.
International derivatives after September 9, 2026 are a different story. The Deribit-powered gateway speaks JSON-RPC over WebSocket and does support order entry (private/buy, private/sell, and similar). That is a new host and a new protocol. Spot and US futures stay on the REST-plus-streams model above.
Monitoring Private Account Streams
Subscribe to user for order and fill updates, and futures_balance_summary if you trade Coinbase futures. Subscribes on advTradeUserData are signed automatically when you pass CDP credentials.
Imported example
const { WebsocketClient } = require("coinbase-api");
const client = new WebsocketClient({
apiKey: process.env.API_KEY_NAME,
apiSecret: process.env.API_PRIVATE_KEY,
});
client.on("update", (data) => {
console.info(new Date(), "user data:", JSON.stringify(data));
});
client.subscribe("user", "advTradeUserData");
client.subscribe("futures_balance_summary", "advTradeUserData");
client.subscribe("heartbeats", "advTradeUserData");
Push those events into your local order state. Ignore public noise you did not ask for.
Unauthenticated WebSocket messages are limited to 8 per second per IP. Connection attempts are limited too. Authenticate when you can. Throttle subscribe/unsubscribe bursts in your own code.
Engineering for Reliability: Reconnections and State
You do not need to write a reconnect loop from scratch. WebsocketClient sends pings (default every 10 seconds), waits for pong (default 1 second), and if pong never arrives it tears the socket down. On drop it waits reconnectTimeout (default 500 ms) and reconnects. After a successful reconnect it emits reconnected and resubscribes to the topics it stored for that WS key.
That delay is a fixed timer, not exponential backoff. If you want a longer pause, pass reconnectTimeout when you construct the client. Do not hammer Coinbase with your own extra retry storm on top of the SDK's.
The SDK still does not rate-limit REST or WebSocket subscribe traffic. That stays in your app.
WebSocket Stability Best Practices
You do not need to re-send subscribe payloads after a drop. The client already does that.
You do need to treat local book state as dirty. level2 is snapshot then incremental updates. After reconnect / reconnected, wipe the in-memory book and rebuild from the next snapshot. Trading on a half-applied book is how you get nonsense prices.
Listen to exception and close. An unexpected close should be followed by reconnect then reconnected. If it is not, you have a bug or a ban, not a flap.
Managing Exchange API Rate Limits
CDP REST: 600 GET requests and 500 writes per rolling 10-second window, per the Coinbase rate-limit docs. Persistent 429s can get your IP in trouble.
Build a queue or a token bucket in your process. The SDK will not. Watch for 429 and back off. For the plumbing of signed requests and sockets, read the coinbase-api docs.
Quickstart: Building Your First Integration with coinbase-api
Install the package, call a public endpoint, then add keys and place a test-size order. Advanced Trade has no sandbox (useSandbox exists for Exchange and International, not for Advanced Trade). Start with public REST, then tiny sizes on live keys you trust.
Step-by-Step Installation and Setup
Install:
Imported example
npm install coinbase-api
Public REST, no keys:
Imported example
const { CBAdvancedTradeClient } = require("coinbase-api");
// import { CBAdvancedTradeClient } from 'coinbase-api';
const client = new CBAdvancedTradeClient({});
async function publicCalls() {
const serverTime = await client.getServerTime();
console.log("Server Time:", serverTime);
const publicProduct = await client.getPublicProduct({
product_id: "BTC-USD",
});
console.log("Public Product:", publicProduct);
const productBook = await client.getPublicProductBook({
product_id: "BTC-USD",
limit: 10,
});
console.log("Public Product Book:", productBook);
}
publicCalls();
getPublicProduct is product metadata. getPublicMarketTrades hits /api/v3/brokerage/market/products/{product_id}/ticker if you want recent trades and best bid/ask without auth. Authenticated getBestBidAsk is the private sibling.
The package is TypeScript. Types cover most request and response shapes. Not every field on every endpoint is fully typed. Treat "most" as the honest description.
Transitioning to Production Architecture
Put CDP credentials in the environment. Use client.generateNewOrderId() for client_order_id (the SDK prefixes IDs so Coinbase accepts them).
Imported example
const { CBAdvancedTradeClient } = require("coinbase-api");
const client = new CBAdvancedTradeClient({
apiKey: process.env.API_KEY_NAME,
apiSecret: process.env.API_PRIVATE_KEY,
});
async function submitOrders() {
const marketSell = await client.submitOrder({
product_id: "BTC-USDT",
side: "SELL",
client_order_id: client.generateNewOrderId(),
order_configuration: {
market_market_ioc: { base_size: "0.001" },
},
});
console.log("Market order:", marketSell);
const limitBuy = await client.submitOrder({
product_id: "BTC-USDT",
side: "BUY",
client_order_id: client.generateNewOrderId(),
order_configuration: {
limit_limit_gtc: {
base_size: "0.001",
limit_price: "50000.00",
},
},
});
console.log("Limit order:", limitBuy);
}
submitOrders();
That is REST. Pair it with the user WebSocket so fills show up without polling.
Rate limits stay in your application. There is no Advanced Trade testnet. previewOrder is useful before you send live size. For Exchange or INTX you can set useSandbox: true on those clients. Not on CBAdvancedTradeClient.
For a wider view of process layout, see Algorithmic Trading System Architecture.
Scaling Your Coinbase Integration for 2026
Get CDP keys working. Put orders on REST. Put market data and fills on WebsocketClient. Let the SDK sign JWTs, heartbeat, reconnect, and resubscribe. You handle throttling and local book reset.
September 9, 2026 is a hard cutover for international derivatives only. Spot and US futures stay on the clients and URLs in this article. INTX traffic moves to JSON-RPC on drb.coinbase.com. Do not assume coinbase-api will hide that protocol change for you on day one. Track Coinbase's migration guide and the SDK changelog.
Start building with the Siebly Coinbase SDK. Use public endpoints first, then least-privilege keys, then live size.
Frequently Asked Questions
Is the Coinbase Advanced Trade API free to use for developers?
Yes. Coinbase does not charge for API access. You pay trading fees on fills. Advanced Trade is maker-taker, based on trailing 30-day USD volume. Coinbase's own Advanced overview lists fees at or below 0.40% maker and 0.60% taker, with exact tiers in your account. Those numbers change. Check the fee page in Coinbase, not a blog.
How do I handle Coinbase API rate limits in a Node.js application?
In your code. Siebly SDKs do not throttle. CDP REST is 600 reads and 500 writes per rolling 10-second window. WebSocket unauthenticated messages are 8 per second per IP. Queue requests, backoff on 429, and do not retry in a tight loop.
What is the difference between Coinbase Pro and Advanced Trade APIs?
Coinbase Pro is gone. Advanced Trade is the v3 brokerage API. Auth is CDP JWT (ES256 or EdDSA), not the old key/secret/passphrase trio. Passphrase auth still exists on Exchange, International, and Prime via CBExchangeClient, CBInternationalClient, and CBPrimeClient. Those are different products in the same npm package.
Can I use WebSockets to place orders on Coinbase Advanced Trade?
Not on the current Advanced Trade sockets. Place orders with CBAdvancedTradeClient.submitOrder(). Subscribe to user on advTradeUserData to hear about those orders. WebSocket order entry is part of the Deribit-powered international derivatives gateway that goes live September 9, 2026. That is JSON-RPC on wss://drb.coinbase.com/ws/api/v2, not WebsocketClient as it exists today. Spot and US futures stay REST-for-orders.
Does the Siebly coinbase-api SDK support TypeScript out of the box?
Yes. The package is written in TypeScript and ships declarations. Most request and response shapes are typed. That is stronger than raw fetch, not a guarantee that every nested field is modeled.
How do I securely store my Coinbase CDP API keys in Node.js?
Environment variables or a secret manager. Never commit the private key. Disable withdrawals on automation keys. IP allowlist in CDP.
What happens to international derivatives on the Advanced Trade API in late 2026?
On September 9, 2026 Coinbase cuts international derivatives over to a Deribit-powered gateway (Starbase matching engine). Protocol becomes JSON-RPC 2.0 over HTTP and WebSocket. Open INTX orders are cancelled during the window. Spot and US futures keep the current Advanced Trade REST and WebSocket APIs. coinbase-api covers those current APIs and current INTX REST. The new drb.coinbase.com gateway is a separate integration until the SDK adds it. Official Coinbase docs remain the source of truth for cutover details.
Disclaimer
*Technical and legal disclaimer: Siebly.io provides software development tools, SDKs, documentation, and educational engineering content for crypto exchange API integrations. This content is for software engineering education only and is not financial, investment, legal, tax, accounting, compliance, or trading advice.
Nothing in this article is a recommendation, invitation, or inducement to buy, sell, hold, trade, long, short, or allocate to any cryptoasset, exchange product, strategy, bot, or automated workflow. Examples, code patterns, simulations, backtests, and architecture diagrams are illustrative only and must not be treated as trading signals, investment recommendations, or evidence of future performance.
Cryptoasset markets are high risk and volatile. If you choose to build or operate exchange-connected software, you are responsible for your own legal, regulatory, tax, security, exchange-account, API-key, and risk-management obligations. Use public data, testnet, demo, dry-run, or paper-trading workflows before any live execution. Keep API keys server-side, use least-privilege permissions, and never enable withdrawals for automation keys unless you fully understand and accept the risks.
Siebly.io is not an exchange, custodian, investment adviser, trading-signal provider, or managed trading service. Official exchange documentation remains the source of truth for exchange-specific rules, API behavior, and terms of use. Use of Siebly.io content and software is also subject to the Siebly.io terms and conditions.*
Related articles
Continue from here