API Authentication: API Keys, Bearer Tokens and Why They Matter
~11 min read
Authentication proves WHO is calling an API. API keys and Bearer tokens are the two forms you'll see constantly — both are secrets that must never leak, since anyone holding them can act as you.
An API that does anything valuable — costs money per call, accesses private data, or performs real actions — needs to know WHO is calling it before doing the work. Authentication is the process of proving your identity to the API; authorization (a related but distinct concept) is then deciding what that identified caller is ALLOWED to do. Without authentication, an API accessible on the internet would let literally anyone use it, run up unlimited costs on the provider's bill, or access data that isn't theirs.
An API key is the simplest common form: a single, unique, secret string that identifies you (or your application) to the API provider. You obtain it once (usually by signing up for the API provider's service) and include it with every request you make, typically as an HTTP header. The provider checks that the key is valid and looks up who it belongs to, which lets them track usage, enforce rate limits, and bill you correctly. OpenAI, Anthropic, and virtually every AI API provider use exactly this pattern for their core authentication.
A Bearer token is a closely related idea, standardized as part of HTTP's Authorization header: you send Authorization: Bearer <token> with your request, and 'bearer' literally means whoever HOLDS ('bears') this token is treated as authenticated — no additional proof needed beyond possessing the token itself. This is the mechanism many API keys are technically delivered through (an API key IS often sent as a Bearer token), and it's also how OAuth-based systems (where you might log in via 'Sign in with Google' and get a temporary access token) authenticate requests after the initial login flow completes.
The critical practical point: an API key or Bearer token is exactly as sensitive as a password — anyone who obtains it can make requests AS YOU, running up your bill or accessing your data, with the provider having no way to distinguish them from the real you. This means: never commit an API key into source code that gets pushed to a public (or even private) repository; never put one directly in frontend/browser JavaScript, where any user can view it in their browser's developer tools; load it from an environment variable or a secrets manager instead; and if a key ever DOES leak, revoke it (invalidate the old one, generate a new one) immediately through the provider's dashboard rather than hoping nobody notices.
💻 Code example
# Correct vs incorrect patterns for handling an API key --
# the security mistake matters more here than the specific syntax.
import os
# --- WRONG: hardcoding a secret directly in source code ---
# api_key = "sk-abc123-this-should-never-be-in-committed-code"
# --- RIGHT: load from an environment variable, never committed ---
api_key = os.environ.get("OPENAI_API_KEY")
def build_auth_header(api_key: str) -> dict:
"""The standard Bearer token pattern: whoever HOLDS this header
value is treated as authenticated -- no extra proof needed."""
if not api_key:
raise ValueError("Missing API key -- set OPENAI_API_KEY in your environment")
return {"Authorization": f"Bearer {api_key}"}
# Simulate calling an API with the header attached
def call_authenticated_api(headers: dict) -> dict:
auth = headers.get("Authorization", "")
if not auth.startswith("Bearer ") or len(auth) < 15:
return {"status": 401, "error": "Unauthorized"}
return {"status": 200, "data": "here is your response"}
demo_key = "sk-demo-00000000000000000000" # stand-in only, never a real key
headers = build_auth_header(demo_key)
print("Request headers:", {"Authorization": "Bearer sk-***HIDDEN***"}) # never log the real value
print("Response:", call_authenticated_api(headers))
print("Response (missing key):", call_authenticated_api({}))
💬 Deep Dive with AI
Key points
- •Authentication proves WHO is calling an API; authorization then decides what that identified caller is allowed to do
- •An API key is a unique secret string, typically sent with every request via an HTTP header, that identifies you to the provider
- •A Bearer token (Authorization: Bearer <token>) means whoever HOLDS the token is treated as authenticated — often how API keys are actually transmitted
- •An API key/token is exactly as sensitive as a password — anyone who obtains it can act as you, running up your bill or accessing your data
- •Never hardcode keys in source code or frontend JavaScript; load from environment variables/secrets managers, and revoke immediately if one leaks