> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cdp.coinbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exchange REST API Authentication

This page explains how to sign and authenticate REST API endpoints with API keys that let you control authorization.

<Info>
  See [FIX API Connectivity](/exchange/fix-api/connectivity) for FIX API authentication.
</Info>

## Private Endpoints

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

<Info>
  Private endpoints require authentication using your Coinbase Exchange API key. You can generate API keys <a href="https://exchange.coinbase.com/profile/api">here</a>.
</Info>

## API Keys

To sign a request, you must create an API key via the Coinbase Exchange website. The API key is scoped to a specific profile. Each user can generate a max of 300 API keys.

### Generating an API Key

When creating a key, you must remember (and should write down) your (1) key, (2) secret, and (3) passphrase. The key and secret are randomly generated and provided by Coinbase Exchange -- you choose a passphrase to further secure your API access.

<Warning>
  Coinbase Exchange stores the salted hash of your passphrase for verification and cannot be recovered if you forget it.
</Warning>

### API Key Permissions

You can control access by restricting the functionality of API keys. Before creating the key, you must choose what permissions you would like the key to have:

| Permission | Description                                                                            |
| :--------- | :------------------------------------------------------------------------------------- |
| View       | Key has read permissions for all endpoints (including GET)                             |
| Transfer   | Key can transfer value for accounts, including deposits/withdrawals (and bypasses 2FA) |
| Trade      | Key can post orders and get data                                                       |
| Manage     | Key can manage user settings and preferences such as address books entries             |

Refer to the documentation below to see what API key permissions are required for a specific route.

## Signing Requests

All REST requests must contain the following headers:

| Header                 | Description                                                            |
| :--------------------- | :--------------------------------------------------------------------- |
| `CB-ACCESS-KEY`        | API key as a string                                                    |
| `CB-ACCESS-SIGN`       | base64-encoded signature (see [Signing a Message](#signing-a-message)) |
| `CB-ACCESS-TIMESTAMP`  | Timestamp for your request                                             |
| `CB-ACCESS-PASSPHRASE` | Passphrase you specified when creating the API key                     |

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

### Selecting a Timestamp

The `CB-ACCESS-TIMESTAMP` header MUST be number of seconds since [Unix Epoch](http://en.wikipedia.org/wiki/Unix_time) in UTC. Decimal values are allowed.

Your timestamp must be within 30 seconds of the API service time or your request is considered expired and rejected. We recommend using the [time](https://api.exchange.coinbase.com/time) endpoint to query for the API server time if you believe there is a time difference between your server and the API servers.

### 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.

<Info>
  Remember to 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.
</Info>

* `timestamp` is the same as the `CB-ACCESS-TIMESTAMP` header.

* `method` should be UPPER CASE e.g., `GET` or `POST`.

* `requestPath` should only include the path of the API endpoint.

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

### Signature Example

The following example demonstrates how to generate a signature in Javascript:

```js lines wrap theme={null}
// import crypto library
var crypto = require("crypto");

// create the json request object
var cb_access_timestamp = Date.now() / 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.from(secret, "base64");

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

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