All /api/** routes (except public health checks) now require API key authentication and are protected by rate limiting.
Generate a secure random API key:
# Option 1: Using OpenSSL
openssl rand -hex 32
# Option 2: Using Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Option 3: Using Python
python3 -c "import secrets; print(secrets.token_hex(32))"Add to your .env.local or deployment environment:
NEXTELEVEN_API_KEY=your_generated_api_key_hereImportant:
- In production,
NEXTELEVEN_API_KEYis required - In development, if not set, API access is allowed (with a warning)
curl -H "X-API-Key: your_api_key_here" \
https://your-domain.com/api/chatcurl -H "Authorization: Bearer your_api_key_here" \
https://your-domain.com/api/chatconst response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.NEXTELEVEN_API_KEY, // or Authorization: Bearer
},
body: JSON.stringify({ message: 'Hello' }),
})These endpoints don't require authentication:
GET /api/system/env-status- Health check and environment status
- Limit: 100 requests per hour per client
- Headers: Rate limit status is included in response headers:
X-RateLimit-Limit: Maximum requests allowedX-RateLimit-Remaining: Requests remaining in current windowX-RateLimit-Reset: ISO timestamp when limit resets
- Response:
429 Too Many Requestswhen limit exceeded
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 2026-01-14T18:00:00.000Z
Retry-After: 3600
{
"error": "Rate limit exceeded",
"message": "Too many requests. Limit: 100 requests per hour...",
"retryAfter": 3600
}
{
"error": "Authentication required",
"message": "Provide API key via X-API-Key header or Authorization: Bearer token",
"requestId": "..."
}{
"error": "Invalid API key",
"message": "The provided API key is invalid",
"requestId": "..."
}{
"error": "Rate limit exceeded",
"message": "Too many requests. Limit: 100 requests per hour...",
"requestId": "...",
"retryAfter": 3600
}- Constant-Time Comparison: API key validation uses constant-time comparison to prevent timing attacks
- Secure Token Storage: Never log or expose API keys in responses
- Rate Limiting: Prevents abuse and DoS attacks
- Public Endpoint Whitelist: Health checks accessible without auth
If you're upgrading from a version without authentication:
- Set
NEXTELEVEN_API_KEYenvironment variable - Update all API clients to include the
X-API-Keyheader - Test health check endpoint:
GET /api/system/env-status(should work without auth) - Test authenticated endpoint:
POST /api/chat(should work with auth, fail without)
-
NEXTELEVEN_API_KEYis set in production environment - API key is strong (32+ characters, random)
- API key is rotated periodically
- All API clients include authentication headers
- Rate limiting is tested under load
- Monitoring is set up for 401/429 responses
Issue: 401 Authentication required
Solution: Ensure X-API-Key header is included in requests
Issue: 401 Invalid API key
Solution: Verify NEXTELEVEN_API_KEY environment variable matches the header value
Issue: 429 Rate limit exceeded
Solution: Wait for rate limit window to reset, or increase limit in src/lib/ratelimit.ts
Issue: Development mode allowing access without API key
Solution: This is expected behavior in development. In production, API key is required.