Six months of call data. Three thousand calls a week. You want to know how many calls were billing-related and resolved on first contact. The answer your dashboard returns is “between 12% and 47%, depending on how you count”. That is not a reporting problem, it is a disposition discipline problem. Free-text wrap-up notes are how voice operations stay unmeasurable.
What a disposition actually is
In Freshcaller a call disposition is a structured outcome code applied at the end of every call. It is a dropdown selection, not a note. It can be required before the agent hangs up. It can drive downstream automation — write a contact field, update a deal stage, fire a workflow. It is also the single most useful field for voice analytics, and the most commonly under-designed.
The default Freshcaller config gives you a small starter list (Resolved, Follow-up, Voicemail, etc.). That is fine for a 5-person team. At scale you need a real taxonomy.
The two-dimensional taxonomy
One dimension is not enough. “Resolved” tells you outcome; it does not tell you what the call was about. The shape that works is reason × outcome.
reason: billing | technical | sales | retention | account_admin | escalation
outcome: resolved | follow_up_scheduled | escalated | callback_requested | abandoned_by_caller | wrong_number
Six reasons, six outcomes. Thirty-six legitimate combinations. You can absolutely live with that. The mistake is putting reason and outcome into a single 36-option dropdown — agents will not scroll and will pick the first plausible one.
Build two dependent fields. Reason first, outcome second, filtered by valid combinations. wrong_number only appears under account_admin or sales. escalated does not appear under wrong_number. The dependency tree prunes nonsense before the agent can pick it.
Make it required, make it fast
Optional disposition fields end up populated on maybe 40% of calls, and the 40% is non-random — diligent agents do it, the rest do not. Your data is now biased toward the agents who already log everything.
Enforce required selection at the call wrap-up screen. Pair it with a 20-second auto-redial lockout so agents cannot dodge by hanging up and starting the next call. Yes, agents will complain. The complaint goes away within two weeks when they see the dashboard showing their own QA scores climb.
Keep wrap-up time bounded. If the agent has not selected within 60 seconds, default to a wrap_up_timeout disposition and surface that in supervisor view. The timeout disposition itself is data — a team with high timeout counts is overloaded, undertrained, or has wrap-up screens that are too complicated.
Disposition-driven automation
Once dispositions are clean, they are wiring. A retention × callback_requested outcome should fire a workflow that creates a Freshsales task for the account owner with a 24-hour due date. A technical × escalated outcome should create a Freshdesk ticket pre-populated with the call recording URL and the caller’s history.
{
"workflow": "Freshcaller_PostCall_Routing",
"trigger": "Call Completed",
"branches": [
{
"if": { "reason": "retention", "outcome": "callback_requested" },
"do": [
{
"action": "create_task",
"target": "freshsales",
"subject": "Retention callback: {{call.from}}",
"due_in_hours": 24,
"assignee": "{{contact.owner_id}}"
}
]
},
{
"if": { "reason": "technical", "outcome": "escalated" },
"do": [
{
"action": "create_ticket",
"target": "freshdesk",
"subject": "Phone escalation: {{call.summary_short}}",
"priority": "High",
"attachments": ["{{call.recording_url}}"]
}
]
}
]
}
This is where disposition discipline pays back. The downstream automation is only as trustworthy as the field that triggers it. Agents who would otherwise tag every call follow_up because they could not be bothered are now creating tasks for someone else, who pushes back, which fixes the data faster than any training program.
Reporting that finally works
With a clean taxonomy you can answer real questions:
- First-call resolution =
outcome = resolved/ total calls per reason. - Backlog generated by voice = count of
callback_requestedandfollow_up_scheduledper day. - Demand mix shift = reason distribution week over week.
- Agent variance = same metrics sliced by
agent_id, looking for outliers.
The Freshworks reporting layer can do all of this with custom reports keyed on the disposition fields. See freshworks-reports-analytics for the report-modelling pattern.
Reviewing the taxonomy quarterly
Reasons drift. A new product launch adds a reason. An old product retiring removes one. Run a quarterly review with this script:
curl -s "https://acme.freshcaller.com/api/v1/calls?disposed_after=2026-02-14" \
-H "X-Api-Auth: $FC_KEY" \
| jq '[.calls[] | {reason: .disposition.reason, outcome: .disposition.outcome}]
| group_by(.reason)
| map({reason: .[0].reason, count: length})
| sort_by(.count) | reverse'
Any reason with under 0.5% volume is either dying (retire it) or being avoided by agents (rename or split it). Any combination that never appears should be removed from the dependent dropdown to shrink the surface.
The notes field is not dead
Free-text notes still have a place — case-specific context the dropdown cannot capture. The rule is: structured field first, free text second. Notes are read by humans, dispositions are queried by dashboards. Keep them separated, and the dashboard never has to parse English to answer a question.
A useful pattern: a small key_phrase custom field with a list of pre-approved short tokens (refund_processed, account_locked, escalation_to_legal). Twelve tokens, agents click through them in a second, and you get a third axis of analysis without the noise of full free text.
Connecting to Freddy
If you have Freddy Copilot enabled, call summarisation can pre-fill disposition suggestions from the transcript. The pattern that works: Freddy suggests reason and outcome, the agent confirms or overrides. Confirmation rate above 80% in your sandbox before you turn it on for the whole team. Below that, the suggestions are noise.
See freddy-copilot-self-service-tuning for the broader tuning loop on Freddy outputs.
Bottom line
Voice analytics live and die on the disposition field. Two-dimensional taxonomy, dependent dropdowns, required selection, timeout default, quarterly review. Wire the codes into downstream automation so the data has consequences, and the data gets clean. The agents who hated the dropdown become the loudest defenders of it once they see the dashboard.