Why am I getting a 401 from Coinbase Advanced API using ES256 JWT, even with a valid JSON key and permissions?
12:07 11 Dec 2025

I’m trying to authenticate with the Coinbase Advanced API using an ES256-signed JWT, but I keep getting a 401 response from every endpoint.

I’m using a JSON API key created in the Coinbase Developer Platform (CDP), and I’ve confirmed that:

- The key has the correct permissions
- The `kid` in the JWT header matches the API key ID
- The `sub` claim matches the key name (organizations/.../apiKeys/...)
- The token is signed with ES256
- The `aud` is set to `https://api.coinbase.com`
- The `nbf` and `exp` claims are within the correct window
- The HTTP request includes the JWT in the `Authorization: Bearer ` header

I’ve also verified that I’m generating a new JWT for each request, but the response is always:

401 Unauthorized
{"error":"invalid_token"}

Here is a simplified example of how I’m generating the JWT:

Here is a simplified example of how I'm generating the JWT:

```python

import jwt
import json
import time
from pathlib import Path
from cryptography.hazmat.primitives import serialization

# Load JSON API key (Coinbase CDP key)
with open("cdp_api_key.json", "r") as f:
    key_data = json.load(f)

# Load EC private key
with open("private_key.pem", "r") as f:
    private_key = serialization.load_pem_private_key(
        f.read().encode(),
        password=None,
    )

now = int(time.time())

# JWT payload
payload = {
    "sub": key_data["name"],
    "iss": key_data["name"],
    "nbf": now,
    "exp": now + 120,
    "aud": "https://api.coinbase.com",
}

# Generate ES256-signed JWT
token = jwt.encode(
    payload,
    private_key,
    algorithm="ES256",
    headers={"kid": key_data["id"]},
)

print(token)

Even with this, the request still returns 401.


Even with this, the request still returns 401.

QUESTION:
Is there an additional requirement for Coinbase’s ES256 JWT flow (CDP JSON keys) that isn’t documented, or something subtle that I’m missing?
python json authentication jwt coinbase-api