> ## Documentation Index
> Fetch the complete documentation index at: https://developer.copper.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

Authentication to the API is performed via the Authorization header with an API key. Each request requires an API key to authenticate the user and a signature to verify the request’s integrity, ensuring safe and authorized access to our API. To provide access to the API, all requests must contain the following headers:

| Header          | Description                                                          |
| :-------------- | :------------------------------------------------------------------- |
| `Authorization` | API key obtained on the Copper Platform                              |
| `X-Signature`   | Signature of your request                                            |
| `X-Timestamp`   | Timestamp of your request in UNIX Timestamp format (in milliseconds) |

For information on creating an API key, see [Create an API key](/api-reference/create-api-key).

### Generating a signature

<Steps>
  <Step title="Concatenate the following strings:">
    * Value of the `X-Timestamp` header
    * HTTP request method uppercase
    * Path of the requested endpoint including the `platform` prefix and all additional parameters (e.g., `/platform/orders?limit=1000`)
    * All fields of the request body (use an empty string if the request does not include a body)

    `"$timestamp${req.method.value.toUpperCase}${req.uri}${body.data.utf8}"`

    For example:
    `1730482675607POST/platform/orders{"orderType":"withdraw","amount":"1.0"}`
  </Step>

  <Step title="Sign the concatenated string with your API Secret using the HMAC SHA256 method." />

  <Step title="Encode the generated signature in hexadecimal format." />
</Steps>

<CodeGroup>
  ```bash Bash theme={"system"}
  #!/bin/bash -ex
  API_KEY='ksgJrNOT1...i02V1hLfZs1I'
  SECRET='W02cN5UDsF...SJtTyjDtq5SN'

  TIMESTAMP="$(($(date +%s) * 1000))"
  METHOD="GET"
  URL_PATH="/platform/portfolios"
  BODY=""

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

  curl -v "https://api.copper.co${URL_PATH}" \
  -H "Authorization: ApiKey ${API_KEY}" \
  -H "Content-Type: application/json" \
  -H "X-Signature: ${SIGNATURE#*= }" \
  -H "X-Timestamp: ${TIMESTAMP}"
  ```

  ```python Python theme={"system"}
  import hashlib
  import hmac
  import requests
  import time

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

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

  signature = hmac.new(
      key=bytes(Secret, 'utf-8'),
      msg=bytes(timestamp + method + path + body, 'utf-8'),
      digestmod=hashlib.sha256
  ).hexdigest()

  print(signature) # example: 1b6064ca0d052d1a08d831c915ead54e6c5ff17237c845dab8b8c1cb8439a9c1

  url = 'https://api.copper.co' + path

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

  ```java Java theme={"system"}
  import javax.crypto.Mac;
  import javax.crypto.spec.SecretKeySpec;
  import java.nio.charset.StandardCharsets;
  import java.util.HexFormat;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.io.OutputStream;

  public class CopperApiExample {
      public static void main(String[] args) throws Exception {
          String apiKey = "ksgJrNOT1X...i02V1hLfZs1I";
          String secret = "W02cN5UDsF...SJtTyjDtq5SN";
          long timestamp = System.currentTimeMillis();
          String method = "GET";
          String path = "/platform/portfolios";
          String body = "";

          String message = timestamp + method + path + body;
          Mac sha256Hmac = Mac.getInstance("HmacSHA256");
          SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
          sha256Hmac.init(secretKey);
          String signature = HexFormat.of().formatHex(sha256Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8)));

          URL url = new URL("https://api.copper.co" + path);
          HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          connection.setRequestMethod(method);
          connection.setRequestProperty("Authorization", "ApiKey " + apiKey);
          connection.setRequestProperty("X-Signature", signature);
          connection.setRequestProperty("X-Timestamp", String.valueOf(timestamp));
          connection.setRequestProperty("Content-Type", "application/json");

          int responseCode = connection.getResponseCode();
          System.out.println("Response Code: " + responseCode);
      }
  }
  ```

  ```scala Scala theme={"system"}
  import javax.crypto.Mac
  import javax.crypto.spec.SecretKeySpec
  import java.nio.charset.StandardCharsets
  import java.util.HexFormat;
  import scalaj.http._

  object CopperApiExample extends App {
      val apiKey = "ksgJrNOT1X...i02V1hLfZs1I"
      val secret = "W02cN5UDsF...SJtTyjDtq5SN"
      val timestamp = System.currentTimeMillis().toString
      val method = "GET"
      val path = "/platform/portfolios"
      val body = ""

      val message = timestamp + method + path + body
      val sha256Hmac = Mac.getInstance("HmacSHA256")
      val secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256")
      sha256Hmac.init(secretKey)
      val signature = HexFormat.of().formatHex(sha256Hmac.doFinal(message.getBytes(StandardCharsets.UTF_8)))

      val response = Http("https://api.copper.co" + path)
          .header("Authorization", "ApiKey " + apiKey)
          .header("X-Signature", signature)
          .header("X-Timestamp", timestamp)
          .asString

      println("Response Code: " + response.code)
  }
  ```

  ```go Go theme={"system"}
  package main

  import (
      "crypto/hmac"
      "crypto/sha256"
      "encoding/hex"
      "fmt"
      "net/http"
      "strconv"
      "time"
  )

  func main() {
      apiKey := "ksgJrNOT1X...i02V1hLfZs1I"
      secret := "W02cN5UDsF...SJtTyjDtq5SN"
      timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10)
      method := "GET"
      path := "/platform/portfolios"
      body := ""

      message := timestamp + method + path + body
      mac := hmac.New(sha256.New, []byte(secret))
      mac.Write([]byte(message))
      signature := hex.EncodeToString(mac.Sum(nil))

      client := &http.Client{}
      req, _ := http.NewRequest(method, "https://api.copper.co"+path, nil)
      req.Header.Add("Authorization", "ApiKey "+apiKey)
      req.Header.Add("X-Signature", signature)
      req.Header.Add("X-Timestamp", timestamp)
      req.Header.Add("Content-Type", "application/json")

      resp, _ := client.Do(req)
      fmt.Println("Response Code:", resp.StatusCode)
  }
  ```
</CodeGroup>
