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

# Authenticating with the Coinbase Advanced Trade API

> Learn how to generate a JWT token and authorize your Coinbase Advanced Trade API requests using the Bearer token authentication scheme.

Every request to the Coinbase Advanced Trade API must carry a valid JSON Web Token (JWT) in the `Authorization` header. The JWT is signed with your private key and encodes your API key identity, so Coinbase can verify who is making the request and what permissions they have — without transmitting your private key over the network.

The fastest way to confirm your credentials are working is to run this command:

```bash theme={null}
curl -H "Authorization: Bearer $JWT" 'https://api.coinbase.com/api/v3/brokerage/accounts'
```

The sections below walk you through creating an API key, generating a signed JWT, and constructing the header for every request.

**1. Create an API key**

Log in to your Coinbase account and navigate to **Settings → API → Create API Key**. During creation you will:

1. Choose a **key name** (used as the `sub` claim in your JWT).
2. Select the **permissions** (scopes) the key requires — see [API key scopes](#api-key-scopes) below.
3. Download or copy your **private key** (PEM format). Coinbase does not store your private key, so save it securely now.

> [!WARNING]
>
> Never embed your private key in client-side code, commit it to version control, or share it publicly. Anyone who obtains your private key can sign valid JWTs and act on your account. Store it in an environment variable, a secrets manager, or an encrypted vault.

**2. Generate a JWT**

The JWT must include the following claims and be signed using **ES256** (ECDSA with P-256 and SHA-256):

| Claim | Value |
| - | - |
| `sub` | Your API key name |
| `iss` | `coinbase-cloud` |
| `nbf` | Current Unix timestamp |
| `exp` | `nbf` + 120 seconds (tokens are short-lived) |
| `uri` | `METHOD URL` of the request, e.g. `GET api.coinbase.com/api/v3/brokerage/accounts` |

### Using the official SDK (recommended)

The easiest way to handle JWT generation is to use Coinbase's official SDK, which manages signing automatically.

```python Python theme={null}
from coinbase.rest import RESTClient

# The SDK reads your API key name and private key, signs JWTs, and injects
# the Authorization header on every request automatically.
client = RESTClient(
    api_key="organizations/{org_id}/apiKeys/{key_id}",
    api_secret="-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n"
)

accounts = client.get_accounts()
print(accounts)
```

```javascript Node.js theme={null}
import { RESTClient } from "@coinbase/coinbase-advanced-sdk";

// Pass your API key name and PEM private key. The SDK handles JWT signing.
const client = new RESTClient({
  apiKey: "organizations/{org_id}/apiKeys/{key_id}",
  apiSecret: "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n",
});

const accounts = await client.getAccounts();
console.log(accounts);
```

### Manual JWT construction

If you prefer not to use the SDK, you can sign a JWT directly using any ES256-capable JWT library.

```python Python theme={null}
import jwt
import time
from cryptography.hazmat.primitives.serialization import load_pem_private_key

API_KEY_NAME = "organizations/{org_id}/apiKeys/{key_id}"
PRIVATE_KEY_PEM = b"-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n"

def build_jwt(method: str, path: str) -> str:
    private_key = load_pem_private_key(PRIVATE_KEY_PEM, password=None)
    now = int(time.time())
    payload = {
        "sub": API_KEY_NAME,
        "iss": "coinbase-cloud",
        "nbf": now,
        "exp": now + 120,
        "uri": f"{method} api.coinbase.com{path}",
    }
    return jwt.encode(payload, private_key, algorithm="ES256")

token = build_jwt("GET", "/api/v3/brokerage/accounts")
print(token)
```

```javascript Node.js theme={null}
import jwt from "jsonwebtoken";

const API_KEY_NAME = "organizations/{org_id}/apiKeys/{key_id}";
const PRIVATE_KEY_PEM = "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n";

function buildJwt(method, path) {
  const now = Math.floor(Date.now() / 1000);
  const payload = {
    sub: API_KEY_NAME,
    iss: "coinbase-cloud",
    nbf: now,
    exp: now + 120,
    uri: `${method} api.coinbase.com${path}`,
  };
  return jwt.sign(payload, PRIVATE_KEY_PEM, { algorithm: "ES256" });
}

const token = buildJwt("GET", "/api/v3/brokerage/accounts");
console.log(token);
```

> [!NOTE]
>
> JWT tokens expire after 120 seconds. Generate a fresh token for each request, or immediately before sending a batch of requests. Long-running applications should automate token refresh rather than reusing a single token.

**3. Construct the Authorization header**

Once you have a signed JWT, pass it as a Bearer token in the `Authorization` header of every HTTP request:

```
Authorization: Bearer <JWT>
```

Use the token as `$JWT` in `curl` calls. For example, to list your accounts:

```bash theme={null}
curl -H "Authorization: Bearer $JWT" 'https://api.coinbase.com/api/v3/brokerage/accounts'
```

Replace `$JWT` with the token string you generated in the previous step. If you are using an official SDK, the library constructs and injects this header automatically.

## Authentication errors

If your JWT is missing, malformed, expired, or signed with an unrecognized key, the API returns an HTTP `401 Unauthorized` response:

```json theme={null}
{
  "error": "UNAUTHENTICATED",
  "message": "Invalid JWT: signature verification failed",
  "preview_failure_reason": "",
  "new_order_failure_reason": ""
}
```

Common causes of `401` errors:

* The JWT has expired (older than 120 seconds).
* The `uri` claim does not match the request method and path exactly.
* The private key does not correspond to the API key name in the `sub` claim.
* The key has been revoked in the Coinbase dashboard.

## API key scopes

When you create an API key you assign it one or more permission scopes. Choose the minimum scopes your application needs.

| Scope | Description |
| - | - |
| **View** | Read-only access to accounts, balances, order history, and market data. |
| **Trade** | Permission to place, edit, and cancel orders on your behalf. Requires **View**. |

> [!NOTE]
>
> Keep your API credentials safe. Rotate keys regularly, revoke keys you no longer use, and use separate keys with the narrowest possible scopes for each application or environment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.