Skip to content
Cloudflare Integration

Cloudflare Integration

Track AI crawler visits on any site behind Cloudflare — with a lightweight Worker on any plan, or zero-code Logpush on Enterprise.

Updated
Ask AI
View as Markdown

Both options capture every request at the Cloudflare edge and forward it to Airefs, where bot traffic is classified and assets and errors are dropped server-side. They power AI Impressions; to also track Clicks, add the client-side tracking script from Site Settings → Tracking Script.

Your access token is in your Airefs account under Site Settings → Access Token.

Option A: Cloudflare Worker (any plan)

A passthrough Worker that returns your pages untouched and reports each request to Airefs in the background with ctx.waitUntil — it adds no latency for visitors or crawlers.

  1. In the Cloudflare dashboard, go to Workers & Pages → Create and create a Worker from the Hello World template.
  2. Replace the generated code with:
// @ts-check

/**
 * @typedef {{ AIREFS_ACCESS_TOKEN: string }} Env
 * @typedef {Request & { cf?: { country?: string } }} WorkerRequest
 * @typedef {{ waitUntil(promise: Promise<unknown>): void }} ExecutionContext
 */

const AIREFS_LOG_ENDPOINT = "https://api.getairefs.com/v1/logs/http";

/**
 * @param {WorkerRequest} request
 * @param {Response} response
 * @param {Env} env
 */
async function forwardLogRecord(request, response, env) {
  const eventId = request.headers.get("cf-ray");
  if (!eventId) {
    return;
  }

  const url = new URL(request.url);
  const record = {
    event_id: eventId,
    timestamp: new Date().toISOString(),
    status_code: response.status,
    request_method: request.method,
    request_path: url.pathname,
    query_string: url.search.slice(1) || undefined,
    hostname: url.hostname,
    content_type: response.headers.get("content-type")?.split(";")[0] ?? undefined,
    client_ip: request.headers.get("cf-connecting-ip") ?? undefined,
    user_agent: request.headers.get("user-agent") ?? undefined,
    referrer: request.headers.get("referer") ?? undefined,
    country_code: request.cf?.country,
    event_client: "cloudflare-worker@1.0.0",
  };

  await fetch(AIREFS_LOG_ENDPOINT, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": env.AIREFS_ACCESS_TOKEN,
    },
    body: JSON.stringify(record),
  });
}

export default {
  /**
   * @param {WorkerRequest} request
   * @param {Env} env
   * @param {ExecutionContext} ctx
   */
  async fetch(request, env, ctx) {
    const response = await fetch(request);
    ctx.waitUntil(forwardLogRecord(request, response, env).catch(() => {}));
    return response;
  },
};
  1. Deploy, then open the Worker’s Settings → Variables and Secrets and add a secret named AIREFS_ACCESS_TOKEN with your access token.
  2. Add a route so the Worker runs on your domain: your zone → Workers Routes → Add route, pattern yourdomain.com/*, select the Worker.
  3. Make sure the DNS record for your domain is Proxied (orange cloud) — Workers only run on proxied traffic.

Do not pre-filter anything in the Worker: send all traffic so Airefs can classify bots versus humans and drop assets and error responses server-side.

Option B: Logpush (Enterprise)

On a Cloudflare Enterprise zone, Logpush streams HTTP request logs to Airefs with no code at all.

  1. In your zone, go to Analytics & Logs → Logpush and create a job with the HTTP destination type.
  2. Set the destination URL (the header is URL-encoded into it):
https://api.getairefs.com/v1/logs/cloudflare?header_Authorization=Bearer%20YOUR_ACCESS_TOKEN
  1. Dataset: HTTP requests. Choose Filtered logs and filter ClientRequestHost equals your domain.
  2. Select these fields: ClientIP, ClientRequestHost, ClientRequestMethod, ClientRequestReferer, ClientRequestScheme, ClientRequestURI, ClientRequestUserAgent, RayID, EdgeStartTimestamp, EdgeResponseStatus, EdgeResponseContentType, ClientCountry.

  3. Create the job. Cloudflare validates the destination with a test upload; a wrong token makes validation fail with a 401.

Verification

Visit a few pages on your site. Events appear in your Airefs dashboard within a few minutes (Logpush batches roughly once per minute).

Outside dry-run mode, a successful response means Airefs stored every accepted record and reports why the rest were dropped. For a one-off test before going live, POST a sample record with ?dry_run=1 appended to the endpoint URL: Airefs returns a per-record verdict, including the bot classification it detected, without storing anything.

No events? For the Worker: confirm the route pattern matches your domain, the DNS record is proxied, and the AIREFS_ACCESS_TOKEN secret is set. For Logpush: check the destination URL is exactly as shown with Bearer%20 URL-encoded. Need help? Email support@getairefs.com.