diagram.mmd — flowchart
API Key Authentication flowchart diagram

API key authentication is the simplest form of machine-to-machine authentication: a client proves its identity by presenting a shared secret string — the API key — with each request. It is widely used for public APIs, webhook endpoints, and developer tooling where the simplicity of a static credential outweighs the overhead of OAuth2 flows.

An API key is a long, random string (typically 32–64 bytes encoded as hex or Base64) generated by the API provider and given to the client. The client includes the key on every request, typically via an Authorization: Bearer header, an X-API-Key header, or a query parameter (query parameters are discouraged as keys appear in access logs and browser history).

On the server side, the key is never stored in plaintext. Instead, the server stores a hash of the key (using SHA-256 or a similar fast hash — bcrypt is too slow for per-request use). When a request arrives, the server hashes the incoming key and compares it to the stored hash. This means a database breach does not immediately expose all API keys.

After validation, the server looks up the key's associated account, checks whether the key is active and not expired, and verifies that the key has the required permissions or scope for the requested endpoint. Rate limiting is typically applied per key. Usage events are logged for audit and billing purposes.

Key rotation is an operational challenge: unlike OAuth2 Client Credentials Flow which issues short-lived tokens automatically, API keys are long-lived secrets that must be rotated manually. Best practice is to support multiple active keys per account simultaneously, allowing clients to transition to a new key before the old one is revoked. For richer permission models, see RBAC Authorization Model.

Free online editor
Edit this diagram in Graphlet
Fork, modify, and export to SVG or PNG. No sign-up required.
Open in Graphlet →

Frequently asked questions

API key authentication is a simple machine-to-machine authentication method where a client proves its identity by including a shared secret string — the API key — with each request. The server validates the key, identifies the associated account, checks permissions, and processes the request. It is widely used for public APIs, webhooks, and developer tooling.
The server never stores API keys in plaintext. Instead, it stores a hash of the key (typically SHA-256). When a request arrives, the server hashes the incoming key and compares it to the stored hash. This means a database breach does not immediately expose all API keys. The client, however, must store the key securely — treat it like a password.
Support multiple active keys per account simultaneously so clients can generate a new key, update their configuration, and only then revoke the old key — with no downtime. Provide clear expiry dates and remind API key holders before expiry. Log usage per key to detect anomalies. Never put API keys in source code or URLs; use environment variables or a secrets manager.
API keys are long-lived static secrets that authenticate a client identity but carry no scopes or user context by default. OAuth2 Client Credentials Flow issues short-lived, scoped tokens automatically — the client re-authenticates when tokens expire. OAuth2 is more secure (smaller compromise window) and more flexible (scope-limited tokens), but requires more integration work. API keys are simpler and appropriate when the added complexity of OAuth2 is not justified.
mermaid
flowchart TD A([API request with key]) --> B{Key present in header?} B -- No --> C([401 - API key required]) B -- Yes --> D[Hash incoming API key with SHA-256] D --> E[Look up hash in database] E --> F{Key found?} F -- No --> G([401 - invalid API key]) F -- Yes --> H{Key active and not expired?} H -- No --> I([401 - key revoked or expired]) H -- Yes --> J[Load associated account and permissions] J --> K{Rate limit exceeded?} K -- Yes --> L([429 - rate limit exceeded]) K -- No --> M{Key has required scope?} M -- No --> N([403 - insufficient permissions]) M -- Yes --> O[Log usage event] O --> P([Process request and return response])
Copied to clipboard