Advanced Trade API Legacy Key Authentication
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).
Creating Legacy Keys
Generate an API key on Coinbase.com and copy the API key string and API secret to create a signature.
- Login and navigate to https://www.coinbase.com/settings/api.
- Select New API Key and enter you 2FA code.
- Configure the following key details:
- Accounts
- Permissions
- Notifications
- Allowlist IPs
- Securely store the values of your new API key and API secret. They will not be shown again.
Signing Requests
All Advanced Trade REST API requests with legacy API keys must contain the following headers:
| Header | Description |
|---|---|
CB-ACCESS-KEY | API key as a string (that you create on coinbase.com) |
CB-ACCESS-SIGN | Encoded signature using API secret |
CB-ACCESS-TIMESTAMP | Timestamp for your request |
Advanced Trade does not require a PASSPHRASE as did Coinbase Pro.
Creating a Signature
-
Create a signature string by concatenating the values of these query parameters with the
+operator:timestamp + method + requestPath + body.timestampis the same as theCB-ACCESS-TIMESTAMPheader (+/-30 seconds)methodshould be UPPER CASErequestPathis the full path (minus the base URL and query parameters), for example:/api/v3/brokerage/orders/historical/fills/api/v3/brokerage/products/BTC-USD/ticker
bodyis the request body string -- it is omitted if there is no request body (typically forGETrequests)
-
Create a sha256 HMAC object with your API secret on the signature string.
-
Get the hexadecimal string representation of the sha256 HMAC object and pass that in as the
CB-ACCESS-SIGNheader.
A signature must be in lowercase letters or the program throws a 401 error.
Signature Code Samples
The following examples demonstrate how to generate a signature in Python, Ruby, and JavaScript:
- Python
- Ruby
- JavaScript
import json, hmac, hashlib, time, base64
#timestamp = str(int(time.time()))
#request.method = GET or POST
#request.path_url.split('?')[0] = /api/v3/brokerage/orders/historical/batch
message = timestamp + request.method + request.path_url.split('?')[0] + str(request.body or '')
signature = hmac.new(secretKey.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()
print(signature.hex(), ts)
timestamp = Time.now.to_i
payload = "#{timestamp}#{method}#{request_path}#{body}";
# create a sha256 hmac with the secret
signature = OpenSSL::HMAC.hexdigest('sha256', secret, payload)
const CryptoJS = require('crypto-js');
function sign(str, secret) {
const hash = CryptoJS.HmacSHA256(str, secret);
return hash.toString();
}
const timestamp = Math.floor(Date.now() / 1000).toString();
const str = timestamp + req.Method + req.Path + req.Body
const sig = sign(str, apiSecret)
The Advanced Trade requestPath should only include the path of the API endpoint in the string for hashing. It should not include the base URL (protocol and domain) nor any query parameters. By contrast, the SIWC requestPath does include query parameters.
| API | requestPath | Valid Example |
|---|---|---|
| Advanced (v3) | API endpoint | /api/v3/brokerage/products/BTC-USD/ticker |
| SIWC (v2) | API endpoint + query params | /v2/exchange-rates?currency=USD |
Making Requests
All private API requests must include CB-ACCESS-* headers:
- Set a timestamp for the
CB-ACCESS-TIMESTAMPheader. - Create an encoded signature as the
CB-ACCESS-SIGNheader (with the API secret). - Set your legacy API key for the
CB-ACCESS-KEYheader. - Apply the headers to the request. You are ready to send.
Example Request
curl https://api.coinbase.com/v3/brokerage/accounts \
--header "CB-ACCESS-KEY: <your api key>" \
--header "CB-ACCESS-SIGN: <the user generated message signature>" \
--header "CB-ACCESS-TIMESTAMP: <a timestamp for your request>"
All requests should have content type application/json and the body must be valid JSON.
// Ruby code sample of a GET Request to product ticker
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://coinbase.com/api/v3/brokerage/products/BTC-USD/ticker?limit=3")
request_path= "/api/v3/brokerage/products/BTC-USD/ticker"
body = ""
method = "GET"
timestamp = Time.now.to_i
payload = "#{timestamp}#{method}#{request_path}#{body}"
# create a sha256 hmac with the secret
signature = OpenSSL::HMAC.hexdigest('sha256', $SECRET_KEY, payload)
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["accept"] = 'application/json'
request["CB-ACCESS-KEY"] = $ACCESS_KEY
request["CB-ACCESS-SIGN"] = signature
request["CB-ACCESS-TIMESTAMP"] = timestamp
response = http.request(request)
puts response.read_body