Authenticating Messages
To send requests to the Advanced Trade API, you must sign and authenticate each endpoint with an API key. This page explains how.
You can use the same API Key authentication scheme for both the Advanced Trade API (v3) and Sign In API (v2) although you will need different scopes.
Signing Requests
All Advanced Trade REST API requests must contain the following headers:
CB-ACCESS-KEY: The API key as a string (that you create on coinbase.com)CB-ACCESS-TIMESTAMP: A timestamp for your requestCB-ACCESS-SIGN: The encoded signature
For example:
--header "CB-ACCESS-KEY: Sd55555555555tP3"
--header "CB-ACCESS-SIGN: 35f238402bb2400aeb0a048dab64d6cd82d99590da255bd9afe1c1f37fd1686d"
--header "CB-ACCESS-TIMESTAMP: 1667500462"
To create a signed request, you must:
- Generate an API key at
coinbase.com/settings/apiand copy the API key string for theCB-ACCESS-KEYand the API secret to create the signature. - Set a timestamp for the
CB-ACCESS-TIMESTAMPheader. - Create an encoded signature as the
CB-ACCESS-SIGNheader (with the API secret). - Apply the headers to the request. You are ready to send.
Step 1: Generate API Key
To start, create an API key at coinbase.com/settings/api. API keys do not expire.
Copy the API key string and API secret. Apply the API key to the CB-ACCESS-KEY header. Keep the API secret to create the signature below.
An Advanced Trade API key is scoped to an account, not a profile (or portfolio). See API Scopes for a workaround.
Step 2: Set Timestamp
The CB-ACCESS-TIMESTAMP header MUST be a UNIX timestamp and it must be the same timestamp used to create the request signature, +/-30 seconds. Decimal values are not allowed. Make sure to use an integer.
Step 3: Create Signature
The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC object using the API secret key on the string timestamp + method + requestPath + body.
Create a signature string by concatenating the values of these query parameters:
timestamp + method + requestPath + body.Concatenate the values of the following parameters with the
+operator: these query parameters: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.
See SigGen Code Samples below.
Request Path
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 Sign In requestPath does include query parameters.
| API | requestPath | Valid Example |
|---|---|---|
| Advanced Trade (v3) | API endpoint | /api/v3/brokerage/products/BTC-USD/ticker |
| Sign In (v2) | API endpoint + query params | /v2/exchange-rates?currency=USD |
/api/v3/brokerage/products/BTC-USD/ticker https://coinbase.com/api/v3/brokerage/products/BTC-USD/ticker?limit=3// Ruby code sample of a GET Request Signature Flow
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
SigGen Code Samples
The following examples demonstrate how to generate a signature in Python, Ruby, and JavaScript:
Python
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)
Ruby
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)
JavaScript
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)
See Also:
Was this helpful?