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

# Cloudflare Agents integration

> Connect Cloudflare Agents to Toqan Router's AI Gateway for routing across providers, and export Workers traces and logs to Toqan Router over OpenTelemetry.

> [card] [AI Gateway](#ai-gateway)
>
> Route agent model calls through the **AI Gateway** with a single base URL change. Zero vendor lock-in: always run on the best model at the lowest cost for the workload.

> [card] [Observability](#observability)
>
> Export the traces and logs Workers emit to **Toqan Router** over OpenTelemetry, straight from the Workers runtime.

## AI Gateway

### Overview

[Cloudflare Agents](https://developers.cloudflare.com/agents/) run on Workers and Durable Objects, and call models through the [AI SDK](https://ai-sdk.dev/docs/introduction). Pointing that provider at **Toqan Router**'s **AI Gateway** sends every model call that uses it through the gateway, so routing, fallbacks, and cost tracking apply to those calls. Calls that read the Workers AI binding directly keep going to Cloudflare.

### Key Benefits

Connecting Cloudflare Agents to **Toqan Router**'s **AI Gateway** adds:

> [card] Complete Observability
>
> Track model calls and their token usage with detailed traces and analytics

> [card] Built-in Reliability
>
> Automatic fallbacks, retries, and load balancing for production resilience

> [card] Cost Optimization
>
> Real-time cost tracking and spend management across every AI operation

> [card] Multi-Provider Access
>
> Access 500+ LLMs and 30+ providers through a single, unified integration

### Prerequisites

Before integrating Cloudflare Agents with **Toqan Router**, confirm:

* A **Toqan Router** account and API Key
* A Cloudflare account with a Worker created from the [Cloudflare Agents](https://developers.cloudflare.com/agents/) starter
* `wrangler` installed and authenticated

### Installation

Install the Agents SDK and the AI SDK with the OpenAI-compatible provider:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
npm install agents ai @ai-sdk/openai @cloudflare/ai-chat
```

Store the **Toqan Router** API key as a Worker secret:

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

### Configure the Gateway

Create the provider once and pass it the gateway base URL. `this.env` carries the secret stored above:

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { createOpenAI } from "@ai-sdk/openai";

export interface Env {
  TOQAN_API_KEY: string;
}

export const gateway = ({ TOQAN_API_KEY }: Env) =>
  createOpenAI({
    baseURL: "https://router.toqan.ai/eu/v3/router",
    apiKey: TOQAN_API_KEY,
  });
```

> **baseURL**: `https://router.toqan.ai/eu/v3/router`

### Basic Agent Example

Every model call in an `Agent` subclass goes through the gateway with that provider:

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { Agent } from "agents";
import { generateText } from "ai";

import { gateway, type Env } from "./gateway";

export class Assistant extends Agent<Env> {
  async onRequest(request: Request): Promise<Response> {
    const prompt = new URL(request.url).searchParams.get("prompt") ?? "Explain quantum computing in simple terms.";
    const toqan = gateway(this.env);

    const { text } = await generateText({
      model: toqan("openai/gpt-5.6-sol"),
      prompt,
    });

    return Response.json({ text });
  }
}
```

For a streaming chat agent, the starter's `AIChatAgent` takes the same provider in `onChatMessage`:

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { AIChatAgent } from "@cloudflare/ai-chat";
import { convertToModelMessages, streamText } from "ai";

import { gateway } from "./gateway";

export class ChatAgent extends AIChatAgent {
  async onChatMessage() {
    const result = streamText({
      model: gateway(this.env)("openai/gpt-5.6-sol"),
      messages: await convertToModelMessages(this.messages),
    });

    return result.toUIMessageStreamResponse();
  }
}
```

### Model Selection

With **Toqan Router**, use any supported model from 30+ providers by changing the model id:

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { generateText } from "ai";

import { gateway, type Env } from "./gateway";

// Swap the model id for any provider in the catalog:
// anthropic/claude-sonnet-5, google/gemini-2.5-pro, openai/gpt-5.6-luna
export async function ask(env: Env, modelId: string, prompt: string) {
  const toqan = gateway(env);

  const { text } = await generateText({
    model: toqan(modelId),
    prompt,
  });

  return text;
}
```

See [Supported Models](/docs/ai-gateway/supported-models.md) for the catalog.

## Observability

### Getting Started

Cloudflare exports Workers telemetry to any OpenTelemetry-compliant destination, and **Toqan Router** is one of them, so traces and logs arrive from the Workers runtime itself.

### Create the destination

Cloudflare keeps destinations at the account level, so the same destination serves every Worker in the account.

1. In the Cloudflare dashboard, open **Observability** > **Destinations** and select **Add destination**.
2. Name the destination, for example `toqan-traces`, and set **Destination type** to **Traces**.
3. Set **OTLP endpoint** to `https://router.toqan.ai/eu/v2/otel/v1/traces`.
4. Add an **Authorization** entry under **Custom headers** with the value `Bearer <TOQAN_API_KEY>`.
5. Save, then repeat with the name `toqan-logs`, the type **Logs**, and the endpoint `https://router.toqan.ai/eu/v2/otel/v1/logs`.

Both destinations use the same header, and the exporter accepts the base path or the full path. See the [Observability quickstart](/docs/ai-studio/observability/quickstart.md) for the general OTLP contract and [Base URLs](/docs/reference/base-urls.md) for self-hosted deployments.

### Reference the destination in Wrangler

Name the destinations in the Worker configuration, then redeploy:

```json wrangler.jsonc theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "observability": {
    "traces": {
      "enabled": true,
      "destinations": ["toqan-traces"],
      "head_sampling_rate": 1,
      "persist": false
    },
    "logs": {
      "enabled": true,
      "destinations": ["toqan-logs"],
      "head_sampling_rate": 1,
      "persist": false
    }
  }
}
```

* **Sample rate**: `head_sampling_rate` is the share of requests exported, from `0` to `1`. Lower it on high-volume Workers.
* **Persist**: `persist` keeps a copy in Cloudflare as well. Persisted traces and logs count toward Cloudflare Observability usage from 1 December 2026, so the value above exports to **Toqan Router** alone.

Events can take several minutes to reach the destination after the first deploy.

### View Traces

Open **Traces** for the path each request takes through the Worker and its connected services, and **Logs** for the `console.log` output the Worker emits. Model calls are recorded by the gateway, so they appear in the trace of the request that made them.

> [card] [Traces](/docs/ai-studio/observability/traces.md)
>
> See each request through the Worker and the services it calls.

> [card] [Logs](/docs/ai-studio/observability/logs.md)
>
> Search the `console.log` output a Worker emits during a run.


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