Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/cloudflare-os/llms.txt

Use this file to discover all available pages before exploring further.

Cloudflare OS includes an opt-in billing system that gives every user a free daily AI allowance and — once that runs out — routes further usage through the user’s own Cloudflare account so their credits are billed directly. The platform operator is never charged for funded users. When ENABLE_CLOUDFLARE_LIMITS is unset (the default), all usage is unlimited and no billing logic runs, which is ideal for self-hosted or internal deployments.

How it works

Each user’s AI usage is tracked on their UserDurableObject via a daily counter (consumeDailyLlmCall / checkDailyLlmCount) that resets at midnight UTC. Before every user-initiated agent turn, the overseer calls checkUsageAndBalance to determine how to route the request:

Connected, balance ≥ $2

Routed through the user’s own Cloudflare account. Usage bills their AI Gateway credits. The platform is never charged. The user’s free-tier counter is left untouched.

Within free tier

Routed through the platform’s AI Gateway (CF_AI_GATEWAY). This includes users with a connected account whose balance is below $2.

Free tier exhausted, no account

Blocked. The user sees a prompt to connect their Cloudflare account.

Free tier exhausted, balance < $2

Blocked. The user sees a prompt to add credits to their Cloudflare account.
The credit balance is read live from each user’s Cloudflare AI Gateway billing endpoint (/ai-gateway-billing/credit_balance) and cached for 5 minutes. The platform never holds any money — topping up means adding credits directly in the Cloudflare dashboard.

Connecting Cloudflare

Billing is tied to the Cloudflare gatekeeper. OAuth tokens for accessing the Cloudflare billing API live in the gatekeeper’s connected account, and the billing flow obtains a usable token via getUsableAccessToken(). A user connects Cloudflare in one of two ways:
  1. Sign in with Cloudflare — if cloudflare is in AUTH_GATEKEEPERS, the user can sign in via Cloudflare. After sign-in they’ll be prompted to connect the full gatekeeper to enable billing.
  2. Connect via the Connectors panel — if the user signed in another way, they can connect Cloudflare from the Connections tab using AuthenticatedApi.connectAccount("cloudflare"). This requests the full scopes and persists the connection.
When the OAuth grant has access to exactly one Cloudflare account, billing is auto-configured to that account. If the user has multiple accounts, they are prompted to choose one. Billing is account-level (Unified Billing), and inference is routed through the account’s auto-created default AI Gateway.

Configuration

Enable billing by setting ENABLE_CLOUDFLARE_LIMITS=true along with the AI Gateway variables. Set these in .dev.vars for local development or as wrangler secrets/vars in production.
# .dev.vars — enable billing with free tier + Cloudflare sign-in

ENABLE_CLOUDFLARE_LIMITS=true
PUBLIC_BASE_URL=https://your-host
AUTH_GATEKEEPERS=cloudflare

# Cloudflare gatekeeper OAuth app (client id/secret live on the gatekeeper Worker;
# in local dev these are seeded by run-dev-server.js from these vars):
CLOUDFLARE_OAUTH_CLIENT_ID=...
CLOUDFLARE_OAUTH_CLIENT_SECRET=...

# Platform AI Gateway used for the free tier:
CF_AI_GATEWAY=your-gateway-id
CF_AI_GATEWAY_PROVIDERS=anthropic,openai,google

# Required whenever CF_AI_GATEWAY is set — inference goes over HTTPS with these tokens:
CF_AI_GATEWAY_ACCOUNT_ID=...
CF_AI_GATEWAY_API_TOKEN=...
The CF_AI_GATEWAY_API_TOKEN needs AI Gateway Run and AI Gateway Read permissions. The Run permission lets Gadgets execute models through the gateway; the Read permission lets them retrieve each request’s cost for user-visible accounting. The gateway may live in the worker’s own account or a separate one — the CF_AI_GATEWAY_ACCOUNT_ID specifies which account owns it.
You can also tune the free-tier defaults with these optional variables:
DAILY_LLM_CALL_LIMIT=100       # free LLM calls per user per UTC day (default: 100)
MINIMUM_CLOUDFLARE_BALANCE=2   # minimum balance in USD to use BYOK routing (default: 2)

Workers AI routing options

Workers AI is handled separately from other providers because it can run via a binding (in the wrangler process) or via the REST API (over HTTPS). You have three options:
VariableEffect
CF_AI_GATEWAY (default)Workers AI uses the same gateway ID as other providers.
CF_AI_GATEWAY_WAI=your-wai-gatewayRoute Workers AI through a different AI Gateway in the same account.
CF_AI_GATEWAY_WAI_DIRECT=trueBypass the gateway entirely for Workers AI and call the Workers AI REST endpoint directly using CF_AI_GATEWAY_ACCOUNT_ID / CF_AI_GATEWAY_API_TOKEN. Requests produce no cost logs.
When using CF_AI_GATEWAY* in local development, start the backend with the --use-workers-ai-binding flag so the webFetch tool’s document-to-Markdown conversion still has a WORKERS_AI binding available:
pnpm dev-server -- --use-workers-ai-binding
Inference itself no longer uses the binding when gateway variables are set — it goes over HTTPS with the tokens above — but the binding is still needed by the document conversion helper.

Topping up credits

When a user’s free tier is exhausted and their balance is below $2, they are shown a prompt with a link to add credits. Credits are added directly in the Cloudflare AI Gateway dashboard — the platform never intermediates payments: dash.cloudflare.com → AI → AI Gateway → Credits The balance is cached for 5 minutes on the user’s UserDurableObject, so after a top-up the user may need to wait up to 5 minutes before the new balance is reflected.

Build docs developers (and LLMs) love