Most teams stop at the Cloudflare UI. But the real power is in the API. Here's what becomes possible when you query it directly — batched, real-time, across 100+ zones at once.
If you run a large estate on Cloudflare — dozens of zones, multiple teams, production and non-production environments — the Cloudflare dashboard starts to break down. It is designed for a single zone, not a portfolio.
Here is what the status quo looks like in practice:
This is not a workflow problem. It is a data access problem. All of that information exists — Cloudflare stores it — but it is locked behind a UI built for one zone at a time.
I built FlareSight to solve this. It is an open-source React dashboard that queries the Cloudflare GraphQL Analytics API in batches, processes the data client-side, and surfaces everything across your entire zone portfolio in a single view.
Most engineers know Cloudflare has a REST API. Fewer know about the GraphQL Analytics API at /client/v4/graphql. It is a different surface entirely, and it is the right tool for analytics workloads.
Here are the datasets it exposes that power FlareSight:
| Dataset | What it contains | Limit |
|---|---|---|
httpRequests1dGroups | Daily traffic: requests, cached requests, bytes, cached bytes, page views — per zone | 30 days |
httpRequests1hGroups | Hourly traffic broken down by datetime — for trend charts | 72 hours |
httpRequestsAdaptiveGroups | Request-level data with country, response status, HTTP method, bot score dimensions | 10,000 rows |
firewallEventsAdaptiveGroups | WAF and firewall events: action (block/challenge/log), source, rule ID, client IP, ASN, country, user agent | 10,000 rows |
The key insight is the zoneTag_in filter — you can pass an array of zone IDs and get data for all of them in one query. That is what makes a portfolio-wide dashboard feasible.
Cloudflare caps the zoneTag_in array at 10 zones per request. If you have 100 zones, you need 10 batched requests. Here is the exact pattern FlareSight uses:
// Split zone IDs into chunks of 10
const batchZones = (zoneIds) => {
const batches = [];
for (let i = 0; i < zoneIds.length; i += 10) {
batches.push(zoneIds.slice(i, i + 10));
}
return batches;
};
// Execute batches sequentially with 250ms spacing
// to stay under the rate limit (4 req/sec)
for (const batch of batches) {
const data = await graphqlRequest(query, { zoneIds: batch, start, end });
allResults.push(...data.viewer.zones);
await sleep(250);
}
With this pattern, 100 zones load in roughly 10 sequential requests — about 3–4 seconds. The rate limiter prevents 429s, and a 2-minute in-memory cache means subsequent navigations are instant.
Here is the actual query that powers the Zone Portfolio and Performance modules — pulling 30 days of daily traffic with cache metrics for a batch of zones:
query ($zoneIds: [String!], $start: Date!, $end: Date!) {
viewer {
zones(filter: { zoneTag_in: $zoneIds }) {
zoneTag
httpRequests1dGroups(
limit: 30
filter: { date_geq: $start, date_leq: $end }
orderBy: [date_ASC]
) {
sum {
requests
cachedRequests
bytes
cachedBytes
pageViews
}
dimensions {
date
}
}
}
}
}
From requests and cachedRequests alone you get cache hit rate. From bytes and cachedBytes you get bandwidth savings. From requests - pageViews you get API traffic ratio — the split between human and machine traffic, with no extra query.
The security and threat modules use firewallEventsAdaptiveGroups combined with httpRequestsAdaptiveGroups. The critical thing most implementations miss: WAF events only capture traffic that triggered a firewall rule. Organic attacks — credential stuffing against your login endpoint, reconnaissance scanning 404s, API abuse returning 401s — come from httpRequestsAdaptiveGroups filtered on edgeResponseStatus_geq: 400.
FlareSight merges both datasets into unified attack instances:
// Dataset 1: WAF-triggered events
firewallEventsAdaptiveGroups(
limit: 10000
filter: { datetime_geq: $since }
) {
count
dimensions {
action # block / challenge / log
source # waf / rateLimit / firewallRules
ruleId
clientIP
clientAsn
clientCountryName
clientRequestPath
edgeResponseStatus
userAgent
}
}
// Dataset 2: HTTP errors (organic attacks, no WAF trigger)
httpRequestsAdaptiveGroups(
limit: 10000
filter: {
datetime_geq: $since
edgeResponseStatus_geq: 400
}
) {
count
dimensions {
clientIP
clientCountryName
edgeResponseStatus
clientRequestPath
}
}
The merged data then feeds a classifier that maps raw rule IDs and behaviour patterns into named attack categories: SQL Injection, XSS, DDoS (L7), Credential Stuffing, Reconnaissance Scanning, API Abuse, Content Scraping. No external threat intel service required — just pattern matching on what Cloudflare already gives you.
Seven intelligence modules, all driven by the API calls described above:
Every zone gets auto-graded A–F on cache efficiency. "Zombie" zones — zero traffic for 30+ days — are flagged automatically. Zones with low cache offload that are silently driving up your origin egress costs are highlighted with estimated monthly impact.
7-day trend charts of cache hit rate and bandwidth savings per zone. The grading engine uses industry benchmarks: above 85% cache hit rate is an A, below 40% is an F. Per-zone recommendations (e.g. "Enable Tiered Cache", "Tune Browser TTL") are generated from the same data — no separate API call needed.
This module uses the Cloudflare REST Zone Settings API (not GraphQL) to check SSL/TLS mode, HSTS, WAF status, and Bot Fight Mode per zone. Every zone gets a 0–100 security score. The result is a filterable table you can export to CSV — ready for an auditor or a security review.
Real-time WAF block and challenge events across all zones. Block vs. managed challenge vs. log breakdown. Rule effectiveness ranking — which WAF rules are firing most frequently across your entire portfolio. Per-zone threat severity scoring with a searchable table.
The campaign analysis engine groups raw events by source IP and behaviour, then classifies them. It surfaces top malicious ASNs, targeted endpoints, and attack method breakdown. A webhook payload builder generates structured JSON for SOC integrations (Slack, PagerDuty, SIEM) directly from the UI.
Computes estimated annual bandwidth egress savings at $85/TB based on actual cached bytes from the API. Cache hit rate, cached bandwidth in TB, and CPU offload savings are surfaced as top-line KPIs — the kind of numbers that matter to an executive, derived entirely from cachedBytes in the GraphQL response.
The Cloudflare GraphQL API has a hard limit: 30 days of daily-granularity data, and 72 hours of hourly data. Trend charts, campaign history, and period-over-period comparisons are all bounded by this window.
Today FlareSight works around this with browser localStorage — every time the dashboard loads, it snapshots the current campaign data and stores it locally. This gives a rolling 30-day history of attack campaigns on that machine, with no backend database. It is a pragmatic solution. It is also an obvious ceiling.
The simplest upgrade: a Node.js cron job runs every hour, calls the GraphQL API for all zones, and writes the results to Redis with a time-series key structure. The dashboard queries Redis instead of Cloudflare directly. You gain:
For deeper analytics: store every daily snapshot in Postgres with TimescaleDB. This enables SQL aggregations over arbitrary date ranges, per-zone regression analysis, and scheduled PDF reports generated server-side. Traffic anomaly detection becomes trivial — a simple query comparing last week's p95 to the current hourly rate.
The most elegant path for teams already on Cloudflare: deploy a Worker on a cron trigger that writes zone snapshots to D1 (Cloudflare's serverless SQLite). The dashboard queries the Worker instead of the GraphQL API directly. Zero infrastructure, zero operational overhead — and the Worker runs at the edge, so the latency to the Cloudflare API is minimal. This is the direction FlareSight will move.
Once data is in a persistent store, alerting becomes straightforward. A spike in firewallEventsAdaptiveGroups beyond a configurable threshold triggers a Slack webhook. A zone dropping below 60% cache hit rate sends a PagerDuty alert. Traffic anomaly detection without a third-party observability platform.
Most teams interact with Cloudflare through the dashboard or Terraform. The API surface is far richer than most people realise:
| API Surface | What you can build with it |
|---|---|
| GraphQL Analytics API | Traffic analytics, WAF events, bot scores, cache metrics — all queryable in batch |
| Zone Settings REST API | Compliance audits, drift detection, automated remediation |
| Firewall Rules API | Programmatic WAF rule management, rule effectiveness analysis |
| Logpush API | Stream raw logs to S3/R2/BigQuery for unlimited retention and custom analytics |
| Workers Analytics Engine | Custom metrics emitted from Workers, queryable via SQL — build your own datasets |
| Radar API | Internet-wide threat intelligence — BGP route leaks, DDoS attack trends, top attack origins globally |
FlareSight only uses the first two. Logpush alone would eliminate the 30-day analytics window entirely by streaming every HTTP request to a data store you control. Workers Analytics Engine would let you emit custom business metrics — revenue per zone, SLA breach events, conversion rates by CDN PoP — and query them with the same GraphQL interface.
The platform is genuinely more powerful than it is given credit for. The dashboard is a consumer product. The API is an enterprise data platform.
To run it locally you need a Cloudflare API token with Analytics:Read, Firewall Services:Read, and Zone:Read scopes. The backend is a thin Node.js CORS proxy — it never stores credentials. Everything else runs in the browser.
The codebase is structured so the Cloudflare API layer is entirely isolated in src/api/cloudflare/. Swapping in a Redis-backed persistence layer or connecting to Logpush is a matter of replacing the API module without touching any of the processing or UI code.
firewallEventsAdaptiveGroups with httpRequestsAdaptiveGroups for HTTP error codes gives you a far more complete picture of what is actually attacking your zones than WAF events alone.FlareSight is built with React 19, Vite 7, Tailwind CSS, and Recharts. The Cloudflare GraphQL Analytics API is available on all plan tiers; Enterprise plans unlock higher row limits and Bot Management score dimensions. All code referenced in this article is available in the open-source repository.