> ## Documentation Index
> Fetch the complete documentation index at: https://docs.braintrust.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare

> Trace Cloudflare AI Gateway and Workers AI calls, and export Cloudflare Agents traces to Braintrust with OpenTelemetry

Braintrust integrates with Cloudflare in three ways: tracing LLM requests routed through [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/), tracing Clef and Clairic calls on [Workers AI](https://developers.cloudflare.com/workers-ai/) bindings, and exporting traces from [Cloudflare Agents](https://developers.cloudflare.com/agents/) over OpenTelemetry. This page covers all three.

**TypeScript**

## Cloudflare AI Gateway

[Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) provides a unified interface to access multiple AI providers with observability, caching, and rate limiting. Braintrust traces requests routed through Cloudflare AI Gateway across all supported providers.

### Setup

Install the Braintrust SDK alongside the OpenAI client, then configure your environment variables.

**1. Install packages**

```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
pnpm add braintrust openai
```

```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
npm install braintrust openai
```

**2. Set environment variables**

```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
OPENAI_API_KEY=<your-provider-api-key>
CLOUDFLARE_ACCOUNT_ID=<your-cloudflare-account-id>
CLOUDFLARE_AI_GATEWAY_NAME=<your-gateway-name>
BRAINTRUST_API_KEY=<your-braintrust-api-key>
```

### Manual instrumentation

To trace requests routed through Cloudflare AI Gateway, wrap your OpenAI client with `wrapOpenAI` and point it at the gateway's OpenAI-compatible endpoint.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { OpenAI } from "openai";
import { initLogger, wrapOpenAI } from "braintrust";

// Initialize Braintrust logging
initLogger({
  projectName: "My Project",
  apiKey: process.env.BRAINTRUST_API_KEY,
});

// Create OpenAI client configured for Cloudflare AI Gateway
const client = wrapOpenAI(
  new OpenAI({
    // OpenAI SDK automatically adds /chat/completions
    baseURL: `https://gateway.ai.cloudflare.com/v1/${process.env.CLOUDFLARE_ACCOUNT_ID}/${process.env.CLOUDFLARE_AI_GATEWAY_NAME}/compat`,
    apiKey: process.env.OPENAI_API_KEY,
  }),
);

// This request will be automatically traced by Braintrust
const result = await client.chat.completions.create({
  model: "openai/gpt-4o",
  messages: [{ role: "user", content: "What is 1+1?" }],
});

console.log(result);
```

#### Switching providers

Cloudflare AI Gateway's unified API allows you to easily switch between different AI providers by changing the `model` parameter and corresponding API key. All requests are automatically traced by Braintrust regardless of which provider you use.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { OpenAI } from "openai";
import { wrapOpenAI } from "braintrust";

// Switch to Anthropic
const client = wrapOpenAI(
  new OpenAI({
    baseURL: `https://gateway.ai.cloudflare.com/v1/${process.env.CLOUDFLARE_ACCOUNT_ID}/${process.env.CLOUDFLARE_AI_GATEWAY_NAME}/compat`,
    apiKey: process.env.ANTHROPIC_API_KEY, // Use Anthropic's API key
  }),
);

const result = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4-5-20250929", // Use Anthropic model
  messages: [{ role: "user", content: "Hello!" }],
});
```

Cloudflare AI Gateway supports OpenAI, Anthropic, Google AI Studio, Groq, Mistral, Cohere, Perplexity, DeepSeek, Cerebras, xAI, and Workers AI. See the [Cloudflare documentation](https://developers.cloudflare.com/ai-gateway/usage/chat-completion/) for the complete list.

### AI Gateway resources

* [Cloudflare AI Gateway documentation](https://developers.cloudflare.com/ai-gateway/).
* [Supported providers](https://developers.cloudflare.com/ai-gateway/usage/chat-completion/).

## Cloudflare Workers AI

[Workers AI](https://developers.cloudflare.com/workers-ai/) runs models from a Worker through an AI binding. Braintrust v3.40.0+ traces calls to Cloudflare's Clef decision models (`@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash`, and `@cf/cloudflare/clef-omni`) and the Clairic extraction model (`@cf/cloudflare/clairic`).

### Setup

Install the Braintrust SDK in your Worker project, then configure the Worker and add your Braintrust API key.

**1. Install packages**

```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
pnpm add braintrust
```

```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
npm install braintrust
```

**2. Configure the Worker**

In your Worker's `wrangler.jsonc`, add a Workers AI binding named `AI` and enable the `nodejs_compat` compatibility flag, which the Braintrust SDK needs for the Node.js `AsyncLocalStorage` API:

```json title="wrangler.jsonc" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "compatibility_flags": ["nodejs_compat"],
  "ai": {
    "binding": "AI"
  }
}
```

**3. Add your Braintrust API key**

Store your Braintrust API key as a Worker secret named `BRAINTRUST_API_KEY`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
npx wrangler secret put BRAINTRUST_API_KEY
```

