Activity, logs and analytics
Everything the gateway records about your requests, how to read it in the dashboard, and how to pull it into your own tools.
What is recorded
Every request becomes a generation: model and vendor, key, workspace, status and finish reason, prompt / completion / cached / reasoning tokens, exact cost at the official rate, time to first token, total time, time spent routing, time lost to failed attempts, the list of attempts (vendor, outcome, classified reason), and your own labels — app (X-Title), session (X-ER-Session-Id / session_id) and end user (X-ER-User-Id / user). Prompts and completions are never stored.
Activity
The Activity page compares the selected range with the previous one: spend, requests, tokens, cache hit rate, blended $/1M tokens, error rate, p50 time to first token and output throughput, each with a sparkline. Below it: spend by model over time, requests by outcome, the token split, top keys and vendors. Anomaly banners appear when the last 24 hours deviate strongly from the 7-day baseline (spend, error rate, latency or volume). Turn on Live to refresh every 15 seconds.
Explore pivots any metric by any dimension — model, vendor, key, workspace, status, finish reason, user, session, app, API, streamed, BYOK or error code — with an optional second dimension and a top-N cut-off. Rates and percentiles are computed on the grouped rows, never averaged.
Logs
Logs lists every request with a histogram, a search box (id, session, user, app or model), filters, a column chooser and saved views. Live tails new requests in place. Click a row to open the drawer: a waterfall (routing → failed attempts → time to first token → generation), each attempt with its vendor and classified reason, a cost explainer that multiplies your token counts by the captured official rates, and the raw record. Use ← → to move between rows and "Report a problem" to send us the request id. The Sessions tab groups requests by session or user with per-group cost.
Exporting logs
Export the current filters as CSV or JSON. Exports run in the background and produce a signed download link that stays valid for seven days. Columns match the Logs table; vendor names are the model's official vendor.
Analytics API
The same engine is available to management keys, so anything you can see in the dashboard you can pull into a spreadsheet, a BI tool or your own alerting.
# Metrics and dimensions the engine understands
curl https://elevenrouter.com/api/v1/analytics/metrics -H "Authorization: Bearer $ELEVENROUTER_MANAGEMENT_KEY"
# Daily spend and requests per model for the last 30 days, Berlin time
curl https://elevenrouter.com/api/v1/analytics/query \
-H "Authorization: Bearer $ELEVENROUTER_MANAGEMENT_KEY" \
-H "content-type: application/json" \
-d '{
"from": "2026-08-16T00:00:00Z", "to": "2026-09-15T00:00:00Z",
"timezone": "Europe/Berlin", "granularity": "day",
"metrics": ["cost", "requests", "cache_hit_rate", "p95_ttft_ms"],
"dimensions": ["model"], "limit": 10,
"filters": { "status": ["succeeded"] }
}'{
"data": {
"query": { "from": "…", "to": "…", "timezone": "Europe/Berlin", "granularity": "day", "metrics": ["cost", …], "dimensions": ["model"] },
"rows": [
{ "bucket": "2026-09-14T00:00:00", "dimensions": { "model": "anthropic/claude-sonnet-5" },
"metrics": { "cost": 12.4031, "requests": 1840, "cache_hit_rate": 0.41, "p95_ttft_ms": 910 } },
{ "bucket": "2026-09-14T00:00:00", "dimensions": { "model": "__other__" }, "metrics": { … } }
],
"labels": { "api_key": { "…": "prod" } },
"truncated": false
}
}metricsstring[]- requests, succeeded, failed, error_rate, cost, prompt_tokens, completion_tokens, cached_tokens, reasoning_tokens, total_tokens, cache_hit_rate, blended_per_million, p50_ttft_ms, p95_ttft_ms, p50_total_ms, p95_total_ms, tokens_per_second, fallback_rate, insured, users, sessions.
dimensionsstring[] (max 2)- model, vendor, api_key, workspace, status, finish_reason, end_user, session, app, api_type, streamed, byok, error_code. The first dimension is cut to the top `limit` values by the first metric; the rest is reported as `__other__`.
granularityhour | day | week | month | total | auto- Bucket size. `total` returns one row per dimension combination; `auto` picks a readable size for the range.
timezoneIANA zone- Bucket boundaries are computed in this zone; `bucket` strings are local times.
filtersobject- model, vendor, api_key_id, workspace_id, status, finish_reason, user, session, app, api_type, streamed, byok, error_code — arrays match any value.
Ranges are limited to 400 days and results to 5,000 rows; narrow the range or use a coarser granularity when truncated is true. Inference keys cannot call the analytics API.