API Gateway Architecture
The freeAIhashtags.com API Gateway is a Cloudflare Worker that handles authentication, rate limiting, and proxying to Supabase Edge Functions.
Overview
Client Request
|
v
API Gateway (Cloudflare Worker)
|
+--> Auth Middleware
| |- Check x-api-key?
| | |- YES: Validate via KV cache/DB
| | |- NO: Check Bearer token
| |
| +--> Set authContext
|
+--> Rate Limit Middleware
| |- Get user's plan limits
| |- Check KV usage counter
| |- Enforce daily quota
|
+--> Proxy to Supabase Edge Function
|- Forward auth headers
|- Set X-User-Id for API key requests
Dual Authentication
1. API Key Authentication (Public API)
- Header:
x-api-key: faiht_sk_xxxxx - Format:
faiht_sk_prefix + random string - Storage: SHA-256 hash in
user_api_keystable - Caching: 5-minute TTL in Cloudflare KV
- Use Case: Server-to-server, third-party developers
2. Bearer Token (Internal/Frontend)
- Header:
Authorization: Bearer <jwt> - Source: Supabase JWT tokens
- Validation: Done by Supabase Edge Functions
- Use Case: Frontend applications, authenticated users
Rate Limiting
Implementation
- Storage: Cloudflare KV (free tier: 100K reads, 1K writes/day)
- Granularity: Per-user, per-day
- Reset: Midnight UTC
Flow
- Extract
userIdfrom auth context - Check KV for
limit:{userId}(plan limit, cached 1 hour) - Check KV for
usage:{userId}:{date}(current usage) - Compare:
usage < limit - Return
429if exceeded, otherwise increment counter
Response Headers
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 499
X-RateLimit-Reset: 2024-12-13T00:00:00Z
Database Schema
user_api_keys Table
CREATE TABLE user_api_keys (
id uuid PRIMARY KEY,
user_id uuid REFERENCES auth.users(id),
key_hash text NOT NULL, -- SHA-256 of actual key
key_prefix text NOT NULL, -- First 8 chars for display
name text DEFAULT 'Default Key',
created_at timestamptz,
last_used_at timestamptz,
revoked_at timestamptz,
UNIQUE(user_id, key_hash)
);
Plan Limits (in plans.features)
{
"api_calls_daily_limit": 500, // Pro plan
"api_calls_daily_limit": 5000 // Business plan
}
KV Namespace Structure
Keys
apikey:{sha256}→{valid: bool, userId: string, keyId: string}(5 min TTL)limit:{userId}→500(1 hour TTL)usage:{userId}:{YYYY-MM-DD}→123(expires at midnight)
Cache Strategy
- API Key Validation: Cache both positive and negative results
- Plan Limits: Cache for 1 hour (changes are rare)
- Usage Counters: Auto-expire at end of day
Deployment
Prerequisites
- Create KV namespace:
wrangler kv:namespace create "FAIHT_CACHE"
- Add GitHub Secrets:
PROD_KV_NAMESPACE_IDSANDBOX_KV_NAMESPACE_IDPROD_SUPABASE_URLSANDBOX_SUPABASE_URL
Subscription Management
The gateway exposes high-level endpoints for user subscription lifecycle:
POST /v1/user/subscription/cancelPOST /v1/user/subscription/reactivate
Both are proxied to the unified manage-subscription Edge Function. The gateway prepends the appropriate action ("cancel" or "reactivate") to the request body before proxying.
Webhook Proxying
Paddle webhooks are proxied through the gateway to provide a stable public URL while allowing the internal Supabase function to remain private:
POST /v1/webhooks/paddle→paddle-webhookEdge Function
Auto-Deployment
The API auto-deploys via GitHub Actions when changes are pushed to apps/api/:
# .github/workflows/ci-cd.yml
deploy-api:
if: changes in apps/api/**
runs:
- Install dependencies
- Inject KV_NAMESPACE_ID into wrangler.toml
- wrangler deploy with secrets
Manual Deployment
cd apps/api
# Update wrangler.toml with actual KV ID
# Then deploy:
npx wrangler deploy \
--var SUPABASE_URL:$SUPABASE_URL \
--var SUPABASE_ANON_KEY:$ANON_KEY
Security Considerations
- API Keys are Hashed: Never stored in plaintext
- KV Cache Invalidation: Revoked keys expire from cache in max 5 minutes
- Rate Limiting: Prevents abuse even with valid keys
- No Bearer Token Validation: Delegated to Supabase Edge Functions
Cost Analysis (Cloudflare Free Tier)
Monthly Estimates (1,000 API calls/day)
- Worker Invocations: 30,000/month (100K free)
- KV Reads: 90,000/month (3 per call: key check, limit, usage)
- KV Writes: 30,000/month (1 per call: usage increment)
Status: ✅ Well within free tier (100K requests, 100K KV reads, 1K KV writes/day)
Monitoring
Key Metrics to Track
- KV Read/Write Usage: Monitor via Cloudflare dashboard
- API Key Cache Hit Rate: Should be >80%
- Rate Limit Rejections: Track 429 responses
- Worker CPU Time: Should be <10ms per request
Alerts
- Set up Cloudflare alerts for:
- KV quota approaching limits
- Worker errors
- Unusual traffic patterns
Future Enhancements
- Burst Limits: Implementation is in progress using Cloudflare KV.
- Usage Analytics: Track per-endpoint usage
- Key Rotation: Auto-expire keys after X days
- IP-based Rate Limiting: Additional layer for anonymous users
- GraphQL API: Alternative to REST endpoints