Complete guide to API authentication: API keys, OAuth 2.0, JWT tokens, rate limiting, and security best practices for REST APIs in 2026.
API authentication is the gatekeeper of your web service. Whether you're building a public API, a microservice, or integrating with third-party services, understanding authentication methods is critical. This guide covers the three most popular approaches — API keys, OAuth 2.0, and JWT tokens — with practical code examples and security recommendations for 2026.
Authentication answers the question: "Who is making this request?" Authorization answers: "What are they allowed to do?" In REST APIs, authentication typically happens via HTTP headers, query parameters, or cookies. The method you choose depends on your use case:
API keys are the simplest and most widely used authentication method for REST APIs. Services like Google Maps, Stripe, OpenAI, and DevProToolkit all use API keys.
sk_live_abc123...)# Calling an API with an API key (Python)
import requests
response = requests.get(
"https://api.commandsector.in/api/qr/generate",
params={"data": "https://example.com", "size": 300},
headers={"X-API-Key": "your_api_key_here"}
)
# The server validates your key before processing
print(response.status_code) # 200 if valid, 401 if invalid
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
async def validate_api_key(request: Request):
api_key = request.headers.get("X-API-Key")
if not api_key:
raise HTTPException(401, "Missing API key")
# Look up key in database
user = await db.get_user_by_key(api_key)
if not user or not user.is_active:
raise HTTPException(401, "Invalid API key")
# Check rate limits
if await is_rate_limited(user):
raise HTTPException(429, "Rate limit exceeded")
return user
@app.get("/api/resource")
async def get_resource(request: Request):
user = await validate_api_key(request)
# Process request...
return {"data": "your resource"}
Get a free API key for 13 production APIs — no credit card required.
Get Free API KeyOAuth 2.0 is the industry standard for delegated authorization. It allows users to grant third-party apps limited access to their resources without sharing passwords. You've used OAuth every time you clicked "Sign in with Google" or "Connect your GitHub account."
JSON Web Tokens (JWTs) are compact, self-contained tokens that carry user identity and claims. They're signed (and optionally encrypted) so the server can verify them without a database lookup.
# A JWT has three parts: header.payload.signature
# Example:
# eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMjN9.abc123signature
import jwt
from datetime import datetime, timedelta
SECRET_KEY = "your-secret-key"
# Create a token
token = jwt.encode({
"user_id": 123,
"email": "dev@example.com",
"exp": datetime.utcnow() + timedelta(hours=24)
}, SECRET_KEY, algorithm="HS256")
# Verify a token
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
print(f"User ID: {payload['user_id']}")
except jwt.ExpiredSignatureError:
print("Token expired")
except jwt.InvalidTokenError:
print("Invalid token")
Rate limiting is essential for any API. It prevents abuse, ensures fair usage, and enables tiered pricing.
| Strategy | How It Works | Best For |
|---|---|---|
| Fixed Window | Count requests per time window (e.g., 100/hour) | Simple APIs |
| Sliding Window | Rolling count that smooths traffic spikes | Production APIs |
| Token Bucket | Tokens refill at a constant rate; each request costs a token | High-traffic APIs |
| Per-Key Quotas | Daily/monthly limits per API key | Freemium models |
| Tier | Daily Requests | Rate Limit | Price |
|---|---|---|---|
| Free | 100 | 10/minute | $0 |
| Pro | 10,000 | 120/minute | $9.99/mo |
| Enterprise | 1,000,000 | 600/minute | $49.99/mo |
This is the exact pricing model used by DevProToolkit API Hub, which offers 13 APIs under a single key with tiered access.
| Feature | API Keys | OAuth 2.0 | JWT |
|---|---|---|---|
| Complexity | Low | High | Medium |
| User context | No (machine identity) | Yes | Yes |
| Stateless | No (DB lookup) | No | Yes |
| Revocable | Yes (delete key) | Yes | Hard (need blocklist) |
| Best for | Public APIs | User-facing apps | Microservices |
| Example services | Stripe, OpenAI, DevProToolkit | Google, GitHub | Auth0, Firebase |
Here's a complete API key authentication system you can copy into your FastAPI project:
from fastapi import FastAPI, Request, HTTPException, Depends
import sqlite3, secrets, hashlib, time
from functools import wraps
app = FastAPI()
def create_api_key(email: str, tier: str = "free"):
"""Generate and store a new API key."""
raw_key = f"sk_{secrets.token_hex(24)}"
hashed = hashlib.sha256(raw_key.encode()).hexdigest()
conn = sqlite3.connect("api_keys.db")
conn.execute(
"INSERT INTO api_keys (key_hash, email, tier) VALUES (?, ?, ?)",
(hashed, email, tier)
)
conn.commit()
conn.close()
return raw_key # Only returned once, never stored in plain text
RATE_LIMITS = {
"free": {"daily": 100, "per_minute": 10},
"pro": {"daily": 10000, "per_minute": 120},
}
async def get_api_user(request: Request):
"""Dependency that validates API key and enforces rate limits."""
key = request.headers.get("X-API-Key", "")
if not key:
raise HTTPException(401, {"error": "Missing X-API-Key header"})
hashed = hashlib.sha256(key.encode()).hexdigest()
conn = sqlite3.connect("api_keys.db")
row = conn.execute(
"SELECT email, tier, is_active FROM api_keys WHERE key_hash = ?",
(hashed,)
).fetchone()
conn.close()
if not row:
raise HTTPException(401, {"error": "Invalid API key"})
if not row[2]:
raise HTTPException(403, {"error": "API key disabled"})
return {"email": row[0], "tier": row[1]}
@app.get("/api/protected")
async def protected_endpoint(user=Depends(get_api_user)):
return {"message": f"Hello {user['email']}!", "tier": user["tier"]}
This pattern is used by professional API services like DevProToolkit, which manages 13 APIs, 104+ endpoints, and multiple pricing tiers with a single unified authentication system.
DevProToolkit provides 13 ready-to-use APIs with built-in authentication, rate limiting, and usage tracking. Get a free key and start building.
Get Free API Key Try API PlaygroundIt depends on your use case. API keys are best for public developer APIs and server-to-server communication. OAuth 2.0 is best for user-facing apps that need delegated access. JWT tokens are best for stateless auth in microservice architectures.
Use API keys when your consumers are developers or machines. Use OAuth when end users need to grant and revoke access. Many services (like GitHub) offer both: API keys for personal use and OAuth for third-party apps.
Start with a fixed window counter (count requests per API key per day). For production, use a sliding window or token bucket algorithm. Store counters in Redis for performance, or SQLite for simplicity.
Get your free API key and start making requests in minutes.
curl "http://147.224.212.116/api/..." \
-H "X-API-Key: YOUR_API_KEY"
Get a free API key with 100 requests/day. No credit card required.
Get Free API Key