A common pattern is a single "Router" assistant that greets every caller, classifies the nature of the inquiry, and routes to a specialist:
{
"members": [
{
"assistant": {
"name": "Router",
"firstMessage": "Thanks for calling. Are you calling about a maintenance issue, a lease question, or something else?",
"model": {
"provider": "openai",
"model": "gpt-4o",
"messages": [{ "role": "system", "content": "Classify the caller's inquiry and transfer to the correct specialist." }]
}
},
"assistantDestinations": [
{
"type": "assistant",
"assistantName": "Maintenance Specialist",
"description": "Caller is reporting a maintenance issue, repair need, or something broken in their unit.",
"contextEngineeringPlan": { "type": "all" }
},
{
"type": "assistant",
"assistantName": "Leasing Specialist",
"description": "Caller has a question about renting a unit, lease terms, renewals, or move-in/move-out.",
"contextEngineeringPlan": { "type": "all" }
}
]
},
{
"assistant": {
"name": "Maintenance Specialist",
"model": { "provider": "openai", "model": "gpt-4o", "messages": [{ "role": "system", "content": "Handle maintenance requests: gather unit number, issue description, and urgency." }] }
}
},
{
"assistant": {
"name": "Leasing Specialist",
"model": { "provider": "openai", "model": "gpt-4o", "messages": [{ "role": "system", "content": "Handle leasing questions: availability, pricing, and application steps." }] }
}
}
]
}
Notice each destination's description is a specific triggering condition, not a generic label — this is what makes the router reliable at picking between the two specialists.
In summary: assistantDestinations is a convenient shorthand over the handoff tool, the description field is the actual routing logic the model reasons over, multi-destination structure should match your LLM provider's recommended pattern, contextEngineeringPlan controls exactly what history follows the caller to the next assistant, and dynamic destinations hand routing decisions off to your own server when static rules aren't enough.