### Manual instrumentation

To trace Workers AI calls, wrap the AI binding with `wrapWorkersAI()` and call `run()` on the wrapped binding. `wrapWorkersAI()` traces Clef and Clairic calls that return a JSON result. Calls to other models, and calls that stream, return a raw response, use a WebSocket, or queue the request, pass through unchanged.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { initLogger, wrapWorkersAI } from "braintrust";

interface Env {
  AI: Ai;
  BRAINTRUST_API_KEY: string;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext,
  ): Promise<Response> {
    const logger = initLogger({
      projectName: "My Project", // Replace with your project name
      apiKey: env.BRAINTRUST_API_KEY,
    });

    const ai = wrapWorkersAI(env.AI);

    try {
      const result = await ai.run("@cf/cloudflare/clef-flash", {
        model: "clef-flash",
        state: "Checkout has failed for every customer for an hour.",
        questions: {
          urgent: { type: "noul", instructions: "Is this urgent?" },
        },
      });
      return Response.json(result);
    } finally {
      ctx.waitUntil(logger.flush());
    }
  },
};
```

Passing `logger.flush()` to `ctx.waitUntil()` sends the trace after the response returns. See the [Cloudflare Workers setup guide](https://docs.braintrust.dev/sdks/typescript/install-and-instrument.md#cloudflare) for the full deployment configuration.

### What Braintrust traces

Braintrust records each traced call as a `workers_ai.run` span:

* Decision spans (`workers_ai.run`) for Clef calls, with the state and each question's ID, type, instructions, and criteria as input, and the list of answers, each with its question ID, as output.
* Extraction spans (`workers_ai.run`) for Clairic calls, with the state, each field's ID and settings, the reference date, and options as input, and each field's extracted value and confidence details as output.
* Model, provider (`cloudflare`), and operation (`decision` or `extraction`) in metadata.
* Token usage metrics (prompt, completion, and total) when Workers AI reports them.
* Base64 images, audio, and video in the input, stored as attachments when `BRAINTRUST_CAPTURE_ATTACHMENTS` is enabled and recorded as `<omitted>` otherwise.

### Workers AI resources

* [Workers AI documentation](https://developers.cloudflare.com/workers-ai/).
* [Workers AI bindings](https://developers.cloudflare.com/workers-ai/configuration/bindings/).

**Python**

## Cloudflare AI Gateway

[Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) provides a unified interface to access multiple AI providers with observability, caching, and rate limiting. Braintrust traces requests routed through Cloudflare AI Gateway across all supported providers.

### Setup

Install the Braintrust SDK alongside the OpenAI client, then configure your environment variables.

**1. Install packages**

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
pip install braintrust openai
```

**2. Set environment variables**

```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
OPENAI_API_KEY=<your-provider-api-key>
CLOUDFLARE_ACCOUNT_ID=<your-cloudflare-account-id>
CLOUDFLARE_AI_GATEWAY_NAME=<your-gateway-name>
BRAINTRUST_API_KEY=<your-braintrust-api-key>
```

### Manual instrumentation

To trace requests routed through Cloudflare AI Gateway, wrap your OpenAI client with `wrap_openai` and point it at the gateway's OpenAI-compatible endpoint.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import os
import openai
from braintrust import init_logger, wrap_openai

# Initialize Braintrust logging
logger = init_logger(project="My Project")

# Create OpenAI client configured for Cloudflare AI Gateway
client = wrap_openai(
    # OpenAI client automatically adds /chat/completions
    openai.OpenAI(
        base_url=f"https://gateway.ai.cloudflare.com/v1/{os.getenv('CLOUDFLARE_ACCOUNT_ID')}/{os.getenv('CLOUDFLARE_AI_GATEWAY_NAME')}/compat",
        api_key=os.getenv("OPENAI_API_KEY"),
    )
)

