NightDesk now has a call analytics endpoint for MSP ROI reporting
The most common question a pilot MSP owner asks after the first two weeks: "Is it actually working?"
You can look at individual transcripts. But when someone asks for a summary — at a quarterly business review, in a conversation with a skeptical co-owner, or just to sanity-check your own gut — you need a number.
NightDesk now has a call analytics endpoint.
What it returns
GET /admin/tenants/{tenant_id}/stats?days=7 (or ?days=30) returns:
{
"tenant_id": "agj-systems",
"period_days": 7,
"total_calls": 43,
"resolved": 29,
"escalated": 9,
"paged": 5,
"resolution_rate": 0.674,
"avg_turns": 4.2,
"by_customer": [
{ "customer_id": "acme-corp", "calls": 12, "resolved": 9, "escalated": 2, "paged": 1 },
{ "customer_id": "widget-co", "calls": 8, "resolved": 6, "escalated": 1, "paged": 1 }
]
}
Resolution rate is the headline number. In internal testing it runs 60–70% — meaning 6–7 out of every 10 after-hours calls resolve without waking anyone up.
avg_turns tells you how much work each call takes. Lower is better, but too low might mean the AI is escalating too aggressively. The sweet spot for a well-tuned runbook is 3–5 turns.
by_customer sorts by call volume so you can see which customers are driving your after-hours load. Useful for runbook tuning and for conversations with customers who might need daytime workflow changes.
How it's implemented
The endpoint queries a GSI on the nightdesk_call_stats table, filtering by tenant_id and a timestamp range calculated from days. All the heavy lifting is a single DynamoDB query — no aggregation in Lambda, no N+1 lookups.
The GSI (tenant_id-created_at-index) exists primarily to make this query fast. Without it, you'd be doing a full scan and filtering in memory — fine at 100 calls/month, not fine at 5,000.
Each call already writes a stat record at resolution time, so the analytics data is real-time. No separate job or batch process.
Why this matters for the pilot
The pilot ask for an MSP owner is "try this for 30 days and tell me if it's worth the price." At the 30-day mark, you pull the stats and have a concrete answer:
- $500/mo pilot price vs. what you were paying for that volume in engineer time
- X calls resolved without a page vs. X calls that used to hit the on-call rotation
- Average handle time vs. what a human on-call would spend
If the numbers don't tell a clear story, the system isn't working and you stop the pilot. That's the deal. This endpoint gives you the data to have that conversation honestly.
I built it as a standalone branch — no stacking dependency — so it can merge and deploy independently.