Overview
GET /api/analytics returns one consolidated metric block for your workspace,
filterable down to a single campaign, sender line, sending user, or date
window. The same numbers power the /analytics page in the dashboard and
the analytics MCP tool, so a UI chart, an MCP question, and a curl call all
agree.
Reply rate and positive rate are computed as unique-by-contact ratios.
A contact who got 5 messages still counts as 1 toward “reached”, and one
contact who replies 10 times still counts as 1 toward “uniqueReplied”.
Endpoint
Authentication
Bearer-token. Pass your API key (tuco_...) in the Authorization header:
Query parameters
string
Restrict the result to one campaign (MongoDB ObjectId as 24-char hex).
string
Restrict to a single sender line (MongoDB ObjectId as 24-char hex).
string
Restrict to a single Clerk user ID who created the messages (
user_…).string
Inclusive lower bound, ISO 8601 (e.g.
2026-06-01T00:00:00Z). Filters on
message.createdAt.string
Inclusive upper bound, ISO 8601.
string
Reserved for the multi-workspace agency rollup that ships later. Today the
endpoint returns 501 Not Implemented if this parameter is supplied;
call without it to get your own workspace’s numbers.
Response
Metric definitions
number
Distinct contacts (phone or email) that received at least one outbound
message with status
sent or delivered inside the filter window.number
Total outbound messages with status
sent or delivered. Not de-duplicated
by contact — a 7-step campaign over 1,000 contacts can show sent ≈ 7,000.number
Outbound messages with status
fallback or with fallbackSmsDispatched
set. Both signal iMessage didn’t go through and SMS was attempted instead.number
Outbound messages with status
failed — hard send failure (technical
error, blocked recipient, transient-exhausted, etc.).number
Total inbound messages received inside the filter window. Includes
multiple replies from the same contact.
number
Distinct contacts that replied at least once inside the window.
number
uniqueReplied / reached. A decimal between 0 and 1 (multiply by 100 for
the display %). Returns 0 when reached is 0 — never divides by zero.number
Distinct contacts among
uniqueReplied whose conversation document carries
at least one positive tag: interested, to respond, to-answer, or
to_answer (case-insensitive exact match). Tags are written by Tuco’s
reply classifier and by Unibox operators.number
positiveReplied / uniqueReplied. Share of repliers tagged warm. Returns
0 when uniqueReplied is 0.Error responses
Example: pull last-30-day numbers for one campaign
Example: via MCP
Configure the Tuco MCP server and ask any MCP-compatible AI assistant:
“Show analytics for campaign 60d5ec49e3a8a0001f9b1234 over the last 30
days.”
The assistant calls the analytics MCP tool, which hits this endpoint with
your API key and returns the same metric block.
Observability
Every successful call emits a structuredanalytics.served event to Loki:
analytics.error with the error message and workspace id.