API Integration

Add AI impression and click tracking to any website or framework with a single server-side API call.

Send a POST request to the Airefs events endpoint on each page visit. It needs to run server-side — not in the browser — so AI crawlers are captured even when they don't execute JavaScript. The call is fire-and-forget: don't await it in your critical path, and swallow any errors silently so a tracking failure never affects your users.

Your API key is in your Airefs account under Settings → Tracking.

The request

POST https://api.getairefs.com/v1/events
Authorization: Bearer <your-api-key>
Content-Type: application/json

The request body takes three fields:

Field Type Description
name string Your site name (e.g. "mysite.com")
url string Full URL of the page visited
headers object The incoming request headers — used to identify AI crawlers and human referrals from AI answers

Pass the visitor's original request headers unchanged. Airefs uses user-agent to identify AI crawlers and referer to detect human clicks from AI answers. The API returns 200 on success, 401 for an invalid key, and 400 for a malformed body.

Examples

curl

curl -X POST https://api.getairefs.com/v1/events \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mysite.com",
    "url": "https://mysite.com/blog/post",
    "headers": {
      "user-agent": "Mozilla/5.0 ...",
      "referer": "https://chatgpt.com/"
    }
  }'

Node.js

async function trackPageView(req) {
  const headers = Object.fromEntries(req.headers.entries());
  fetch('https://api.getairefs.com/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <your-api-key>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'mysite.com',
      url: req.url,
      headers,
    }),
  }).catch(() => {});
}

Express.js

app.use((req, res, next) => {
  fetch('https://api.getairefs.com/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <your-api-key>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'mysite.com',
      url: `https://mysite.com${req.url}`,
      headers: req.headers,
    }),
  }).catch(() => {});
  next();
});

Next.js middleware

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const headers = Object.fromEntries(request.headers.entries());
  fetch('https://api.getairefs.com/v1/events', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <your-api-key>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      name: 'mysite.com',
      url: request.url,
      headers,
    }),
  }).catch(() => {});
  return NextResponse.next();
}

Cloudflare Workers

export default {
  async fetch(request, env, ctx) {
    const headers = Object.fromEntries(request.headers.entries());
    ctx.waitUntil(
      fetch('https://api.getairefs.com/v1/events', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${env.AIREFS_API_KEY}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          name: 'mysite.com',
          url: request.url,
          headers,
        }),
      })
    );
    return fetch(request);
  },
}

Python (FastAPI)

@app.middleware("http")
async def track_pageview(request: Request, call_next):
    asyncio.create_task(
        httpx.AsyncClient().post(
            "https://api.getairefs.com/v1/events",
            headers={
                "Authorization": "Bearer <your-api-key>",
                "Content-Type": "application/json",
            },
            json={
                "name": "mysite.com",
                "url": str(request.url),
                "headers": dict(request.headers),
            },
        )
    )
    return await call_next(request)

Python (Flask)

@app.before_request
def track_pageview():
    data = {
        "name": "mysite.com",
        "url": request.url,
        "headers": dict(request.headers),
    }
    thread = threading.Thread(
        target=requests.post,
        args=("https://api.getairefs.com/v1/events",),
        kwargs={
            "json": data,
            "headers": {
                "Authorization": "Bearer <your-api-key>",
            },
        }
    )
    thread.daemon = True
    thread.start()

Django middleware

class AirefsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        thread = threading.Thread(
            target=requests.post,
            args=("https://api.getairefs.com/v1/events",),
            kwargs={
                "json": {
                    "name": "mysite.com",
                    "url": request.build_absolute_uri(),
                    "headers": dict(request.headers),
                },
                "headers": {
                    "Authorization": "Bearer <your-api-key>",
                },
            }
        )
        thread.daemon = True
        thread.start()
        return self.get_response(request)

Security

Store your API key as an environment variable — never hardcode it in source files or commit it to version control. Airefs doesn't store full visitor header payloads, only what's needed to classify the visit. No cookies are set and no personal data is collected, so this integration doesn't require a consent banner under GDPR or CCPA.

On WordPress? Use the WordPress plugin instead — it handles all of this automatically.