Analytics
Query aggregated stats, timeseries, breakdowns, and logs across two datasets: api_traffic and key_activity. Rate-limited per customer.
/analytics/statsBearerAggregate stats
source selects the dataset: api_traffic (full proxy logs) or key_activity (validation events). timeRange defaults to "24h".
source"api_traffic" | "key_activity"requiredWhich dataset to query.
timeRangestring1h, 3h, 6h, 12h, 24h, 7d, 30d. Default 24h.
apiIdstringFilter to a specific API.
filtersobjectNarrow by endpoint, method, statusCode, clientIp, consumer.
curl -X POST "https://api.reqkey.com/analytics/stats" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"source": "api_traffic",
"timeRange": "24h",
"filters": {}
}'{
"source": "api_traffic",
"timeRange": "24h",
"stats": {
"totalRequests": 15230,
"errorRate": 2.45,
"avgLatencyMs": 128.5
}
}/analytics/stats/detailsBearerStat card drill-down
Timeseries + breakdown for a single stat card.
sourcestringrequiredapi_traffic or key_activity.
cardstringrequiredtotalRequests, totalApiCalls, errorRate, or latency.
timeRangestringDefault 24h.
filtersobjectOptional dimension filters.
curl -X POST "https://api.reqkey.com/analytics/stats/details" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"source": "api_traffic",
"card": "errorRate",
"timeRange": "24h",
"filters": {}
}'{
"source": "api_traffic",
"card": "errorRate",
"timeRange": "24h",
"details": {
"errorBreakdown": [
{
"code": "404",
"count": 150,
"percentage": 60
},
{
"code": "500",
"count": 80,
"percentage": 32
},
{
"code": "429",
"count": 20,
"percentage": 8
}
]
}
}/analytics/timeseriesBearerTimeseries
Time-bucketed requests, errors, and latency for charts.
sourcestringrequiredapi_traffic or key_activity.
timeRangestringDefault 24h. Bucket size is chosen automatically.
filtersobjectOptional dimension filters.
curl -X POST "https://api.reqkey.com/analytics/timeseries" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"source": "api_traffic",
"timeRange": "24h",
"filters": {}
}'{
"source": "api_traffic",
"timeRange": "24h",
"granularity": "1 HOUR",
"data": [
{
"timeBucket": "2026-02-23T12:00:00Z",
"requests": 500,
"errors": 25,
"avgLatencyMs": 125.5
},
{
"timeBucket": "2026-02-23T13:00:00Z",
"requests": 450,
"errors": 18,
"avgLatencyMs": 110.25
}
]
}/analytics/breakdownBearerDimension breakdown
Top values for a dimension, ranked by request count (max 50).
sourcestringrequiredapi_traffic or key_activity.
dimensionstringrequiredendpoint, method, statusCode, clientIp, or consumer.
timeRangestringDefault 24h.
filtersobjectOptional dimension filters.
curl -X POST "https://api.reqkey.com/analytics/breakdown" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"source": "api_traffic",
"dimension": "endpoint",
"timeRange": "24h",
"filters": {}
}'{
"source": "api_traffic",
"dimension": "endpoint",
"timeRange": "24h",
"data": [
{
"value": "/api/users",
"count": 5000,
"percentage": 45.5
},
{
"value": "/api/products",
"count": 3200,
"percentage": 29.1
},
{
"value": "/api/orders",
"count": 2800,
"percentage": 25.4
}
]
}- Filtering by the same dimension you break down on is ignored to prevent self-filtering.
/analytics/logsBearerLog list
Returns one page of log rows plus a nextCursor. Omit cursor for the first page, then send each response’s nextCursor back as cursor to fetch the next page — every page is equally fast, no matter how deep. Full request/response data for a row comes from /analytics/logs/detail.
sourcestringrequiredapi_traffic or key_activity.
timeRangestring1h, 3h, 6h, 12h, 24h, 7d, 30d. Default 24h.
pageSizenumberResults per page (max 200). Default 50.
cursorstringOpaque cursor from the previous response’s nextCursor. Omit for the first page. Pass it back unchanged — don’t parse or modify it.
statusFilterstring"all", "success" (200–399), or "error" (400+).
filtersobjectOptional dimension filters.
curl -X POST "https://api.reqkey.com/analytics/logs" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"source": "api_traffic",
"timeRange": "24h",
"pageSize": 50,
"cursor": "1784050973_req_rLDNyUfIzvKA",
"statusFilter": "all"
}'{
"source": "api_traffic",
"timeRange": "24h",
"total": 574122,
"pageSize": 50,
"nextCursor": "1784061384_req_tcZZoOkQVMor",
"rows": [
{
"requestId": "req_tcZZoOkQVMor",
"timestamp": "2026-07-14 20:36:24",
"tsUnix": 1784061384,
"method": "GET",
"endpoint": "/api/users",
"path": "/api/users?page=1&limit=20",
"statusCode": 200,
"latencyMs": 125.5,
"clientIp": "192.168.1.100",
"apiKey": "***...abc123",
"apiId": "api_xyz",
"apiName": "user-service",
"consumerId": "consumer_123",
"consumerName": "Acme Corp",
"country": "US",
"region": "us-east-1"
}
]
}- nextCursor is null on the last page. total comes back on every page for count displays.
- Cursors move forward only — “jump to page N” isn’t supported. Keep earlier cursors in memory if you need a back button.
- Save each row’s timestamp: /analytics/logs/detail needs it for fast lookups.
- Prefer timeRange strings ("1h", "24h", "30d") over computing exact start/end times per request — identical windows share the server cache.
- API keys are masked — only the last 6–8 characters are shown.
/analytics/logs/detailBearerLog detail
Look up one request by its requestId and timestamp, both taken from an /analytics/logs row. The timestamp pins the lookup to the right time slice, which is what makes the query fast — always send it.
requestIdstringrequiredRequest ID from a logs list entry.
timestampstringrequiredThe row’s timestamp exactly as /analytics/logs returned it (YYYY-MM-DD HH:MM:SS). Unix seconds or milliseconds also work. Pass it through verbatim — don’t reformat it.
sourcestringRestrict to one table. If omitted, both are searched.
curl -X POST "https://api.reqkey.com/analytics/logs/detail" \
-H "Authorization: Bearer reqkey_xxx..." \
-H "Content-Type: application/json" \
-d '{
"requestId": "req_abc123xyz",
"source": "api_traffic",
"timestamp": "2026-07-14 12:44:58"
}'{
"requestId": "req_abc123xyz",
"keyLog": null,
"apiLog": {
"requestId": "req_abc123xyz",
"timestamp": "2026-07-14 12:44:58",
"method": "POST",
"endpoint": "/api/users",
"statusCode": 201,
"latencyMs": 150.25,
"consumerId": "consumer_123",
"region": "us-east-1",
"requestBody": "{\"name\":\"John Doe\"}",
"responseBody": "{\"id\":\"user_123\",\"status\":\"created\"}",
"requestHeaders": "{\"content-type\":\"application/json\"}",
"responseHeaders": "{\"content-type\":\"application/json\"}"
}
}- keyLog and apiLog are each null when absent. Bodies are truncated at 2KB.