Get the traffic summary for a time range
Returns request, byte, status class, latency and geo event totals for the range. With comparePrevious it adds the period of the same length that ends just before startDate, which stays null unless the range and that period each have requests or geo events. Ranges over 24 hours read the hourly aggregates, or the daily ones above 30 days. Those reads count whole hours or UTC days, from the one that holds startDate through the last one that starts before endDate. The unique IP and country counts are then estimates, and /api/v1/analytics/live-summary gives exact figures.
session<token>Session cookie authentication.
startDate?|Start of the range, inclusive, as ISO 8601 with a timezone, such as 2026-11-01T00:00:00Z. Requires endDate; omit with window.
endDate?|End of the range, exclusive, as ISO 8601 with a timezone, such as 2026-11-02T00:00:00Z. Requires startDate; omit with window.
window?|A rolling window ending now, such as 15m, 24h or 7d, up to 365 days. Use positive whole minutes, hours or days. Cannot be combined with explicit time bounds.
comparePrevious?booleanAlso return the period of the same length just before the range, and the percent change from it. Defaults to false.
falseRequest fulfilled, document follows
application/json- response
Totals for a time range, and optionally for the period of the same length before it.
currentPeriod*Request and geo event totals for one period.
Request times are in seconds over the requests timedRequests counts, and null when it is 0.
endDate*stringThe request's endDate, echoed as ISO 8601.
percentChanges?|Null whenever previousPeriod is null.
previousPeriod?|Null unless comparePrevious is true and the range and the previous period each have requests or geo events.
startDate*stringThe request's startDate, echoed as ISO 8601.
curl -X GET 'https://geometrikks.example.com/api/v1/analytics/summary?startDate=2026-11-01T00%3A00%3A00Z&endDate=2026-11-02T00%3A00%3A00Z'{ "currentPeriod": { "avgBytesPerRequest": 0, "avgRequestTime": 0, "errorRate": 0, "malformedRequests": 0, "maxRequestTime": 0, "status2xx": 0, "status3xx": 0, "status4xx": 0, "status5xx": 0, "timedRequests": 0, "totalBytesSent": 0, "totalGeoEvents": 0, "totalRequests": 0, "uniqueCountries": 0, "uniqueIps": 0 }, "endDate": "string", "percentChanges": { "avgRequestTime": 0, "bytesSent": 0, "errorRate": 0, "geoRecords": 0, "logRecords": 0, "malformedRate": 0, "uniqueIps": 0 }, "previousPeriod": { "avgBytesPerRequest": 0, "avgRequestTime": 0, "errorRate": 0, "malformedRequests": 0, "maxRequestTime": 0, "status2xx": 0, "status3xx": 0, "status4xx": 0, "status5xx": 0, "timedRequests": 0, "totalBytesSent": 0, "totalGeoEvents": 0, "totalRequests": 0, "uniqueCountries": 0, "uniqueIps": 0 }, "startDate": "string"}Get the exact traffic summary from the raw rows GET
Returns the same figures as `/api/v1/analytics/summary`, counted from the raw access log and geo event rows of the exact range, so the unique counts are exact. It gets slower as the range grows, and the raw rows go back only ANALYTICS_RAW_RETENTION_DAYS days, 180 by default. `percentChanges.malformedRate` is always null here.
Get request metrics per hour or day GET
Returns requests, bytes, status classes, error rate and latency for each bucket that has requests, oldest first. Without filters it reads the hourly or daily aggregates at any range length, and those reads count whole hours or UTC days, from the one that holds `startDate` through the last one that starts before `endDate`. With `granularity=daily` and a `tz` other than UTC on a range of 30 days or less, those reads count local days instead. They start at the local midnight of the day holding `startDate` and run through the last hour that starts before `endDate`. A country, city, IP or ASN filter makes it read the raw access log rows, which go back only ANALYTICS_RAW_RETENTION_DAYS days, 180 by default. On that filtered path `tz` sets local days at any range length. `totalGeoEvents` is always 0 here, and `/api/v1/analytics/geo-time-series` has the geo series.