Skip to main content
A squad is a multi-agent collaborative unit: one classifier agent routes each inbound conversation turn to the right specialist member, so you split capability across several focused AI providers (for example a voice skill plus a chat skill) instead of growing one agent without bound. The operator UI lives at /agents/squads; the concepts and reference pages at agents/squads, concepts/agent-run-lifecycle, and Language quality describe the shape; this guide walks the operator loop end to end. Every control here is tenant-owned: the squad definition, member list, and routing loop decisions live in your organization’s settings on reading and writing. Squads run on Orbit’s agent runtime (agent conversations, handoffs, and the run lifecycle) — none of these controls touch outbound voice or SMS termination; a squad is inbound routing config, not a carrier- or provider-side change. Base path: /agents/squads Authentication: Clerk session or API key. Writes require an owner, admin, or developer role. Reads require a signed-in session or API key. The guide keeps voice and chat provider selection to the models and agents you already run — see Agent model selection and Cost controls.

1. What a squad is in Orbit

A squad is one row plus a member list: Three shapes must stay loop-free or the API rejects the create/update with a 422:
  1. The classifier must not appear in members[] — routing the classifier’s decision back to itself recurses and bills LLM calls until the API ceiling.
  2. The fallback must not equal the classifier — an unmatched intent bounces back and re-classifies the same message forever.
  3. Intent labels must be unique across members — duplicates make routing ambiguous and first-match-wins varies by row order.
Read concepts/agent-run-lifecycle for how an agent run is started, halted, escalated, and finished — a squad plugs into that exact run envelope once the classifier has chosen a member.

2. Create a squad via POST /agents/squads

Prerequisites:
  • the classifier agent already exists (Creating agents);
  • each member agent exists and carries its own prompt and providers (see below for a voice-plus-chat split);
  • you hold an owner, admin, or developer role.
Create a squad with two members — a voice skill plus a chat skill — each answering a distinct intent cluster:
A 201 returns the new squad including its generated id (prefix squad_). If a referenced agent id is wrong the API returns 422 and names the unknown ids — fix the member list and retry. Use Agent versions to pin the exact prompt revision each member runs before entering traffic. The same object is uploaded by the /agents/squads/new wizard in the dashboard; the UI walks the same fields and ends with a test run (see next section) before deployment.

3. Assign agents and teams

Each member is a normal agent — its prompt, providers, and version pin come from that agent’s own configuration; a squad does not override them. To assign a human team as the fallback or as a deliberate endpoint, route the handoff through agents/squads (the human/handoff shapes that page documents), then point fallback_agent_id at the human squad-intake agent that wraps that team, or stop routing human-intent lanes to a member that hands off to the team directly. Assignment is a write operation: PUT /agents/squads/:id replaces any field you send (name, classifier, members, fallback, active, cost ceiling). Leave members untouched to rotate just the classifier, or send a full new member list to rotate skills. The same 422 loop-shape guard runs on the merged state, so a partial update cannot sneak in a classifier-self loop. To retire a squad: DELETE /agents/squads/:id. Audit entries (agent_squad.created, agent_squad.updated, agent_squad.deleted) flow to the audit log, so the team-review trail records who changed routing and when.

4. Route the squad in the omnichannel queue

Once a squad is live each inbound conversation lands in your normal omnichannel queue machinery and the squad’s classifier decides the member on the next run. The two routing layers interact in one place:
  • Queue layer — which queue or affinity bucket the conversation enters, with SLA previewed on-queue (Omnichannel queue routing).
  • Squad layer — which specialist member takes the run once the work item dispatches.
Set attribute routing and affinity first; the squad changes nothing about where a conversation queues — it only changes which AI capability answers it once it dispatches. Watch the blended queue at GET /api/v1/voice/supervisor/omnichannel-queue (same list the supervisor UI renders) to see voice and digital items shared into one position-ordered backlog; that is where you verify the same queueing that the squad will inherit.

5. SLA and handoff targets

A squad runs inside the broader SLA and escalation model:
  • agents/handoff-targets — the named resolution for every handoff verb (queue, team, human, callback, close). Point the squad’s member handoff_targets at the same named targets; escalation from a member then lands in the operator state you designed.
  • concepts/agent-run-lifecycle — the run envelope: states, clock, halt conditions, and how an escalated run is counted. SLA timers and AI guardrails operate on the run, not on the squad name, so a squad that tips a run into human_review instantly joins the SLA wallboard lane.
Set handoff targets on each member before first traffic — a member with no targets has no clean place to escalate, and the classifier will keep re-routing the same message.

6. Monitor squad utilization on the wallboard

The squad rollup at GET /agents/squads/:id/analytics?days=30 is the utilization surface for one squad across a rolling window (default 30 days). It reports per-specialist utilization, cross-agent handoff success rate, drop-off, and containment lift versus the classifier-alone baseline. Read it from the dashboard’s squad analytics panel or pull it programmatically into your own ops dashboard. The same numbers feed the operator surfaces you already run: the wallboard shows the live backlog and SLA posture for the queues the squad routes into, and wallboard alarm rules let you post a threshold on backlog or SLA breach before it unfolds. Tune member composition from the analytics: if one member absorbs almost every matched label while another is starved, the skill split is wrong — rebalance intent labels and re-deploy.

7. Live monitoring

For the collective picture during a traffic spike, the supervisor surfaces show the queue and any escalated run the squad produced: The squad shape itself does not change any of these surfaces; it only changes which agent picked up the run upstream of the supervisor layer.

Worked example — escalate LP1 → LP2 on a guardrail trip

Language proficiency level 1 (LP1) is a confined inbox + inbound-chat agent, LP2 is a fuller-context agent with a larger model and the authority to finish a billing write. The trigger for the step-up is a guardrail event: the Language quality guardrail (or a sensitive-words event — see Sensitive words guardrail) fires for two consecutive runs, and you want the next turn to route to the heavier LP2 specialist instead of repeating a containment failure. Build the two-tier squad once:
Then operate the trigger:
  1. The LP1 member runs with its normal handoff targets (step 4–5 above) pointing at the escalation lane. When the language-quality guardrail fires on two consecutive runs, set that lane to hand off to the squad’s classifier — see agents/handoff-targets.
  2. The classifier re-runs against the last LP1 message; a label such as guardrail_trip or billing_write matches the LP2 member, which serves the turn.
  3. Watch it on the squad analytics rollup (step 6): handoff success rate for LP1→LP2 tells you the step-up actually fires, and containment lift versus the classifier alone tells you the escalation is doing work.
  4. If LP2 cannot resolve, its own handoff target routes to agent_human_intake; the supervisor picks up from the live-monitoring surfaces in step 7.
When volume shifts — for example LP1 absorbs nearly every label — rebalance intent_labels between members and re-test before redeploying.

Test before you deploy

Run the classifier once against a sample message to confirm label coverage without deploying:
The response carries the matched member, the raw label emitted by the classifier, and the match source (matched, fallback, or unavailable) — the same decision the runtime will make. A unavailable source or a match against the wrong member means the squad’s intent labels do not yet cover that kind of message; edit the member list and re-test.

Reference