Skip to content

Cloudflare AI Gateway

Cloudflare AI Gateway can proxy https://api.aiand.com as a custom provider. You get Gateway logs, analytics, cache, and rate limits; ai& still bills the sk- key.

ai& is not a native Gateway provider. The URL uses custom-{slug}, not /openai or /aiand.

Create an API key first.

  1. In the Cloudflare dashboard, open AI → AI Gateway → Custom Providers and add a provider:

    • Slug: aiand
    • Base URL: https://api.aiand.com (no trailing slash, no /v1)
    • Enable it
  2. Create a gateway (any name; examples below use aiand-gateway).

  3. Send the ai& key as Authorization: Bearer sk-…. Authenticated Gateway is optional on this path. If it is on, also send cf-aig-authorization with a Cloudflare token that has AI Gateway Run.

  4. Or store the key under Provider Keys (BYOK) and omit Authorization. BYOK needs Authenticated Gateway on, and every request must send cf-aig-authorization. That Cloudflare token is not the sk- key.

The custom-provider form has no key field. That is expected.

Replace ACCOUNT_ID with your Cloudflare account id.

Terminal window
curl https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/custom-aiand/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AIAND_API_KEY" \
-H "cf-aig-authorization: Bearer $CF_AIG_TOKEN" \
-d '{
"model": "openai/gpt-oss-120b",
"messages": [{"role": "user", "content": "Hello"}]
}'

The examples include both headers. Drop cf-aig-authorization only when you send the sk- yourself and Authenticated Gateway is off. Drop Authorization only for BYOK, and keep cf-aig-authorization in that case.

import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AIAND_API_KEY,
baseURL: "https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/custom-aiand/v1",
defaultHeaders: {
"cf-aig-authorization": `Bearer ${process.env.CF_AIG_TOKEN}`,
},
});
const response = await client.chat.completions.create({
model: "openai/gpt-oss-120b",
messages: [{ role: "user", content: "Hello" }],
});

The SDK appends /chat/completions. The gateway then calls https://api.aiand.com/v1/chat/completions. The same baseURL works for /v1/responses, /v1/messages, /v1/models, and /v1/completions.

Terminal window
curl https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/compat/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AIAND_API_KEY" \
-H "cf-aig-authorization: Bearer $CF_AIG_TOKEN" \
-d '{
"model": "custom-aiand/openai/gpt-oss-120b",
"messages": [{"role": "user", "content": "Hello"}]
}'

/compat is chat completions only. Prefer the provider-specific /custom-aiand/v1 path for Responses, Messages, and the catalog.

Turn on Cache Responses in the gateway settings. Identical requests return cf-aig-cache-status: HIT and do not reach ai& (and are not billed). A cache miss is MISS.

The default cache key is an exact match of provider, path, model, auth, and the full JSON body. Bypass with cf-aig-skip-cache: true.

Streaming is not cached by default. Cache Responses covers identical non-streaming text and image requests only. A stream: true call still reaches ai& and is billed.

  • Missing or bad cf-aig-authorization (when auth is on): Cloudflare 401 (AiGatewayError), not an OpenAI error body.
  • Wrong custom slug: Cloudflare 502 (The provider did not return a valid response), not ai&’s 404.
  • Unknown model, bad JSON, empty messages, invalid reasoning_effort, vision on a text-only model: ai&’s usual OpenAI-shaped errors, passed through.

Calling env.AI.run("@cf/…") is Workers AI, a different product. A Worker can call ai& with the OpenAI SDK and baseURL: "https://api.aiand.com/v1" without AI Gateway at all.