API Integration
Add AI impression 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.
This integration tracks AI Impressions — visits from AI crawlers like GPTBot and ClaudeBot. To also track Clicks (real users arriving from AI answers), add the WordPress plugin or the client-side tracking script from Settings → Tracking Script.
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 |
Pass the visitor's original request headers unchanged. Airefs uses user-agent to identify AI crawlers. 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.