This section explains the authentication details:

Generating an API Key

Before being able to sign any requests, you must create an API key on Copper. Upon creating a key you will have 2 pieces of information which you must remember:

  • API Key
  • API Secret

The API Key and Secret will be randomly generated and provided by Copper.

Making Requests

Authorization strategies are implemented through Authorization header, which is similar to Basic authorization. Essential strategy is ApiKey (token-based) and most secure resources require ApiKey authorization to be used.

All REST requests must contain the following headers:

  • Authorization - To access secured resource include header Authorization in request with your API key in following format:
    Authorization: ApiKey 6a7eef41b0e160b27eb***********6af970fa77e45a8e20581e4ffd8
  • X-Timestamp - The timestamp of your request (in milliseconds).

  • X-Signature - Signature of a query (see Signing Messages subsection for details).

Signing Messages

The X-Signature header is generated as follows:

  • Create a prehash string of X-Timestamp + HTTP Request Method (Uppercase) + requestPath + body of query (empty string if body is empty) where + represents String concatenation
  • Prepare the API Secret
  • Sign the prehash string with the API Secret using the HMAC SHA256
  • Encode the signature in the hex format

The timestamp value is the same as the X-Timestamp header.

The request method should be UPPER CASE, i.e. GET and POST.

The requestPath is the path of requesting an endpoint with query params.

Example: /platform/orders?limit=1000

The body refers to the String of the request body. It can be omitted if there is no request body (frequently the case for GET requests).

Example: {"externalOrderId": "F7FCCFD3-B61B-4467-B456-B0FC27CE4494", "orderType": "buy", "baseCurrency": "BTC", "quoteCurrency": "USD", "amount": "5"}

The API Secret is generated when you create an API Key.


Bash example:



TIMESTAMP="$(($(date +%s) * 1000))" # current time in millis

SIGNATURE="$(echo -n "${TIMESTAMP}${METHOD}${URL_PATH}${BODY}" | openssl dgst -sha256 -hmac ${SECRET})"

curl -v "${URL_PATH}" \
  -H "Authorization: ApiKey ${API_KEY}" \
  -H "X-Signature: ${SIGNATURE}" \
  -H "X-Timestamp: ${TIMESTAMP}"

Python example:


import hashlib
import hmac
import requests
import time

ApiKey = 'ksgJrNOT1X...i02V1hLfZs1I'
Secret = 'W02cN5UDsF...SJtTyjDtq5SN'

timestamp = str(round(time.time() * 1000))
method = "GET"
path = "/platform/accounts"
body = ""

signature =
    key=bytes(Secret, 'utf-8'),
    msg=bytes(timestamp + method + path + body, 'utf-8'),

print(signature)  # example: 1b6064ca0d052d1a08d831c915ead54e6c5ff17237c845dab8b8c1cb8439a9c1

url = '' + path

resp = requests.get(url, headers={
    'Authorization': 'ApiKey ' + ApiKey,
    'X-Signature': signature,
    'X-Timestamp': timestamp


JavaScript (NodeJs) example:


const crypto = require('crypto');
const https = require('https');

const ApiKey = 'ksgJrNOT1...02V1hLfZs1I';
const Secret = 'W02cN5UDs...tTyjDtq5SN';

const timestamp = new Date().getTime();
const method = 'GET';
const path = '/platform/accounts';
const body = '';

const signature = crypto.createHmac('SHA256', Secret)
  .update(timestamp + method + path + body)

console.log(signature); // example: b5579b7c4cb4d2c8ce19f00676219255dd988a2106929520f443c340fee867bf

const url = '' + path;

https.get(url, {
  headers: {
    Authorization: `ApiKey ${ApiKey}`,
    'X-Signature': signature,
    'X-Timestamp': timestamp,
}, (res) => {

  res.on('data', (body) => {