Prime REST API Authentication
This page explains how to sign and authenticate REST API endpoints. The Prime FIX API uses its own authentication scheme detailed in FIX API Connectivity.
Generating an API Key
Certain API endpoints require authentication and request signing to access. You will need to create an API key via Coinbase Prime website to interact with these resources.
The API is currently scoped to individual portfolios.
Signing Requests
Prime REST API requests must include an access signature header.
X-CB-ACCESS-KEY
: The API key as a stringX-CB-ACCESS-PASSPHRASE
: The Passphrase shown when creating the API keyX-CB-ACCESS-SIGNATURE
: The base64-encoded signatureX-CB-ACCESS-TIMESTAMP
: A timestamp for your request
Selecting a Timestamp
The X-CB-ACCESS-TIMESTAMP
header MUST be number of seconds since Unix Epoch in UTC. Decimal values are not allowed. Make sure to use an integer.
Your timestamp must be within 30 seconds of the api service time or your request will be considered expired and rejected.
Creating a Signature
The X-CB-ACCESS-SIGNATURE
header is generated by creating a sha256 HMAC using the secret key on the prehash string timestamp + method + requestPath + body
(where +
represents string concatenation) and base64-encode the output.
timestamp
is the same as theX-CB-ACCESS-TIMESTAMP
header.method
should be UPPER CASE e.g.GET
orPOST
.requestPath
should only include the path of the API endpoint. Do NOT include the base URL or query parameters when creating the signature.Valid
requestPath
example to include in the string for hashing:/v1/portfolios/<YOUR_PORTFOLIO_ID_HERE>/open_orders
Invalid
requestPath
example:https://api.prime.coinbase.com/v1/portfolios/<YOUR_PORTFOLIO_ID_HERE>/open_orders?order_type=LIMIT
body
is the request body string or omitted if there is no request body (typically forGET
requests).
Remember to base64-encode the digest output before sending in the header.
Signature Examples
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
#request.path_url.split('?')[0] = /v1/portfolios/{portfolio_id}/orders
message = timestamp + request.method + request.path_url.split('?')[0] + str(request.body or '')
signature = hmac.new(self.secret_key.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()
signature_b64 = base64.b64encode(signature).decode()
Ruby
timestamp = Time.now.to_i
what = "#{timestamp}#{method}#{request_path}#{body}";
# create a sha256 hmac with the secret
secret = Base64.decode64(@secret)
hash = OpenSSL::HMAC.digest('sha256', secret, what)
Base64.strict_encode64(hash)
JavaScript
// Function to generate a signature using Google's crypto-js package
function sign(str, secret) {
const hash = CryptoJS.HmacSHA256(str, secret);
return hash.toString(CryptoJS.enc.Base64);
}
// Function to build the payload required to sign
function buildPayload(ts, method, requestPath, body) {
return `${ts}${method}${requestPath}${body}`;
}
// Build the string we want to sign using information defined above
const strToSign = buildPayload(Math.floor(Date.now() / 1000), "GET", "/v1/portfolios/<YOUR_PORTFOLIO_ID_HERE>/orders", "");
// Sign it!
const sig = sign(strToSign, SIGNING_KEY);