GuidesAPI Reference
DocumentationLog In

Authorization and Authentication

Private endpoints

Private endpoints are available for order management, and account management. Every private request must be signed using the described authentication scheme.


Private endpoints require authentication using your Coinbase Exchange API key. You can generate API keys here.

Generating an API Key

Before being able to sign any requests, you must create an API key via the Coinbase Exchange website. The API key will be scoped to a specific profile. Upon creating a key you will have 3 pieces of information which you must remember:

  • Key
  • Secret
  • Passphrase

The Key and Secret will be randomly generated and provided by Coinbase Exchange; the Passphrase will be provided by you to further secure your API access. Coinbase Exchange stores the salted hash of your passphrase for verification, but cannot recover the passphrase if you forget it. Each user can generate a max of 200 API keys.

API key permissions

You can restrict the functionality of API keys. Before creating the key, you must choose what permissions you would like the key to have. The permissions are:

  • View - Allows a key read permissions. This includes all GET endpoints.
  • Transfer - Allows a key to transfer currency on behalf of an account, including deposits and withdraws. Enable with caution - API key transfers WILL BYPASS two-factor authentication.
  • Trade - Allows a key to enter orders, as well as retrieve trade data. This includes POST /orders and several GET endpoints.

Please refer to documentation below to see what API key permissions are required for a specific route.

Creating a request

All REST requests must contain the following headers:

  • CB-ACCESS-KEY The api key as a string.
  • CB-ACCESS-SIGN The base64-encoded signature (see Signing a Message).
  • CB-ACCESS-TIMESTAMP A timestamp for your request.
  • CB-ACCESS-PASSPHRASE The passphrase you specified when creating the API key.

All request bodies should have content type application/json and be valid JSON.

Signing a Message

The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC using the base64-decoded secret key on the prehash string timestamp + method + requestPath + body (where + represents string concatenation) and base64-encode the output. The timestamp value is the same as the CB-ACCESS-TIMESTAMP header.

The body is the request body string or omitted if there is no request body (typically for GET requests).

The method should be UPPER CASE.


Remember to first base64-decode the alphanumeric secret string (resulting in 64 bytes) before using it as the key for HMAC. Also, base64-encode the digest output before sending in the header.

var crypto = require('crypto');

var cb_access_timestamp = / 1000; // in ms
var cb_access_passphrase = '...';
var secret = 'PYPd1Hv4J6/7x...';
var requestPath = '/orders';
var body = JSON.stringify({
    price: '1.0',
    size: '1.0',
    side: 'buy',
    product_id: 'BTC-USD'
var method = 'POST';

// create the prehash string by concatenating required parts
var message = cb_access_timestamp + method + requestPath + body;

// decode the base64 secret
var key = Buffer(secret, 'base64');

// create a sha256 hmac with the secret
var hmac = crypto.createHmac('sha256', key);

// sign the require message with the hmac
// and finally base64 encode the result
var cb_access_sign = hmac.update(message).digest('base64');

Selecting a timestamp

The CB-ACCESS-TIMESTAMP header MUST be number of seconds since Unix Epoch in UTC. Decimal values are allowed.

Your timestamp must be within 30 seconds of the API service time or your request will be considered expired and rejected. We recommend using the time endpoint to query for the API server time if you believe there many be time skew between your server and the API servers.