Cloudflare AI Gateway — unified proxy for Claude, OpenAI, and Workers AI.
AI Gateway is a proxy that sits between your Workers and AI providers (Anthropic, OpenAI, Workers AI). It provides caching, rate limiting, logging, fallback routing, and token usage analytics — all without changing your AI SDK code.
Free tier: 100k requests/month, 7-day log retention. Paid: Higher request limits, 30-day retention, persistent logs.
Every Claude API call in 2nth.ai should go through AI Gateway. This gives:
`` https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_name}/ ``
# Set via wrangler secret
wrangler secret put ANTHROPIC_BASE_URL
# Value: https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_name}/anthropic
// Before: direct Anthropic call
// const client = new Anthropic({ apiKey: env.ANTHROPIC_API_KEY });
// After: route through AI Gateway (no SDK changes needed)
const client = new Anthropic({
apiKey: env.ANTHROPIC_API_KEY,
baseURL: env.ANTHROPIC_BASE_URL, // points to AI Gateway
});
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
});
AI Gateway passes custom headers downstream — use these to tag which client and skill generated each request:
const client = new Anthropic({
apiKey: env.ANTHROPIC_API_KEY,
baseURL: env.ANTHROPIC_BASE_URL,
defaultHeaders: {
'cf-aig-metadata': JSON.stringify({
clientId: currentClient,
skillPath: 'biz/erp/sage-x3',
agentId: 'penny',
sessionId: sessionId,
}),
},
});
This metadata appears in AI Gateway logs → filterable by client for billing.
// Pass cache headers to AI Gateway
const client = new Anthropic({
apiKey: env.ANTHROPIC_API_KEY,
baseURL: env.ANTHROPIC_BASE_URL,
defaultHeaders: {
'cf-aig-cache-ttl': '3600', // cache for 1 hour (in seconds)
'cf-aig-skip-cache': 'false', // set 'true' to always bypass
},
});
When to cache: Classification tasks, FAQ answers, skill summaries — anything deterministic. When not to cache: User-specific conversations, real-time data queries.
// AI Gateway URL format for fallback:
// /v1/{account}/{gateway}/anthropic → /v1/{account}/{gateway}/workers-ai
// Configure in the gateway dashboard under "Providers" — set fallback order.
// Or call the universal gateway endpoint for provider-agnostic routing:
const response = await fetch(`${env.AI_GATEWAY_URL}/anthropic/v1/messages`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${env.ANTHROPIC_API_KEY}`,
'cf-aig-fallback-model': '@cf/meta/llama-3.1-8b-instruct', // Workers AI fallback
},
body: JSON.stringify({
model: 'claude-sonnet-4-6',
max_tokens: 512,
messages: [{ role: 'user', content: prompt }],
}),
});
In the Cloudflare dashboard, set per-gateway rate limits:
clientId fieldNo code changes needed — the gateway enforces limits and returns 429 when exceeded.
// AI Gateway exposes usage via Cloudflare API
// GET /client/v4/accounts/{account_id}/ai-gateway/gateways/{gateway_id}/logs
const logs = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${env.CF_ACCOUNT_ID}/ai-gateway/gateways/${env.GATEWAY_ID}/logs?limit=100`,
{ headers: { 'Authorization': `Bearer ${env.CF_API_TOKEN}` } }
);
// Each log entry includes: tokens_in, tokens_out, model, duration, metadata (client/skill)
// Aggregate by clientId for monthly billing
.../{gateway_name}/anthropic. For OpenAI: .../{gateway_name}/openai. Include the trailing provider slug.baseURL must end without trailing slash for Anthropic SDK v4+.cf-aig-metadata must be valid JSON string: Stringify it before setting as a header value.