Analytics
What the calls added up to: how many, how long, how they ended, what they cost, and what callers thought. Two endpoints — one for totals over a window, one for the same numbers as a series you can plot.
The overview
/v1/analytics/overviewcurl -s "https://voice.sphoro.com/v1/analytics/overview?from=2026-09-01&to=2026-09-08" \
-H "Authorization: Bearer $SPHORO_API_KEY"{
"from": "2026-09-01",
"to": "2026-09-08",
"calls": {
"total": 4182,
"inbound": 1204,
"outbound": 2978,
"connected": 3106,
"average_duration_seconds": 84
},
"end_reasons": {
"ended_by_api": 1902,
"no_answer": 604,
"voicemail": 288,
"busy": 104,
"at_capacity": 41,
"bad_number": 63
},
"cost": { "total": 18240.55, "currency": "INR" },
"csat": { "responses": 311, "average": 4.3 }
}| Field | Type | Description |
|---|---|---|
fromoptional | date | Start of the window, inclusive. |
tooptional | date | End of the window, inclusive. |
agent_idoptional | string | Restrict to one agent. The slice to use when comparing two prompts. |
project_idoptional | string | Restrict to one cost centre. |
As a series
/v1/analytics/timeseriescurl -s "https://voice.sphoro.com/v1/analytics/timeseries?from=2026-08-01&to=2026-09-08&interval=day&metric=calls" \
-H "Authorization: Bearer $SPHORO_API_KEY"{
"metric": "calls",
"interval": "day",
"points": [
{ "at": "2026-08-01", "value": 412 },
{ "at": "2026-08-02", "value": 388 }
]
}The same filters apply. This is the shape for a dashboard, and for the question analytics actually answers best: has it changed, rather than what is it.
The numbers worth watching
| Metric | What a change in it means |
|---|---|
| Connected rate | Falling on outbound is usually the list, not the
agent — check bad_number and not_connected separately, because they are
different problems. |
at_capacity | Anything above zero is calls you never placed. Rising over a week is a ceiling you have grown into. See concurrency. |
| Average duration | A sudden drop usually means callers hanging up early, which is a prompt or a greeting problem. A rise means the agent is not closing. |
voicemail | High on a campaign is a timing problem — you are calling when nobody is there. |
| Cost per connected call | The number that catches a chain quietly falling through to a more expensive vendor. See vendors. |
end_reason before drawing any conclusion
about volume. "Calls are down" and "connected calls are down" are different sentences
with different causes, and the totals hide which one you have.Recording what callers thought
CSAT is not collected automatically — you record it, from wherever you actually ask. A follow-up SMS, a form on your site, a rating in your app.
/v1/analytics/csatcurl -s -X POST https://voice.sphoro.com/v1/analytics/csat \
-H "Authorization: Bearer $SPHORO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"call_id": "'"$CALL_ID"'", "score": 4, "comment": "Sorted it quickly."}'csat.received fires when one lands, so it can drive your own alerting. Scores are
joined to the call, which means they slice by agent and project like everything else — which is
the point: "which prompt do people prefer" is answerable.
Per-call detail
Analytics is aggregate. For one call, the record itself carries its duration, end reason, timings, cost and the vendors it used:
/v1/callscurl -s "https://voice.sphoro.com/v1/calls?agent_id=$AGENT_ID&limit=100" \
-H "Authorization: Bearer $SPHORO_API_KEY"For latency specifically, connect_ms and carrier_handoff_ms are the
two to read first — see latency.