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

# Cloudflare

> Receive errors from Cloudflare Workers and Logpush to Squasher.

If you use the Log Connectors screen in Squasher, create the Cloudflare connector first and copy the managed endpoint and ingest key from there. The options below map to the same Squasher ingest paths.

## One-click Workers setup

1. In Squasher, open **Integrations > Cloudflare** and select **Connect**.
2. Approve access to the Cloudflare account.
3. Select the Workers that can send logs and traces.
4. Run the opt-in verification and confirm that a test signal appears.

Squasher creates Workers Observability destinations and adds them to the selected Worker settings. It
keeps existing destinations. New Workers are not included unless you explicitly select account-wide
coverage.

The Cloudflare OAuth application must be active for public connections. It requests account read,
Workers Observability write, and Workers Scripts read/write access. If the application or a required
scope is not available, use the manual OpenTelemetry setup below.

Disconnect removes only the Squasher destinations and Worker setting entries that Squasher owns.

## Cloudflare Workers

### Manual option 1: OpenTelemetry

Cloudflare can [export Worker traces and logs over OTLP](https://developers.cloudflare.com/workers/observability/exporting-opentelemetry-data/). In **Workers Observability > Destinations**, create a trace destination named `squasher-traces` with:

* URL: `https://ingest.squasher.ai/v1/traces`
* Header: `x-squasher-key: sq_pk_your_api_key`

Then enable the destination on the Worker:

```jsonc wrangler.jsonc theme={null}
{
  "observability": {
    "traces": {
      "enabled": true,
      "destinations": ["squasher-traces"],
      "head_sampling_rate": 1,
      "persist": false,
    },
  },
}
```

Cloudflare currently exports Worker traces and logs, but not Worker metrics. Create a separate log destination pointing to `https://ingest.squasher.ai/v1/logs` if you also want `console` output and system logs.

## Cloudflare Agents and AI Gateway

Worker tracing captures requests, Durable Object and service-binding calls, and [custom spans](https://developers.cloudflare.com/workers/observability/traces/custom-spans/). It does not automatically turn Cloudflare Agents SDK diagnostic events into standardized AI observations.

For model calls routed through Cloudflare AI Gateway, add an [AI Gateway OpenTelemetry exporter](https://developers.cloudflare.com/ai-gateway/observability/otel-integration/) with the Squasher traces URL and ingest-key header above. Squasher maps the fields that AI Gateway documents today:

| Exported field                                | Squasher field                      |
| --------------------------------------------- | ----------------------------------- |
| `gen_ai.request.model`                        | Model and generation classification |
| `gen_ai.model.provider`                       | Provider                            |
| `gen_ai.usage.input_tokens` / `output_tokens` | Prompt and completion tokens        |
| `gen_ai.usage.cost`                           | Provider-reported cost              |
| `gen_ai.prompt_json` / `completion_json`      | Generation input and output         |
| `session.id` added through `cf-aig-metadata`  | Session                             |

AI Gateway custom metadata is retained with the observation. Add a stable `session.id` through `cf-aig-metadata` when you want model calls grouped into a conversation. Prompt and completion attributes contain customer content, so only enable this exporter when that retention is intentional.

To classify application-owned tool work, wrap it in a Worker custom span and set `gen_ai.operation.name` to `execute_tool` plus `gen_ai.tool.name`. Nested custom spans retain their OTLP parent/child relationship. Other custom attributes are retained and queryable even when Squasher does not give them a dedicated field.

<Note>
  Cloudflare does not currently document standard OTLP attributes for Agents SDK sub-agent identity
  or approval state. Squasher therefore does not claim automatic sub-agent or approval mapping. If
  you add your own attributes, they are retained as custom evidence rather than reinterpreted.
</Note>

### Option 2: Direct HTTP Reporting

Add error reporting to your Worker:

```typescript theme={null}
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    try {
      return await handleRequest(request, env);
    } catch (error) {
      // Report to Squasher
      await fetch(`https://ingest.squasher.ai/v1/ingest/${env.SQUASHER_PROJECT_ID}`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-squasher-key": env.SQUASHER_API_KEY,
        },
        body: JSON.stringify({
          message: error instanceof Error ? error.message : String(error),
          type: error instanceof Error ? error.constructor.name : "Error",
          level: "error",
          stack: error instanceof Error ? error.stack : undefined,
          tags: {
            url: request.url,
            method: request.method,
            cf_ray: request.headers.get("cf-ray"),
          },
        }),
      });

      return new Response("Internal Server Error", { status: 500 });
    }
  },
};
```

## Cloudflare Logpush

Forward Cloudflare HTTP request logs, firewall events, and Worker logs to Squasher via Logpush.

<Steps>
  <Step title="Create a Logpush job">
    Use the Cloudflare API or dashboard to create a Logpush job:

    ```bash theme={null}
    curl -X POST "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/logpush/jobs" \
      -H "Authorization: Bearer YOUR_CF_API_TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "destination_conf": "https://ingest.squasher.ai/v1/drain/cloudflare/YOUR_PROJECT_ID?header_x-squasher-key=sq_pk_your_api_key",
        "dataset": "http_requests",
        "enabled": true,
        "logpull_options": "fields=ClientIP,ClientRequestHost,ClientRequestMethod,ClientRequestURI,EdgeResponseStatus,EdgeStartTimestamp,RayID&timestamps=rfc3339"
      }'
    ```
  </Step>

  <Step title="Verify">
    Logpush sends NDJSON batches. Check your Squasher dashboard for incoming events.
  </Step>
</Steps>

## What Gets Captured

| Source                      | Error Detection                              |
| --------------------------- | -------------------------------------------- |
| **Workers**                 | Uncaught exceptions, error-level console.log |
| **Logpush HTTP requests**   | Status codes >= 500, WAF blocks              |
| **Logpush firewall events** | All firewall actions (block, challenge)      |

## Agent handoff

```text theme={null}
Set up Cloudflare logs for Squasher project <project_id>. Prefer @squasher-ai/edge for Worker code and managed connector details for Logpush. Verify with one Worker error or Logpush batch, and ask before changing zone-level Logpush jobs.
```
