On this page
Qualify a request and book the agreed next step
Build an agent for a requested consultation. It captures the prospect’s needs, routes specialist requests, offers available times and asks for confirmation before booking. It records either the confirmed reservation or the follow-up needed.
The screenshots show synthetic data. You implement the availability, booking and CRM endpoints and determine who may be contacted or booked. Select an image to view it at full size.
Design the conversation around decisions
The main graph handles the conversation and specialist route. A separate booking component handles availability, confirmation, reservation and the failure path. Keeping those steps explicit lets you test a booking change without rewriting the entire qualification conversation.
| Stage | Information you need | Decision |
|---|---|---|
| Introduction | Why the person requested contact; whether now is appropriate | Continue or end respectfully |
| Need discovery | Use case, existing system, scale and timeline | Gather the missing facts rather than guessing |
| Qualification | Structured fields with defined types and choices | Standard booking, specialist follow-up or further information |
| Availability | Slots returned by the calendar service | Offer only currently returned options |
| Confirmation | Selected time, time zone, attendees and requested service | Request the reservation only after explicit agreement |
| Business response | Reservation identifier and final state | Confirm completion or record an exception |
| CRM handoff | Agreed next step and the original run identity | Store an accurate outcome for the human team |
Define qualification fields
Define fields an operator can use: use_case as text, monthly_volume as a number, timeline as an enum, and needs_specialist as a boolean. The field descriptions should say what evidence the conversation needs, including what to do when the caller does not know an answer.
Extraction is model-produced information. Your business system validates it before making a decision or committing a transaction. Do not turn a guessed budget, urgency or title into an authoritative business fact.
Use defined variables in the routing conditions and keep a default path. A request outside the standard offering should become a specialist case, not a promise that an unsupported feature is available.
Separate calendar reads from reservation writes
find_availability reads your calendar. book_appointment requests a reservation. create_ticket records a specialist or exception case. update_crm records the agreed outcome. Give reads and writes separate contracts and test mocks.
For example, the availability endpoint can return a stable slot_id, displayed local time and time zone. The reservation endpoint can accept that slot ID and a known contact ID, then return { "state": "confirmed", "appointment_id": "APPT-DEMO-24" }. Those fields are conventions for your service, not built-in Cumulus calendar APIs.
The reservation service must validate the slot again at commit time: another person can take it after the agent reads availability. It must also honor the idempotency contract so a retry does not create a second appointment.
Confirm before booking
Read back the selected time and time zone. Check the requested service and attendee details. Only the explicit confirmation transition should reach the reservation function.
Test “I need a different time,” “I am not ready to book,” a correction to the attendee and an ambiguous response. A model interpreting a transition condition still needs acceptance tests; a visible edge does not make the interpretation deterministic.
Map the business response into the variable the branch reads. Confirm only a successful reservation response. A stale slot, timeout or unknown result should produce the defined review/reconciliation path; it is not evidence that a calendar entry exists.
Configure the phone experience
Choose the voicemail behavior deliberately. The message should identify the purpose without leaking unnecessary account information or claiming that an appointment was booked.
Set interruption behavior, silence handling and maximum duration for the use case. Test the full audio path as well as text simulations: a scenario that passes in text does not establish natural turn-taking, correct voicemail detection or real number routing.
Supply the known context at admission
This example starts a run for a requested consultation. The contact ID is a reference your business already knows; the agent should not invent one from the phone number.
<!-- operation:runs.create -->{
"channel": "phone",
"agent_id": "qualification-booking",
"to": "+14155550124",
"from": "+14155550100",
"dynamic_variables": {
"business_name": "Acme",
"contact_id": "LEAD-DEMO-24",
"service": "technical_consultation",
"timezone": "America/New_York"
},
"metadata": { "lead_reference": "LEAD-DEMO-24", "requested_contact": "true" }
}
Use Start a run with a retained Idempotency-Key. Metadata records your context; it does not independently establish that contact was authorized. For inbound calls, configure the number and published agent as described in Phone.
Test the booking and failure paths
| Test case | Evidence to inspect |
|---|---|
| Person declines to continue | The call ends without a booking write |
| Required qualification field is unknown | The defined information/follow-up route is taken |
| Caller changes the selected time | The confirmed slot matches the final agreement |
| Slot becomes unavailable | No unsupported “you are booked” statement |
| Reservation response is uncertain | Reconciliation or review before another write |
| Specialist required | A case or agreed handoff is recorded with the run reference |
Use node/path assertions for structure, tool assertions for the expected action and a judged criterion for the confirmation conversation. Validate real availability, reservation and CRM contracts separately. Inspect run-linked action receipts before treating a meeting as scheduled.
Store the appointment or follow-up identifier with the run ID in your CRM. If the reservation result is unclear, use those identifiers to reconcile it with the calendar service.







