Analytics REST API
Pull daily analytics from your Workspace via REST endpoints to power custom dashboards, BI pipelines, and operational reports.
The Analytics REST API complements the GraphQL API by exposing a small set of pre-aggregated, cursor-paginated endpoints that return time-series data for the most common Workspace KPIs — chats, messages, returning users, CSAT, AI quality and technical errors.
Use it when you need to:
Build a custom dashboard in your BI tool (Looker, Metabase, Power BI, Grafana, etc.).
Feed an internal data warehouse with daily Workspace metrics.
Generate periodic reports (weekly/monthly) without re-aggregating raw chat data.
The Analytics REST API serves the same numbers shown in the Analytics section of the platform UI, computed from a TimescaleDB continuous aggregate. Today's value is approximate until end-of-day; historical days are stable.
Base URL
All Analytics endpoints are served from https://platform.indigo.ai. The exact path depends on the endpoint — see the Endpoints section below.
Each request is scoped to a single workspace via the {project_id} segment in the URL.
Authentication
Authentication is handled via a Personal Access Token (PAT), the same credential used by the GraphQL API. Pass it in the Authorization header of every request:
Authorization: Bearer pat-*your_pat_value*The token must belong to the same workspace identified by {project_id} in the path; otherwise the platform returns 403 Unauthorized.
API access is a premium feature and incurs an additional cost. If you don't have a PAT yet, contact us.
Pagination
All daily endpoints use opaque cursor-based pagination. Each response includes a metadata object with:
next_cursor— Base64-encoded cursor to pass ascursor(orafter) on the next request.nullwhen there are no more pages.total_count/total_days/days_count— total number of days in the requested range.
To fetch the next page, repeat the request with ?cursor=<next_cursor> (or ?after=<next_cursor> for users/unique-daily).
The limit query parameter controls page size: default 30 (or 31 for users/unique-daily), max 365.
Common parameters
from
YYYY-MM-DD
✅
Start of the date range (inclusive).
to
YYYY-MM-DD
✅
End of the date range (exclusive).
limit
integer (1–365)
❌
Days per page. Default 30 (31 for users/unique-daily).
cursor / after
string
❌
Pagination cursor returned by the previous response.
A 400 ERROR response with body {"status": "ERROR", "message": "Missing required params: from, to"} is returned when from or to are missing.
Rate limiting
The Analytics REST API is rate-limited to 100 requests per 60 seconds per Personal Access Token. When the limit is exceeded the API returns 429 Too Many Requests:
The retry_after value is the number of seconds to wait before retrying.
Endpoints
Six endpoints cover the headline Workspace KPIs. All return the standard envelope:
📨 Daily messages
Returns daily inbound/outbound message counts plus feedback and human-takeover signals.
Example response
inbound_messages— messages sent by the user to the agent.outbound_messages— messages sent by the agent to the user.positive_feedback/negative_feedback— thumb-up / thumb-down counts.ht_requests— number of Handover Block triggers (requests for a human agent).ht_starts— number of human takeover sessions actually started.
💬 Daily chats
Returns the number of chat sessions started each day. Historical days are served from the chat_aggregates hypertable; today's value is computed live and may be partial.
Example response
👥 Returning users (daily)
Returns the daily count of distinct users who already existed before that day and were active on it — a proxy for engagement of returning users. Counts are based on HyperLogLog cardinality (~2% error margin).
This endpoint accepts after instead of cursor for pagination.
Example response
😊 CSAT scores (daily)
Returns the daily aggregated CSAT score from in-chat surveys. Days with no responses are included with total = 0 and avg_score = null.
Example response
total— number of CSAT responses on this day.avg_score— weighted average score on a 1–5 scale, ornullwhentotal = 0.
🤖 AI quality (daily)
Returns the daily aggregated AI Quality score, the platform's automatic measure of how well the agent answered (combines grounding, relevance, and resolution signals).
Example response
⚠️ Technical errors (daily)
Returns the daily count of api_error events — failures emitted by API Blocks, integrations, or LLM calls. Days with no errors are zero-filled.
Example response
Error responses
400
{"status": "ERROR", "message": "Missing required params: from, to"}
from or to not provided.
400
{"status": "ERROR", "message": "Invalid cursor"}
Cursor is malformed or expired.
401
{"status": false, "message": "unauthenticated"}
Missing or invalid PAT.
403
{"status": false, "message": "unauthorized"}
PAT does not match {project_id}.
429
{"status": "error", "message": "rate limit exceeded", "retry_after": 60}
Rate limit hit (100 req/60s).
500
{"status": "ERROR", "message": "Internal server error"}
Unexpected server error — retry with backoff.
Best practices
Page through everything: even ranges with many empty days return zero-filled buckets, so always loop until
next_cursorisnull.Cache aggressively for historical days: values for past days are stable and safe to cache for hours or days. Only re-fetch the current day.
Stay within the rate limit: batch requests by widening the date range and using
limitrather than firing one request per day.Pair with GraphQL when you need raw data: the REST endpoints return aggregates only. To drill into individual conversations or messages, use the
conversationsandmessagesGraphQL queries.
Last updated
Was this helpful?