Introduction

Coinbase Developer Platform (CDP) uses three distinct types of authentication keys, each serving a specific purpose:

Server requests:

These keys should be stored securely, and used only by trusted back-end services:

  • Secret API Key: For all server-to-server communication (i.e., REST APIs).
  • Wallet Secret: Additional requirement for any server-to-server communication that involves sensitive wallet operations (i.e., signing transactions via REST APIs).

Client requests:

These keys are designed for client-side communication, and are safe to include in end-user code:

  • Client API Key: For all client-side communication (i.e., JSON-RPC APIs).

Client API Key

The Client API Key is designed specifically for client-side applications. This key:

  • Is present within your RPC endpoint URL (i.e., https://api.developer.coinbase.com/rpc/v1/base/<MY-CLIENT-API-KEY>)
  • Authenticates JSON-RPC requests from browser-based applications and mobile apps
  • Is safe to include in client-side code
  • Has limited functionality by design
  • Can be easily rotated if needed

1. Create Client API Key

To create a Client API Key:

  1. Navigate to your API Keys dashboard.
  2. Select your desired project from the top drop-down.
  3. Select the Client API Key tab.
  4. Copy the generated key.
  5. Export as an environment variable:
export CLIENT_API_KEY="your_client_api_key"

Click the Rotate button to expire this key and generate a new one.

2. Authenticate

To authenticate your client-side code, include it with your JSON-RPC request:

curl -L -X "$HTTP_METHOD" https://api.developer.coinbase.com/rpc/v1/base/${CLIENT_API_KEY} \
  -H "Content-Type: application/json" \
  -d '${REQUEST_BODY_JSON}'

As an example, you can request the List Historical Balances JSON-RPC endpoint like so:

curl -L -X POST https://api.developer.coinbase.com/rpc/v1/base/${CLIENT_API_KEY} \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "cdp_listBalances", "params": [{"address":"0xF7DCa789B08Ed2F7995D9bC22c500A8CA715D0A8","pageToken":"","pageSize":1}]}'

Secret API Key

The Secret API Key is required for all server-to-server communication with CDP APIs. This key:

  • Is used to generate a Bearer Token (JWT), which authenticates your CDP project ownership
  • Is used in the Authorization header of your request
  • Is required as the base layer of authentication for all server endpoints
  • Must be kept secure and never exposed in client-side code
  • Can be configured with IP allowlists and more granular permissions

1. Create Secret API Key

To create a Secret API Key:

  1. Navigate to your API Keys dashboard.
  2. Select your desired project from the top drop-down.
  3. Select the Secret API Keys tab.
  4. Click Create API key and name your key.
  5. Optional: Configure additional settings
    • IP allowlist
    • Permission restrictions
    • Signature algorithm (Ed25519 recommended)
  6. Click Create & download.

A modal will appear with your key details.

Make sure you save the API key ID and Secret in a safe place. You can’t re-download it later.

To regenerate a Secret API key, click Configure to delete and recreate the key.

2. Generate Bearer Token

Bearer Tokens (JWTs) are required for server-to-server communication only, are included in your Authorization header, and are generated using your Secret API Key.

Use our SDK for easier authentication

The CDP SDK automatically handles generation of Bearer Tokens for you, streamlining the process of making requests to all of our REST endpoints.

For REST API users, continue reading to:

  • Set up your environment for Bearer Token generation by configuring environment variables and installing dependencies
  • Export your generated Bearer Token as an environment variable

Never include Secret API key information in your code.

Instead, securely store it and retrieve it from an environment variable, a secure database, or other storage mechanism intended for highly-sensitive parameters.

Environment setup

To begin, export the following environment variables:

export KEY_NAME="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export KEY_SECRET="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=="
export REQUEST_METHOD="GET"
export REQUEST_PATH="/platform/v2/evm/token-balances/base-sepolia/0x8fddcc0c5c993a1968b46787919cc34577d6dc5c"
export REQUEST_HOST="api.cdp.coinbase.com"

Complete the remaining setup steps for JWT generation below according to your language choice.

Generate Bearer Token (JWT) and export

First, install the CDP SDK:

npm install @coinbase/cdp-sdk

Create a new file for JWT generation code:

main.js
const { generateJwt } = require("@coinbase/cdp-sdk/auth");

const main = async () => {
  // Generate the JWT using the CDP SDK
  const token = await generateJwt({
    apiKeyId: process.env.KEY_NAME,
    apiKeySecret: process.env.KEY_SECRET,
    requestMethod: process.env.REQUEST_METHOD,
    requestHost: process.env.REQUEST_HOST,
    requestPath: process.env.REQUEST_PATH,
    expiresIn: 120 // optional (defaults to 120 seconds)
  });
  
  console.log(token);
};

main();

Finally, run the script to generate the JWT output and export it as an environment variable:

export JWT=$(node main.js)
echo $JWT

Bearer Tokens are valid for 2 minutes by default. After 2 minutes, you will need to generate a new Bearer Token (JWT) to ensure uninterrupted access to the CDP APIs. If you are experiencing issues, please make sure your machine’s clock is accurate.

3. Authenticate

Use our SDK for easier authentication

The CDP SDK automatically handles authentication for you, streamlining the process of making requests to all of our REST endpoints.

To authenticate your server-side code, use the JWT token you generated in the previous step as a Bearer Token within your request:

export API_ENDPOINT="https://$REQUEST_HOST$REQUEST_PATH"

# Now, use that endpoint in your curl command
curl -L -X "$HTTP_METHOD" "$API_ENDPOINT" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json"

As an example, Get Asset by ID could be requested like so:

curl -L -X POST "https://api.cdp.coinbase.com/platform/v1/networks/base-mainnet/assets/BTC" \
  -H "Authorization: Bearer ${JWT}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json"

Wallet Secret

The Wallet Secret is an additional layer of security that’s required for any server-to-server requests that involve sensitive wallet write operations to the EVM and Solana APIs. This key:

  • Is used to generate a Wallet Token (JWT), which authenticates your wallet ownership
  • Is used in the X-Wallet-Auth header of your request
  • Is required for sensitive wallet operations (i.e., POST and DELETE requests), such as signing a transaction
  • Should be treated like the password to your onchain wallet
  • Is generated by CDP’s Trusted Execution Environment (TEE)
  • Is never visible to Coinbase

1. Create Wallet Secret

To create a Wallet Secret:

  1. Navigate to your Wallet API dashboard.
  2. Ensure your desired project is selected from the top drop-down.
  3. In the Wallet Secret section, click the Generate button.
  4. Save the secret in a secure location - you won’t be able to view it again.

Your Wallet Secret is a secret that, when combined with your Secret API Key, can be used to sign transactions and messages. It is generated by CDP’s Trusted Execution Environment (TEE), and is never visible to Coinbase. Secure it as you would a password, and never share it or expose it in client-side code.

2. Generate Wallet Token

Wallet Tokens (Wallet Authentication JWTs) are required for any server-to-server communication that requires a X-Wallet-Auth header, and are generated using your Wallet Secret.

Use our SDK for easier authentication The CDP SDK automatically handles generation of Wallet Authentication JWTs for you, streamlining the process of making requests to all of our REST endpoints.

For REST API users, continue reading to:

  • Set up your environment for Wallet Authentication JWT generation by configuring environment variables and installing dependencies
  • Export your generated Wallet Authentication JWT as an environment variable

Environment setup

To begin, export the following environment variables:

# Your Wallet Secret from the CDP Portal
export WALLET_SECRET="your-wallet-secret"

# The endpoint you're calling
export REQUEST_METHOD="POST"
export REQUEST_PATH="/platform/v2/evm/accounts/0x742d35Cc6634C0532925a3b844Bc454e4438f44e/sign/transaction"
export REQUEST_HOST="api.cdp.coinbase.com"

# The exact request body you'll send
export REQUEST_BODY='{"transaction": "0x1234567890123456789012345678901234567890"}'

Complete the remaining setup steps for JWT generation below according to your language choice.

Generate Wallet Token (JWT) and export

First, install required dependencies:

npm install jsonwebtoken uuid

Create a new file to generate your Wallet Token:

generate_wallet_jwt.js
const jwt = require('jsonwebtoken');
const crypto = require('crypto');

// Get environment variables
const walletSecret = process.env.WALLET_SECRET;
const requestMethod = process.env.REQUEST_METHOD;
const requestHost = process.env.REQUEST_HOST;
const requestPath = process.env.REQUEST_PATH;
const requestBody = process.env.REQUEST_BODY;

// Create the JWT payload
const now = Math.floor(Date.now() / 1000);
const uri = `${requestMethod} ${requestHost}${requestPath}`;

const payload = {
  iat: now,
  nbf: now,
  jti: crypto.randomBytes(16).toString('hex'),
  uris: [uri]
};

// Add request body if present
if (requestBody) {
  payload.req = JSON.parse(requestBody);
}

// Generate the JWT
const token = jwt.sign(payload, walletSecret, {
  algorithm: 'ES256',
  header: { typ: 'JWT' }
});

console.log(token);

Finally, run the script to generate the JWT output and export it as an environment variable:

# Generate and export the JWT
export WALLET_AUTH_JWT=$(node generate_wallet_jwt.js)
echo $WALLET_AUTH_JWT

Wallet Tokens are valid for 1 minute. After 1 minute, you will need to generate a new one. If you are experiencing issues, please make sure your machine’s clock is accurate.

3. Authenticate

Use our SDK for easier authentication The CDP SDK automatically handles authentication for you, streamlining the process of making requests to all of our REST endpoints.

For endpoints that require wallet authentication (marked with the X-Wallet-Auth header requirement), you must include both:

  1. The standard Bearer token in the Authorization header
  2. The Wallet Authentication JWT in the X-Wallet-Auth

For example, to sign a transaction:

# First construct the full API endpoint using our env vars
export API_ENDPOINT="https://${REQUEST_HOST}${REQUEST_PATH}"

# Make the authenticated request using both JWT tokens
curl -L -X ${REQUEST_METHOD} "${API_ENDPOINT}" \
  -H "Authorization: Bearer ${JWT}" \
  -H "X-Wallet-Auth: ${WALLET_AUTH_JWT}" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d "${REQUEST_BODY}"

This example uses the environment variables we set earlier.