Automation opportunities
The Automation opportunities surface (dashboard → Agents → Automation opportunities) answers the question the conversation-intelligence scores leave open: once every inbound conversation is classified and priced, which contact reason should you hand to an agent next — and what would that save per month? This page is the concept model behind that recommendation feed: what qualifies a conversation family as agentable, how the verdict and the 0-100 score are computed, what a recommendation carries, and the endpoint contract for reading and tuning the model programmatically.Why opportunities matter
The conversation-intelligence pass classifies each inbound conversation into a contact reason (“refund”, “account access”, “delivery status”) and the insights rollup family turns those classes into economics: volume, handle time, human-handling cost. That is the conversation P&L. Automation opportunities is the read-time layer that takes that P&L and flags the families where humans still do work an agent could absorb — like the rest of the insights family, it is a read-time rollup over conversation records you already have, not a new pipeline. Every row on the surface is an answer to one question: of the money this contact reason is costing me, how much is winnable back this month? The ranked list orders the reasons by that answer, and the scaffold column turns the top answers into a first draft instead of a to-do item.Model inputs
The miner reads four kinds of input:- The classified conversation set. Every inbound conversation in the window contributes its channel, its classified contact reason, its resolution outcome, and its handle time when known. Resolution outcome is the deflection signal: resolved without a human assignee counts as already deflected, resolved with an assignee counts as still manual, and a conversation still open counts as unknown. The corpus is bounded to the 5,000 most recent conversations in the window so the payload stays fast on high-volume workspaces.
- The time window. A
from/torange of ISO datetimes, defaulting to the last 30 days and capped at 365 days. The miner also looks at the equal-length window precedingfromso each family carries a trend (rising or falling) beside its current volume. - The deflection target.
target_deflection_rateis the rate you believe an automation can realistically reach for a reason (default0.6). The gap between it and today’s measured rate is the headroom every projection starts from. - Unit-cost inputs.
agent_cost_per_hour_cents(your fully-loaded human handling cost per agent-hour, default3000, i.e. $30/hour),automation_cost_per_contact_cents(the marginal cost of one automated deflection, default5),default_aht_seconds(the assumed handle time when a family has no measured one, default300), andmin_volume(the current-window volume floor below which long-tail noise is ignored, default5). All five are yours to read and update on the config endpoints; until you set them, the defaults above apply.
The verdict computation
A family flips into an opportunity only when two thresholds hold at once: its current-window volume clears themin_volume floor, and its
deflection headroom is positive. A family already deflecting at or above
your target is deliberately excluded: the surface answers “what to automate
next”, not “what is already automated”. An unknown deflection rate counts as
zero measured deflection, i.e. full headroom, because “we never measured
deflection here” is itself a strong automate-me signal.
For each qualifying family the math is:
- Automatable volume — the incremental contacts this window that
headroom implies:
automatable_volume = volume × max(0, target_deflection_rate − current_deflection_rate), rounded to whole contacts. - Human handling cost per contact — the family’s measured average
handle time (or
default_aht_secondswhen unmeasured), priced at your labour rate:handle_cost_per_contact_cents = round(handle_seconds / 3600 × agent_cost_per_hour_cents). - Net saving per deflection — human cost minus the automated cost,
floored at zero:
net_savings_per_deflection_cents = max(0, handle_cost − automation_cost_per_contact_cents). - Monthly projection — the window figures normalised to a 30-day month:
projected_monthly_deflections = round(automatable_volume × 30 / window_days), andprojected_monthly_savings_cents = projected_monthly_deflections × net_savings_per_deflection_cents. - Opportunity score (0-100) — a relative rank inside the response, not
an absolute grade. The ranking metric is projected monthly savings when
any family in the set prices out positively; before you tune the ROI
config it falls back to raw automatable volume so the surface is still
useful. The biggest win scores 100 and every other row scores
round(100 × its_metric / top_metric). Ties break on savings, then automatable volume, then family name.
Worked example
Suppose your 30-day window shows acancellation family with 400 contacts,
a measured deflection rate of 10%, and a 6-minute (360 s) average handle
time. With the default target of 60%, headroom is 50 points, so
400 × 0.5 = 200 contacts are automatable this window, projecting to 200
deflections a month. Priced at the default $30/hour labour rate, each contact
costs `360 / 3600 × 3000 = 300` cents to handle; minus the 5-cent automated
cost, each deflection nets 295 cents, so the family projects `200 × 295 = 59,000` cents (about $590) a month and scores 100 as the
biggest win in the set, with a self-serve flow scaffold. A sibling family
with the same volume but a measured deflection rate already above target
does not appear at all — there is nothing left to win there.
The scaffold taxonomy
Each row recommends the Orbit primitive best suited to deflect its family, inscaffold.kind:
flow and ai_agent scaffolds are one-click: the scaffold endpoint creates
the draft for you. A knowledge_base_article scaffold is presented as
guidance on the surface; if you want the article drafted from your real
transcripts too, the
KB auto-draft loop mines the same feed and files
draft articles pending your approval.
Click-to-draft lifecycle
Clicking a scaffold (or calling the scaffold endpoint directly) does not launch anything — it creates a draft. Server-side, the endpoint re-derives the family’s cluster from theopportunity_id within the window
you pass — the id is a deterministic digest of the contact reason, so the
same family yields the same id in the same window — then:
- for an
ai_agentscaffold it creates an agent indraftstatus, titledDraft: <family>, with a starter system prompt grounded in the mined intent; the dashboard deep-links you into that draft agent’s page; - for a
flowscaffold it creates a flow with a single manual trigger node and the opportunity’s id and projected deflection rate recorded in its metadata, and opens the flow builder with the draft loaded.
agent_id or flow_id),
draft: true, and the draft title so your client can deep-link the author
straight into the builder. From there the normal authoring loop applies —
ground the agent, review it, and activate it yourself, or assemble several
scaffolds into a squad; the
creating-agents walkthrough covers that loop.
Once a family has been scaffolded, the feed flags it as scaffolded so you
don’t build the same draft twice. The hand-off contract is exactly this: the
surface offers a pre-titled draft targeting the family’s busiest channel;
the decision to activate stays with you.
The config endpoints
The ROI assumptions above live per organisation and are readable and writable at:GET /api/v1/insights/automation-opportunities/config— returns the current assumptions, always as the full five-field shape; a workspace that never configured them sees the defaults.PUT /api/v1/insights/automation-opportunities/config— accepts a partial body with at least one field; omitted fields keep their current value, and the merged, persisted config is returned. Out-of-range values are rejected with a validation error rather than persisted.
Money in this surface is always integer cents in your organisation’s wallet
currency, never FX-converted.
Reading the recommendation endpoint
The ranked feed is served atGET /api/v1/insights/automation-opportunities?from=&to=&limit= (window
defaults to the last 30 days; limit caps the rows, max 50). The response
carries the window (from, to, window_days), your wallet currency, an
echo of the config the projection used, totals that span every
qualifying family even when the list is truncated (opportunity_count,
shown_count, truncated, and the summed automatable volume, monthly
deflections, and monthly savings), and the ranked opportunities rows.
Each row is one topic family and carries:
topic,volume,previous_volume,trend, andchange_pct, plus the per-channel split andprimary_channel(the busiest channel);current_deflection_rate(null when never measured) andavg_aht_seconds;automatable_volume— the incremental contacts deflection headroom implies;projected_monthly_deflectionsandprojected_monthly_savings_cents— the 30-day projection priced from your config;opportunity_score— the relative 0-100 rank described above;scaffold— the suggestion from the taxonomy, titled and aimed at the family’s busiest channel.
GET /api/v1/agents/automation-opportunities?days=&limit=, which also mints
the opportunity_id each row needs for the scaffold round-trip and attaches
representative_examples (short redacted excerpts from the cluster) and the
scaffolded flag.
Sample requests
All four calls authenticate like any other/api/v1 request from your
account; substitute your bearer credential for <YOUR_ACCESS_TOKEN>.
List the ranked opportunities for the default 30-day window:
opportunity_id from
GET /api/v1/agents/automation-opportunities and pass the same days
window you listed it under, so the cluster re-derives identically:
201 with opportunity_id,
automation_type, exactly one of agent_id / flow_id, draft: true, and
the draft title. Scaffolding requires a role that can create agents and
flows; a family whose cluster has aged out of the window returns 404.
Tenant-operated warnings
The surface is strictly advisory. It never creates an active agent, never routes traffic, and never changes a write path — it reads conversation records and your own ROI assumptions, and it only ever produces drafts when you click. Tuning the assumptions, ignoring a recommendation, or deleting a scaffolded draft are all tenant-owned choices; the flagged options wait for you.Projected savings are estimates computed from your own cost assumptions in
your wallet currency, not a billing commitment. Treat the ranking as a
triage aid and validate a scaffolded draft on real traffic before
activating it.
Related reading
- Conversation intelligence — the per-conversation scores this surface aggregates.
- The insights rollup model — the read-time-rollup design the whole insights family shares.
- Automation opportunity miner — working the surface day to day.
- KB auto-draft — drafting help articles from the same feed, pending approval.
- QA leaderboard and evaluations — review loop for the agents you do activate.
- Creating agents — the authoring loop a scaffold starts.
- Squads — assembling several agents into one squad.