{"_self":{"principle":"Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.","widget":"article_topology","feature":"topology","name":"Article topology","what":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","contains":"claims, sources, anecdotes, question_graph slice","slug":"cloudflare-ai-gateway-setup","urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/topology"},"how_to_use":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","write":null,"imessage":null,"router_tag":null,"proof_chain":[{"step":1,"claim":"Articles are voxel graphs of tiered claims, not prose blobs.","verify":"https://miscsubjects.com/api/articles/constitution"},{"step":2,"claim":"Claims link to hash-chained sources via source_ids.","verify":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/sources"},{"step":3,"claim":"Ask reads topology; ingest/claim append to ledger.","verify":"https://miscsubjects.com/api/protocol"},{"step":4,"claim":"Models queue growth: populate → collaborate → repair → reflex.","verify":"https://miscsubjects.com/api/protocol/grow"},{"step":5,"claim":"Graph proves its own shape (reflex) and $/claim (yield).","verify":"https://miscsubjects.com/graph.html?layer=reflex"},{"step":6,"claim":"Full feature index + _explain on every API response.","verify":"https://miscsubjects.com/api/articles/system-map"}],"related_features":[{"id":"ask","name":"Ask protocol","what":"Answer only from topology; creates question_node with gaps and ingest_hint.","urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/prompts","write":"https://miscsubjects.com/api/protocol/ask"}},{"id":"graph_topology","name":"Cross-article graph","what":"Merged claims/sources across condition+stack slugs for one question.","urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/graph-topology?question=..."}},{"id":"question_graph","name":"Question graph","what":"Ask nodes (questions + gaps) and evidence_ingest nodes (pasted model output).","urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/question-graph","write":"https://miscsubjects.com/api/protocol/ask"}},{"id":"voxels","name":"Voxel graph","what":"Claims as atoms, sources as edges (supported_by, posted_by). Per-claim provenance.","urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/voxels","write":"https://miscsubjects.com/api/protocol/claim"}}],"system_map":"https://miscsubjects.com/api/articles/system-map","system_map_markdown":"https://miscsubjects.com/api/articles/system-map?format=markdown","not_medical_advice":true},"_explain":{"feature":"topology","name":"Article topology","what":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","why":"Every feature is auditable collective intelligence","how":"Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER.","model":null,"verifies":null,"urls":{"read":"https://miscsubjects.com/api/articles/cloudflare-ai-gateway-setup/topology"},"imessage":null,"router":null,"related":[{"id":"ask","what":"Answer only from topology; creates question_node with gaps and ingest_hint."},{"id":"graph_topology","what":"Merged claims/sources across condition+stack slugs for one question."},{"id":"question_graph","what":"Ask nodes (questions + gaps) and evidence_ingest nodes (pasted model output)."},{"id":"voxels","what":"Claims as atoms, sources as edges (supported_by, posted_by). Per-claim provenance."}],"not_medical_advice":true},"slug":"cloudflare-ai-gateway-setup","title":"How to create a Cloudflare AI Gateway, with authentication on","register":"essay","tags":["tooling","cloudflare","ai-gateway"],"updated_at":"2026-07-26T05:37:31.573Z","body_excerpt":"An AI Gateway is a URL you send AI requests to instead of sending them to OpenAI, Anthropic, xAI or Cloudflare's own models directly; Cloudflare forwards the request, returns the provider's answer unchanged, and keeps a row recording the model, the token counts, an estimated cost, the duration and the status code. It is not a model, not a router that picks a model for you, and not a billing account on its own — it is a proxy with a ledger, and everything else it does (caching, retries, rate limits, spend caps) is switched on per gateway or per request.\n\n## Evidence status\n\n**Observed** marks first-party measurements or runtime receipts from the named environment.\n**Derived** marks arithmetic calculated from cited inputs. **Specified** marks vendor or standards\ndocumentation. **Implemented** and **deployed** name code and live-state evidence, respectively.\n**Reproduced** means the stated procedure was rerun. **Externally attested** marks operator reports;\nthose reports show that an experience occurred, not that it is universal.\n\n## The gateway called `default` exists before you create anything\n\nIf a request omits the gateway id, the id `default` is used, and if no gateway by that name exists it is created on the first authenticated request. The settings it is born with are not the ones most guides assume:\n\n| Setting on the auto-created `default` gateway | Value |\n| --- | --- |\n| Authentication | On |\n| Log collection | On |\n| Caching | Off (TTL of 0) |\n| Rate limiting | Off |\n\nCaching is off, so any claim that the gateway will cut your bill by serving repeats describes a feature you have not enabled. Authentication is on, so the first thing that happens to a client which cannot send a second HTTP header is a `401`. Auto-creation applies only to the id `default`; any other id must be created first.\n\n[[embed:source:s1]]\n\n## Prerequisites, with the exact labels\n\n1. **A Cloudflare account.** The free plan is enough — AI Gateway's core features cost nothing on every plan.\n2. **Your account id.** Every dashboard URL is `https://dash.cloudflare.com/<ACCOUNT_ID>/...`; the 32-character hex string after the hostname is it. `wrangler whoami` prints the same value. It goes in every request URL.\n3. **Where the product lives.** Sidebar → **AI** → **AI Gateway**. Direct link: `https://dash.cloudflare.com/?to=/:account/ai/ai-gateway`.\n4. **An API token**, from `https://dash.cloudflare.com/profile/api-tokens` → **Create Token** → **Create Custom Token** → **Get started**. Under **Permissions** the rows read exactly `Account` · `AI Gateway` · `Read | Edit | Run`. Under **Account Resources** pick your account, then **Continue to summary** → **Create Token**. It is displayed once.\n\nThe three permissions are not interchangeable. `Read` lists gateways and reads settings and logs through the API. `Edit` creates, updates and deletes gateways, and is required to set `cache_ttl` or rate limits by API rather than by clicking. `Run` sends inference through `gateway.ai.cloudflare.com`, and is what the `cf-aig-authorization` header carries. None can be narrowed to one gateway:\n\n> The `AI Gateway Read`, `Run`, and `Edit` permissions cannot be restricted to a single gateway — unlike R2, which supports per-bucket scoping. Any token with `AI Gateway Run` can send requests through every gateway in the account, including any configured with stored provider keys through Bring Your Own Keys (BYOK), consuming those credentials.\n\nA leaked `Run` token is therefore an account-wide credential that can spend any provider key you have stored. Isolation between tenants means separate Cloudflare accounts, or a Worker binding instead of a URL.\n\n[[embed:source:s2]]\n\n## Creating one: five clicks, or one POST\n\n**Dashboard.** **AI** → **AI Gateway** → **Create Gateway** → type a **Gateway name** (64-character limit; the name becomes the gateway id and appears in every request URL) → **Create**.\n\n**API**, with a token carrying `AI Gateway` · `Edit`:\n\n```bash\ncurl -X POST \"https:/","ranking":"safety-first (interaction_risk/limitations), then quote-gated effective_weight","claims":[{"id":"c1","text":"The default gateway is created automatically on first authenticated use and begins with authentication and logging on, caching and rate limiting off.","tier":"system","section":"The gateway called default exists before you create anything","interaction_risk":false,"status":"active","source_ids":["s1","s16"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c2","text":"AI Gateway Read, Edit and Run have distinct jobs and cannot be restricted to one gateway, so a Run token is an account-wide spending credential.","tier":"system","section":"Prerequisites, with the exact labels","interaction_risk":false,"status":"active","source_ids":["s2"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c3","text":"Cloudflare exposes provider-native and account REST endpoints with different schemas, authentication, deprecation status and model support.","tier":"system","section":"Three URL shapes, and two of them are deprecated","interaction_risk":false,"status":"active","source_ids":["s3"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c4","text":"In the live comparison, the provider-native host returned 401 code 2009 for a token without AI Gateway Run while the account REST host returned HTTP 200 and logged the request.","tier":"system","section":"A token the REST API accepts is refused by the provider-native host","interaction_risk":false,"status":"active","source_ids":["s17"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c5","text":"Authenticated provider-native gateways require a second cf-aig-authorization header, and some base-URL clients cannot add it or send the provider's required first header shape.","tier":"system","section":"Authentication breaks every client whose whole config is a base URL and a key","interaction_risk":false,"status":"active","source_ids":["s10","s13"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c6","text":"Per-request cf-aig headers override gateway defaults for metadata, caching, retries, timeouts, logging and cost attribution.","tier":"system","section":"The cf-aig headers, their defaults, and what each changes","interaction_risk":false,"status":"active","source_ids":["s4"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c7","text":"The default cache keys the whole request, so identical requests can hit while semantically identical bodies containing different UUIDs miss.","tier":"system","section":"The cache key is a hash of the whole request","interaction_risk":false,"status":"active","source_ids":["s11","s18","s5"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c8","text":"A sliding limit of 120 requests per 60 seconds produced one 429 in 5,252 measured account requests and caps a runaway loop at 172,800 requests per day.","tier":"system","section":"Rate limiting is what stands between a leaked token and your balance","interaction_risk":false,"status":"active","source_ids":["s16","s6"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c9","text":"Gateway logs retain request, response, model, status, usage, cost and timing unless payload collection or log collection is disabled.","tier":"system","section":"Logs keep the prompt and the completion","interaction_risk":false,"status":"active","source_ids":["s7"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c10","text":"GraphQL aiGatewayRequestsAdaptiveGroups exposed per-request status, cache, duration, token and cost dimensions used for the article's measurements.","tier":"system","section":"Logs keep the prompt and the completion","interaction_risk":false,"status":"active","source_ids":["s14","s16"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c11","text":"Cloudflare labels cost as an estimate, and a production operator reports wrong estimates for specific flagship image models.","tier":"system","section":"What it costs, and the one number people report as wrong","interaction_risk":false,"status":"active","source_ids":["s8","s9"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c12","text":"The measured authenticated gateway logged 107 requests, 651,894 input tokens, 8,342 output tokens and $0.44830454 over 30 days; a second gateway logged 5,145 requests and $32.19921439.","tier":"system","section":"What it costs, and the one number people report as wrong","interaction_risk":false,"status":"active","source_ids":["s16"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c13","text":"A six-run-per-arm probe measured medians of 0.741 seconds through the gateway and 0.648 seconds without it, a difference inside the observed run-to-run spread.","tier":"system","section":"The hop costs less than the noise","interaction_risk":false,"status":"active","source_ids":["s15"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c14","text":"Anycast egress can make provider geo-blocking intermittent, as one Anthropic operator reported for requests landing in Hong Kong.","tier":"system","section":"Where the traffic egresses is a failure mode","interaction_risk":false,"status":"active","source_ids":["s12"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c15","text":"When client and provider constraints align, an operator found setup amounted to creating a gateway and changing one environment variable.","tier":"system","section":"Where the traffic egresses is a failure mode","interaction_risk":false,"status":"active","source_ids":["s19"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c16","text":"A reported custom-provider bug prepends /v1 to an upstream path even when the configured base URL omits it.","tier":"system","section":"Symptom, cause, fix","interaction_risk":false,"status":"active","source_ids":["s20"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false},{"id":"c17","text":"A reported dynamic Workers AI route fails through the universal endpoint while the same request succeeds through the compatibility endpoint.","tier":"system","section":"Symptom, cause, fix","interaction_risk":false,"status":"active","source_ids":["s21"],"why_material":"This changes how the gateway should be configured or how its output should be interpreted.","retracted_at":null,"retraction_reason":null,"challenged_by":[],"effective_weight":0.1,"quote_gated":false}],"sources":[{"id":"s1","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/get-started/","title":"Cloudflare AI Gateway — Get started","quote":"If no gateway with the ID default exists, one will be automatically created.","summary":"Documents the automatically created default gateway and its initial authentication, logging, caching, and rate-limit behavior.","claim_ids":["c1"]},{"id":"s2","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/configuration/authentication/","title":"Cloudflare AI Gateway — Authentication","quote":"The AI Gateway Read, Run, and Edit permissions cannot be restricted to a single gateway","summary":"Documents authenticated gateways, the cf-aig-authorization header, and account-wide AI Gateway permissions.","claim_ids":["c2"]},{"id":"s3","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/usage/rest-api/","title":"Cloudflare AI Gateway — REST API","quote":"Workers AI models (@cf/) do not support this schema.","summary":"Documents the account REST endpoints, request schemas, and model compatibility boundaries.","claim_ids":["c3"]},{"id":"s4","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/glossary/","title":"Cloudflare AI Gateway — Header glossary","quote":"Custom metadata allows you to tag requests with user IDs or other identifiers","summary":"Reference for cf-aig request and response headers, their defaults, and their effects.","claim_ids":["c6"]},{"id":"s5","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/features/caching/","title":"Cloudflare AI Gateway — Caching","quote":"Caching applies only to identical requests.","summary":"Documents the exact-request cache, TTL controls, custom keys, and cache-status response header.","claim_ids":["c7"]},{"id":"s6","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/features/rate-limiting/","title":"Cloudflare AI Gateway — Rate limiting","quote":"Once the rate limit is exceeded, requests will be blocked with a 429 status code.","summary":"Documents fixed and sliding windows and the HTTP response after the configured cap is reached.","claim_ids":["c8"]},{"id":"s7","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/observability/logging/","title":"Cloudflare AI Gateway — Logging","quote":"AI Gateway logs contain detailed information about requests and responses.","summary":"Documents stored request and response data, payload collection controls, and API access to log rows.","claim_ids":["c9"]},{"id":"s8","type":"publisher_documentation","url":"https://developers.cloudflare.com/ai-gateway/observability/costs/","title":"Cloudflare AI Gateway — Costs","quote":"The cost metric is an estimation based on the number of tokens sent and received in requests.","summary":"Cloudflare's qualification of gateway cost data as an estimate rather than an invoice.","claim_ids":["c11"]},{"id":"s9","type":"hn","url":"https://news.ycombinator.com/item?id=47806253","title":"Comment on Cloudflare's AI Platform","quote":"because Cloudflare AI Gateway is reporting inaccurate/wrong price for flagship models such as Nano Banana 2 and Nano Banana pro (I run production app using those).","summary":"A production operator reports incorrect price estimates for flagship image models despite repeated reports.","claim_ids":["c11"]},{"id":"s10","type":"github_issue","url":"https://github.com/cloudflare/moltworker/issues/74","title":"Authenticated AI Gateway support in Moltworker","quote":"When Authenticated Gateway is enabled on the AI Gateway, all requests from Moltworker fail because the required `cf-aig-authorization` header is never sent.","summary":"Concrete client failure when a base-URL integration has no way to add the gateway's second credential header.","claim_ids":["c5"]},{"id":"s11","type":"hn","url":"https://news.ycombinator.com/item?id=47301851","title":"Comment on AI Gateway cache hit rate","quote":"I was routing support-bot traffic through Cloudflare AI Gateway and  noticed the cache hit rate was near zero despite the product being  mature.","summary":"A production cache audit found 500 consecutive misses even though 89% of messages collapsed into fewer than 30 intents.","claim_ids":["c7"]},{"id":"s12","type":"hn","url":"https://news.ycombinator.com/item?id=42862073","title":"Comment on AI Gateway geographic egress","quote":"this made Cloudflare's AI Gateway an unusable product, as they hilariously put a node in HK so you never know when your Anthropic request is randomly going to fail defeating the whole purpose behind the product.","summary":"An operator reports intermittent Anthropic failures caused by gateway traffic egressing through Hong Kong.","claim_ids":["c14"]},{"id":"s13","type":"github_issue","url":"https://github.com/farion1231/cc-switch/issues/2311","title":"Cloudflare AI Gateway authentication support in cc-switch","quote":"cc-switch currently sends `Authorization: Bearer <key>` for all upstream providers. Cloudflare AI Gateway requires `x-api-key: <anthropic_key>` instead, causing 401 errors when trying to use it as a proxy.","summary":"Concrete Anthropic-native header mismatch and the proposed two-header client behavior.","claim_ids":["c5"]},{"id":"s14","type":"publisher_documentation","url":"https://developers.cloudflare.com/analytics/graphql-api/","title":"Cloudflare GraphQL Analytics API","quote":"The GraphQL Analytics API is the engine that powers all the product analytics on the Cloudflare dashboard.","summary":"The query surface used to read aiGatewayRequestsAdaptiveGroups for request, token, cost, cache, status, and duration measurements.","claim_ids":["c10"]},{"id":"s15","type":"first_party_measurement","url":"https://miscsubjects.com/a/cloudflare-ai-gateway-setup","title":"Gateway latency A/B probe","quote":"median 0.741 s through the gateway against 0.648 s without","summary":"Harness: six curl time_total runs per arm, one model, one prompt, max_tokens 1, cache bypassed; the gateway-id header was the only changed input.","claim_ids":["c13"]},{"id":"s16","type":"first_party_measurement","url":"https://developers.cloudflare.com/api/resources/ai_gateway/methods/create/","title":"Live gateway configuration and 30-day account measurement","quote":"\"rate_limiting_limit\": 120","summary":"Authenticated API read of the measured gateway plus a 30-day GraphQL aggregation: 5,252 account requests, one 429, and gateway-level token and cost totals.","claim_ids":["c1","c10","c12","c8"]},{"id":"s17","type":"first_party_measurement","url":"https://developers.cloudflare.com/ai-gateway/configuration/authentication/","title":"Gateway-host versus REST-host authentication probe","quote":"\"code\":2009,\"message\":\"Unauthorized\"","summary":"Same token, gateway and model tested against both hosts: provider-native host rejected a token without Run while the REST host returned HTTP 200 and logged the request.","claim_ids":["c4"]},{"id":"s18","type":"first_party_measurement","url":"https://developers.cloudflare.com/ai-gateway/features/caching/","title":"Five-request exact-cache probe","quote":"miss, hit, hit, miss, miss","summary":"Five controlled requests showed identical bodies hitting after fill and UUID-bearing variants missing; GraphQL supplied cache truth when the REST response omitted cf-aig-cache-status.","claim_ids":["c7"]},{"id":"s19","type":"hn","url":"https://news.ycombinator.com/item?id=46100225","title":"Comment on AI Gateway setup","quote":"We used cloudflare's AI gateway which is pretty simple. Set one up, get the proxy URL and set it through the env var, very plug-and-play","summary":"Positive operator report that the base-URL setup can be almost frictionless when authentication and provider constraints fit the client.","claim_ids":["c15"]},{"id":"s20","type":"github_issue","url":"https://github.com/cloudflare/ai/issues/476","title":"Custom provider endpoint prepends /v1","quote":"Gateway appears to prepend `/v1` to the upstream path even when the custom provider `base_url` is configured without `/v1`.","summary":"A reproducible custom-provider path mutation and its upstream-observed failure mode.","claim_ids":["c16"]},{"id":"s21","type":"github_issue","url":"https://github.com/cloudflare/ai/issues/617","title":"Dynamic Workers AI route fails on universal endpoint","quote":"A documented `ai-gateway-provider` dynamic route targeting Workers AI fails when it is sent through the AI Gateway universal endpoint.","summary":"A raw-request reproduction showing a dynamic Workers AI route failing on universal while the compatibility endpoint succeeds.","claim_ids":["c17"]}],"anecdotal_sources":[],"scientific_sources":[],"user_reports":[],"related_articles":[],"question_graph":{"slug":"cloudflare-ai-gateway-setup","questions":[],"evidence":[],"edges":[],"counts":{"questions":0,"evidence":0,"edges":0}},"honesty":{"active_claims":17,"retracted_claims":0,"cut_claims":0,"challenges":0,"scrub_events":0,"note":"Retracted/cut claims stay on ledger but are excluded from ask unless ?include_inactive=1"},"counts":{"claims":17,"claims_total":17,"sources":21,"anecdotal":0,"scientific":0,"user_reports":0,"questions":0,"evidence_ingests":0}}