Sending WebSocket Messages with Legacy Keys
Legacy API key authentication is supported but optional for both Advanced Trade and Sign in with Coinbase APIs. Coinbase recommends that you generate keys on the Coinbase Developer Platform (CDP).
Legacy API keys are for individuals or applications for individual use. They can be used with Advanced REST APIs & WebSocket channels (except new features).
Subscribing
// Request
// Subscribe to ETH-USD and ETH-EUR with the level2 channel
{
"type": "subscribe",
"product_ids": ["ETH-USD", "ETH-EUR"],
"channel": "level2",
"api_key": "exampleApiKey123",
"timestamp": "1660838876",
"signature": "00000000000000000000000000"
}
To subscribe to any channel, users must provide a channel
name, api_key
, timestamp
, and signature
:
-
channel
name as a string. You can only subscribe to one channel per subscription message. -
timestamp
should be a string in UNIX format. Example:"1677527973"
. -
signature
should be created by:-
Concatenating and comma-separating the timestamp, channel name, and product Ids, for example:
1660838876level2ETH-USD,ETH-EUR
. -
Hashing this phrase with your secret key:
CryptoJS.HmacSHA256(str, secret).toString()
.
-
Unsubscribing
// Request
{
"type": "unsubscribe",
"product_ids": ["ETH-USD", "ETH-EUR"],
"channel": "level2",
"api_key": "exampleApiKey123",
"timestamp": "1660839876",
"signature": "00000000000000000000000000"
}
You receive a subscriptions
message as a response to an unsubscribe
message.
JS Code Sample
This JavaScript example is for subscribing to one Advanced Trade WebSocket channel using legacy API keys.
// JS Example for subscribing to a channel
/* eslint-disable */
const WebSocket = require("ws");
const CryptoJS = require("crypto-js");
const fs = require("fs");
// Derived from your Coinbase Retail API Key
// SIGNING_KEY: the signing key provided as a part of your API key. Also called the "SECRET KEY"
// API_KEY: the api key provided as a part of your API key. also called the "PUBLIC KEY"
const SIGNING_KEY = "";
const API_KEY = "";
if (!SIGNING_KEY.length || !API_KEY.length) {
throw new Error("missing mandatory environment variable(s)");
}
const CHANNEL_NAMES = {
level2: "level2",
user: "user",
tickers: "ticker",
ticker_batch: "ticker_batch",
status: "status",
market_trades: "market_trades",
candles: "candles",
};
// The base URL of the API
const WS_API_URL = "wss://advanced-trade-ws.coinbase.com";
// Function to generate a signature using CryptoJS
function sign(str, secret) {
const hash = CryptoJS.HmacSHA256(str, secret);
return hash.toString();
}
function timestampAndSign(message, channel, products = []) {
const timestamp = Math.floor(Date.now() / 1000).toString();
const strToSign = `${timestamp}${channel}${products.join(",")}`;
const sig = sign(strToSign, SIGNING_KEY);
return { ...message, signature: sig, timestamp: timestamp };
}
const ws = new WebSocket(WS_API_URL);
function subscribeToProducts(products, channelName, ws) {
const message = {
type: "subscribe",
channel: channelName,
api_key: API_KEY,
product_ids: products,
};
const subscribeMsg = timestampAndSign(message, channelName, products);
ws.send(JSON.stringify(subscribeMsg));
}
function unsubscribeToProducts(products, channelName, ws) {
const message = {
type: "unsubscribe",
channel: channelName,
api_key: API_KEY,
product_ids: products,
};
const subscribeMsg = timestampAndSign(message, channelName, products);
ws.send(JSON.stringify(subscribeMsg));
}
function onMessage(data) {
const parsedData = JSON.parse(data);
fs.appendFile("Output1.txt", data, (err) => {
// In case of a error throw err.
if (err) throw err;
});
}
const connections = [];
let sentUnsub = false;
for (let i = 0; i < 1; i++) {
const date1 = new Date(new Date().toUTCString());
const ws = new WebSocket(WS_API_URL);
ws.on("message", function (data) {
const date2 = new Date(new Date().toUTCString());
const diffTime = Math.abs(date2 - date1);
if (diffTime > 5000 && !sentUnsub) {
unsubscribeToProducts(["BTC-USD"], CHANNEL_NAMES.user, ws);
sentUnsub = true;
}
const parsedData = JSON.parse(data);
fs.appendFile("Output1.txt", data, (err) => {
// In case of a error throw err.
if (err) throw err;
});
});
ws.on("open", function () {
const products = ["BTC-USD"];
subscribeToProducts(products, CHANNEL_NAMES.user, ws);
});
connections.push(ws);
}