Skip to content

Authentication

Base URLs, the two supported auth headers, the tok_live_ key format, and what the 401 and 403 error codes mean.

On this page

Every request to the Tokens API authentication layer needs one platform key, sent in a header. This page covers the base URLs, the headers we accept, the key format, and what each authentication error means.

Base URLs#

Tokens exposes two surfaces on the same host. Which one you use depends on the client, not the model.

Client styleBase URLTypical tools
OpenAI-compatiblehttps://tokens.bd/v1OpenAI SDKs, Cursor, Cline, Aider, OpenCode, Codex CLI
Anthropic-compatiblehttps://tokens.bdAnthropic SDKs, Claude Code (they append /v1/messages themselves)

If a tool asks for an "API base" or "base URL" and is OpenAI-flavored, include /v1. If it is Anthropic-flavored, leave /v1 off, because the SDK adds it. Getting this wrong is the most common cause of a 404 on the first request.

Tools that need to discover the endpoints can read them from a public, unauthenticated config endpoint:

bash
curl https://tokens.bd/api/gateway/config
json
{
  "openaiBaseUrl": "https://tokens.bd/v1",
  "anthropicBaseUrl": "https://tokens.bd"
}

Send your API key in a header#

We accept the key in either of two headers. Use whichever your client sends by default.

HeaderFormatSent by
AuthorizationBearer tok_live_your_keyOpenAI SDKs, Claude Code with ANTHROPIC_AUTH_TOKEN, most tools
x-api-keytok_live_your_keyAnthropic SDKs

If both are present, the Authorization: Bearer header wins. An Authorization header with any scheme other than Bearer is ignored, and the gateway then looks for x-api-key.

curl https://tokens.bd/v1/models \
  -H "Authorization: Bearer $TOKENS_API_KEY"

Key format#

Keys look like tok_live_ followed by 48 hexadecimal characters. The full secret is shown once, when you create the key in the dashboard. We store only a hash, so a lost key cannot be recovered; create a new one instead. Key creation, spend caps, allowed-model lists and rotation are covered in API keys.

Keep the key in an environment variable#

All examples in these docs read the key from TOKENS_API_KEY:

bash
export TOKENS_API_KEY="tok_live_your_key"

On Windows PowerShell:

powershell
$env:TOKENS_API_KEY = "tok_live_your_key"

Then read it in code rather than pasting it:

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://tokens.bd/v1",
    api_key=os.environ["TOKENS_API_KEY"],
)

Do not commit keys

A key in a committed .env, config file or notebook is a leaked key. Add those files to .gitignore. If a key does leak, rotate it in the dashboard; the old secret stops working immediately.

Server-side only: no browser calls#

The API does not send CORS headers on its responses, so fetch from a web page will fail in the browser even with a valid key. This is deliberate: a key shipped to a browser is readable by anyone who opens dev tools. Call Tokens from your backend, a serverless function, a CLI, or a coding agent, and have your frontend talk to that.

What 401 and 403 mean#

Authentication failures return the standard error body with a machine-readable code:

json
{
  "error": {
    "message": "Invalid API key.",
    "type": "authentication_error",
    "code": "invalid_api_key",
    "param": null,
    "request_id": "8f0c7a4e-2b1d-4c55-9a51-3f7e2d9b6c10"
  }
}
StatusCodeMeaningFix
401missing_api_keyNo Authorization: Bearer or x-api-key header arrivedCheck the env var is set in the shell that runs the tool
401invalid_api_keyThe key does not match any key we issuedCheck for truncation or stray quotes; copy the key again or create a new one
403key_inactiveThe key was revoked or rotatedUse the current secret or create a new key
403key_expiredThe key had an expiry date that has passedCreate a new key
403account_suspendedThe account is suspendedContact support
403model_not_allowed_on_keyThe key has an allowed-models list that excludes this modelUse a listed model or a different key
403monthly_spend_cap_exceededThe key reached its monthly spend capWait for the next month or use another key
403tier_permission_deniedYour plan does not include this model and you have no wallet balanceSee plans and wallet

A 401 or 403 with code upstream_auth_error is different: it means the gateway's own credentials for an upstream provider were refused, not yours. Your key is fine; retry later or try another model, and include the request id if you contact support.

The full list of codes, including billing and rate-limit errors, is in errors. To confirm a key works end to end, the quickstart has a one-line test request.

Was this page helpful?

Still stuck? Open a support ticket

Need help configuring your agent?

Test your connection with the connection tester, or create an API key.