Skip to main content

Overview

Auth methodWhen to useHeader format
API KeyPortfolio, traders, orders, accountAuthorization: Bearer cc_<key>
Privy JWTCreating and revoking API keysAuthorization: Bearer <jwt>
Most integrations only need API keys. You only need a Privy JWT when programmatically managing keys themselves.

API Keys

Format

API keys follow the format cc_ followed by 64 lowercase hexadecimal characters:
cc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Usage

Pass your key as a Bearer token in the Authorization header:
curl https://carboncopy.news/api/v1/portfolio \
  -H "Authorization: Bearer cc_your_key_here"

Scopes

Every key is issued with a set of scopes that control what it can access. Always issue keys with the minimum scopes your use-case requires.
ScopeValuesControls
portfolionone, readView portfolio summary, history, and positions
tradersnone, read, writeList/view traders (read); follow/edit/unfollow (write)
ordersnone, read, writeView orders (read); future order mutations (write)
marketsnone, readMarket data access (coming soon)
accountnone, readView account information
write scope implies read for the same resource. You don’t need to grant both.

Key lifecycle

  • Keys are created via the Dashboard (Settings → API Keys) or the POST /api/v1/keys endpoint.
  • A key’s secret is revealed exactly once at creation — it cannot be retrieved later.
  • Keys can have an optional expiry timestamp (expiresAt).
  • Maximum 10 active keys per account.
  • Revoke a key via the Dashboard or DELETE /api/v1/keys/{keyId}.

Security best practices

Never commit API keys to source control. Use environment variables or a secrets manager.
  • Rotate regularly — set an expiresAt and automate rotation in production.
  • Narrow scopes — monitoring bots only need portfolio:read; they don’t need traders:write.
  • One key per service — easier to audit, easier to revoke if compromised.
  • Revoke immediately if a key is exposed.

Privy JWT (Key Management only)

Privy JWTs are issued by Privy after you authenticate with your Carbon Copy account. They are required for the Key Management endpoints (POST /api/v1/keys, GET /api/v1/keys, DELETE /api/v1/keys/{keyId}). Obtain a Privy JWT client-side using the Privy SDK:
import { usePrivy } from "@privy-io/react-auth";

const { getAccessToken } = usePrivy();
const jwt = await getAccessToken();
Then pass it as a Bearer token, identical to an API key:
curl -X POST https://carboncopy.news/api/v1/keys \
  -H "Authorization: Bearer <privy-jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "my-bot", "scopes": { "portfolio": "read" } }'
Privy JWTs are short-lived. Refresh them before making key management calls.

Error responses

If authentication fails, the API returns a 401 Unauthorized:
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key."
  }
}
If you authenticate successfully but your key lacks the required scope, you’ll receive 403 Forbidden:
{
  "error": {
    "code": "forbidden",
    "message": "This key does not have the required scope."
  }
}
See Errors for the full error reference.