All skills
Skillintermediate

GraphQL Analytics API Gotchas & Troubleshooting

| Limit | Value | |-------|-------| | GraphQL queries per user | **Default 300 per 5 minutes** (max 320, at least 1/sec) | | General API rate limit | 1200 requests per 5 minutes (shared across all API calls) | | Zone scope per query | Up to **10 zones** | | Account scope per query | Exactly **1 account** |

Claude Code Knowledge Pack7/10/2026

Overview

GraphQL Analytics API Gotchas & Troubleshooting

Rate Limits

LimitValue
GraphQL queries per userDefault 300 per 5 minutes (max 320, at least 1/sec)
General API rate limit1200 requests per 5 minutes (shared across all API calls)
Zone scope per queryUp to 10 zones
Account scope per queryExactly 1 account

The GraphQL rate limit is separate from the general API limit. Exceeding either results in HTTP 429 and blocks all API calls for 5 minutes. Enterprise customers can contact support to raise limits.

"429 Too Many Requests"

Cause: Exceeded rate limit.

Solution: Batch multiple datasets into single queries, cache results, increase intervals between queries. Use { viewer { budget } } to monitor remaining budget.

Sampling & Data Accuracy

Adaptive Bit Rate (ABR) Sampling

Datasets with Adaptive in the name use adaptive sampling:

  • Results are statistically representative, not exact
  • Same query may return slightly different numbers each run
  • Higher traffic = higher sampling rate = more accurate
  • sampleInterval dimension shows the ratio (1 = no sampling, 10 = ~1-in-10 sampled)

For high-confidence numbers, use confidence(level: 0.95) to get estimate bounds. For exact counts, use rollup nodes (httpRequests1hGroups, httpRequests1dGroups) which are pre-aggregated without sampling.

Rollup vs. Adaptive

FeatureRollup (*1hGroups, *1dGroups)Adaptive (*AdaptiveGroups)
SamplingNo (pre-aggregated)Yes (ABR)
FlexibilityFixed time bucketsAny granularity
DimensionsFewerMany more
AccuracyExactStatistical estimate

Common Errors

"Access denied" / "authentication error"

Cause: Token lacks required permission or wrong scope.

Solution: Account-scoped queries need Account Analytics: Read. Zone-scoped queries need Zone Analytics: Read. Verify: curl -s https://api.cloudflare.com/client/v4/user/tokens/verify -H "Authorization: Bearer $TOKEN"

"field not found" / "Cannot query field"

Cause: Wrong dataset name, nonexistent field, or wrong scope (zone vs. account).

Solution: Names are case-sensitive camelCase (httpRequestsAdaptiveGroups). Zone datasets go under zones(...), account datasets under accounts(...). Use introspection to verify.

"filter is required" / empty results

Cause: Missing required time range filter or incorrect zone/account tag.

Solution: Always include datetime_gt / datetime_lt (or _geq / _leq).

"limit is required" / "limit exceeds maximum"

Cause: Missing limit or exceeding node's max page size.

Solution: Always specify limit. Max varies by dataset (typically 10,000 for groups, 100 for raw events). Check via settings query.

"query is too complex" / "query exceeds budget"

Cause: Too many fields, datasets, or too broad a time range.

Solution: Reduce time range, request fewer dimensions/metrics, break into smaller queries. Monitor cost and budget in responses.

200 Response with Errors

GraphQL returns HTTP 200 even on failures. Always check response.errors:

{ "data": null, "errors": [{ "message": "filter is required for httpRequestsAdaptiveGroups" }] }

Plan-Based Availability

Not all datasets are available on all plans. Higher plans get more datasets, longer retention (notOlderThan), wider time ranges (maxDuration), more fields, and larger page sizes.

"node is not available" / "node is disabled"

Cause: Dataset not on your plan, or product not enabled.

Solution: Check settings { <nodeName> { enabled } }. Some datasets require specific subscriptions (e.g., Network Analytics requires Magic Transit/Spectrum).

DateTime & Timezone Handling

  • All times are UTC only (ISO 8601: "2025-01-15T10:30:00Z")
  • Date type: "2025-01-15" (used in date_geq/date_leq for storage datasets)
  • Time type: "2025-01-15T10:30:00Z" (used in datetime_gt/datetime_lt)
  • Filters are start-inclusive: events that start within the window are included

Performance Tips

  • Narrow time ranges are faster and cheaper
  • Select only needed dimensions — each additional dimension increases cost
  • Use rollup nodes (*1dGroups) for simple daily totals without dimension breakdowns
  • Batch datasets into one query instead of separate HTTP requests

See Also

  • README.md - Overview, decision tree, dataset index
  • api.md - Query structure, aggregation fields, filtering operators
  • configuration.md - Authentication, client setup, introspection queries
  • patterns.md - Common query patterns (time-series, top-N, per-product)