Skip to main content

Advanced Trade REST API Authentication

This page explains how to authenticate each endpoint with an API key.

All Advanced Trade API v3 endpoints require authentication

The Advanced Trade REST API comprises all v3 endpoints. It does not duplicate the Sign In With Coinbase v2 endpoints for core Coinbase functions (some of which need authentication as well).

To send requests to the Advanced Trade API, you must sign and authenticate each v3 endpoint. You can do so with with an API Key or with OAuth2.

OAuth2

For help with OAuth2, refer to the Sign In documentation on OAuth2.

Signing Requests

tip

You can use the same API Key authentication scheme for both the Advanced Trade API (v3) and Sign In API (v2) although you need different scopes.

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 request
  • CB-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:

  1. Generate an API key at coinbase.com/settings/api and copy the API key string for the CB-ACCESS-KEY and the API secret to create the signature.
  2. Set a timestamp for the CB-ACCESS-TIMESTAMP header.
  3. Create an encoded signature as the CB-ACCESS-SIGN header (with the API secret).
  4. 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.

caution

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.

  1. 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.

    • timestamp is the same as the CB-ACCESS-TIMESTAMP header (+/-30 seconds)
    • method should be UPPER CASE
    • requestPath is 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
    • body is the request body string -- it is omitted if there is no request body (typically for GET requests)
  2. Create a sha256 HMAC object with your API secret on the signature string.

  3. Get the hexadecimal string representation of the sha256 HMAC object and pass that in as the CB-ACCESS-SIGN header.

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.

APIrequestPathValid 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
Advanced Trade requestPath Examples
Valid Valid: /api/v3/brokerage/products/BTC-USD/ticker
Invalid Invalid: 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?