# This request will be automatically traced by Braintrust
result = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "What is 1+1?"}],
)

print(result)
```

#### Switching providers

Cloudflare AI Gateway's unified API allows you to easily switch between different AI providers by changing the `model` parameter and corresponding API key. All requests are automatically traced by Braintrust regardless of which provider you use.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import os
import openai
from braintrust import wrap_openai

# Switch to Anthropic
client = wrap_openai(
    openai.OpenAI(
        base_url=f"https://gateway.ai.cloudflare.com/v1/{os.getenv('CLOUDFLARE_ACCOUNT_ID')}/{os.getenv('CLOUDFLARE_AI_GATEWAY_NAME')}/compat",
        api_key=os.getenv("ANTHROPIC_API_KEY"),  # Use Anthropic's API key
    )
)

result = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-5-20250929",  # Use Anthropic model
    messages=[{"role": "user", "content": "Hello!"}],
)
```

Cloudflare AI Gateway supports OpenAI, Anthropic, Google AI Studio, Groq, Mistral, Cohere, Perplexity, DeepSeek, Cerebras, xAI, and Workers AI. See the [Cloudflare documentation](https://developers.cloudflare.com/ai-gateway/usage/chat-completion/) for the complete list.

### AI Gateway resources

* [Cloudflare AI Gateway documentation](https://developers.cloudflare.com/ai-gateway/).
* [Supported providers](https://developers.cloudflare.com/ai-gateway/usage/chat-completion/).

## Cloudflare Agents

[Cloudflare Agents](https://developers.cloudflare.com/agents/) instrument each agent run with OpenTelemetry spans that follow the [GenAI semantic conventions](https://github.com/open-telemetry/semantic-conventions-genai/blob/main/docs/gen-ai/gen-ai-spans.md). Because Braintrust ingests OpenTelemetry data, you can export these spans to Braintrust from Cloudflare's [Workers Observability](https://developers.cloudflare.com/workers/observability/exporting-opentelemetry-data/) without adding the Braintrust SDK to your Worker. Braintrust maps the incoming spans to `LLM` and tool spans automatically.

**1. Get your Braintrust credentials**

Create an API key in \*\* Settings > [ API keys](https://www.braintrust.dev/app/~/configuration/api-keys)\*\*. Find your project ID using the **Copy project ID** button at the bottom of the project's configuration page.

**2. Add a tracing destination in Cloudflare**

In the Cloudflare dashboard, go to your account's **Workers Observability** section and add a destination pointing at Braintrust's OpenTelemetry endpoint. Name it `braintrust` so you can reference it in the next step:

* **Name**: `braintrust`.
* **OTLP endpoint**: `https://api.braintrust.dev/otel/v1/traces`.
* **Custom headers**:
  * `Authorization`: `Bearer <BRAINTRUST_API_KEY>`.
  * `x-bt-parent`: `project_id:<BRAINTRUST_PROJECT_ID>`.

The `x-bt-parent` header sets the project or experiment that receives the traces. For other parent formats and the full attribute mapping, see the [OpenTelemetry integration](https://docs.braintrust.dev/integrations/sdk-integrations/opentelemetry/send-traces-and-logs.md#send-traces).

> [!NOTE]
>
> If your organization is on the EU data plane, use `https://api-eu.braintrust.dev/otel/v1/traces` instead. Self-hosted deployments should use their stack's API URL followed by `/otel/v1/traces`. See [Data plane region](https://docs.braintrust.dev/admin/organizations.md#data-plane-region).

**3. Enable trace export in wrangler**

In your Worker's `wrangler.jsonc`, enable trace export and reference the `braintrust` destination you created by name:

```json title="wrangler.jsonc" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
{
  "observability": {
    "traces": {
      "enabled": true,
      "destinations": ["braintrust"]
    }
  }
}
```

Deploy your Worker. Agent runs now appear as traces in Braintrust.

### Cloudflare Agents resources

* [Cloudflare Agents tracing](https://developers.cloudflare.com/agents/runtime/operations/observability/tracing/#exporting-traces).
* [Exporting OpenTelemetry data from Workers](https://developers.cloudflare.com/workers/observability/exporting-opentelemetry-data/).
* [Braintrust OpenTelemetry integration](https://docs.braintrust.dev/integrations/sdk-integrations/opentelemetry/send-traces-and-logs.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.