API Key Authentication

API Key authentication should only be used to access your own account or merchant orders. If your application requires access to other Coinbase users’ accounts, do not use API Key. To securely access other Coinbase users’ accounts, use Coinbase Connect (OAuth2)

Signing requests

API key authentication requires each request to be signed (enhanced security measure). You can create and activate new API keys in your API settings. Your API keys should be assigned to access only accounts and permission scopes that are necessary for your app to function. For more detail on which scopes are required to access corresponding endpoints and functionality, see the API reference.

Making a request

All REST requests must contain the following headers:

  • CB-ACCESS-KEY API key as a string
  • CB-ACCESS-SIGN Message signature (see below)
  • CB-ACCESS-TIMESTAMP Timestamp for your request

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

Example request:

curl https://api.coinbase.com/v2/user \
  --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>"

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

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

The method should be UPPER CASE.

The requestPath is the full path and query parameters of the URL, e.g.: /v2/exchange-rates?currency=USD.

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

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 API endpoint to query for the API server time if you believe there may be a time skew between your server and the API servers.

Here are some examples on how to build authentication in different languages:

# Requires python-requests. Install with pip:
#
#   pip install requests
#
# or, with easy-install:
#
#   easy_install requests

import json, hmac, hashlib, time, requests
from requests.auth import AuthBase

# Before implementation, set environmental variables with the names API_KEY and API_SECRET
API_KEY = 'API_KEY'
API_SECRET = 'API_SECRET'

# Create custom authentication for Coinbase API
class CoinbaseWalletAuth(AuthBase):
    def __init__(self, api_key, secret_key):
        self.api_key = api_key
        self.secret_key = secret_key

    def __call__(self, request):
        timestamp = str(int(time.time()))
        message = timestamp + request.method + request.path_url + (request.body or '')
        signature = hmac.new(self.secret_key, message, hashlib.sha256).hexdigest()

        request.headers.update({
            'CB-ACCESS-SIGN': signature,
            'CB-ACCESS-TIMESTAMP': timestamp,
            'CB-ACCESS-KEY': self.api_key,
        })
        return request

api_url = 'https://api.coinbase.com/v2/'
auth = CoinbaseWalletAuth(API_KEY, API_SECRET)

# Get current user
r = requests.get(api_url + 'user', auth=auth)
print r.json()
# {u'data': {u'username': None, u'resource': u'user', u'name': u'User'...

# Send funds
tx = {
    'type': 'send',
    'to': 'user@example.com',
    'amount': '10.0',
    'currency': 'USD',
}
r = requests.post(api_url + 'accounts/primary/transactions', json=tx, auth=auth)
print r.json()
# {u'data': {u'status': u'pending', u'amount': {u'currency': u'BTC'...
require 'openssl'
require 'json'

class CoinbaseWallet
  def initialize(key, secret)
    @key = key
    @secret = secret
  end

  def signature(request_path='', body='', timestamp=nil, method='GET')
    body = body.to_json if body.is_a?(Hash)
    timestamp = Time.now.to_i if !timestamp

    message = "#{timestamp}#{method}#{request_path}#{body}"

    # create a sha256 hmac with the secret
    hash = OpenSSL::HMAC.hexdigest('sha256', @secret, message)
  end
end
// npm install crypto
var crypto = require('crypto');
// npm install request
var request = require('request');

// Set these in your ENVironment, or enter them here with the actual string
var apiKey = '';
var apiSecret = '';


//get unix time in seconds
var timestamp = Math.floor(Date.now() / 1000);

// set the parameter for the request message
var req = {
    method: 'GET',
    path: '/v2/exchange-rates?currency=USD',
    body: ''
};

var message = timestamp + req.method + req.path + req.body;
console.log(message);

//create a hexedecimal encoded SHA256 signature of the message
var signature = crypto.createHmac("sha256", apiSecret).update(message).digest("hex");

//create the request options object
var options = {
    baseUrl: 'https://api.coinbase.com/',
    url: req.path,
    method: req.method,
    headers: {
        'CB-ACCESS-SIGN': signature,
        'CB-ACCESS-TIMESTAMP': timestamp,
        'CB-ACCESS-KEY': apiKey,
        'CB-VERSION': '2015-07-22'
    }
};

request(options,function(err, response){
    if (err) console.log(err);
    console.log(response.body);
});

Security Best Practices

Storing Credentials Securely

You should take great care to store your credentials securely. If someone obtains your api_secret with the wallet:transactions:send permission, they will be able to send all the bitcoin or ethereum out of your account.

You should avoid storing API keys in your code base (which gets added to version control). The recommended best practice is to store them in environment variables. Learn more about environment variables here. Separating credentials from your code base and database is always good practice.

API Key access is turned off by default on all accounts. To implement an API Key integration, you therefore must first enable it,and then take necessary precautions to store the API Key securely. You can always regenerate your API Key (or disable it) if you feel it has been compromised.

Validating SSL Certificates

It is also very important that your application validates our SSL certificate when it connects over https. This helps prevent a man in the middle attack. If you are using a client library, this may be turned on by default, but you should confirm this. Whenever you see ‘verify SSL’ you should always ensure it is set to true.

Additional Security for API Keys

For enhanced API Key security, we recommend that you whitelist IP addresses that are permitted to make requests with a particular API Key.

You can specify IP addresses to whitelist when creating a new API Key or editing an existing one.