Booking Flow
Sequence
Section titled “Sequence”verify_member --> resolve_address (pickup) --> resolve_address (dropoff) --> set_booking_details --> review_trip --> confirm_tripStep-by-Step
Section titled “Step-by-Step”Step 1: verify_member
Section titled “Step 1: verify_member”Verify the member’s identity and create a booking session.
- Input:
member_id(Medicaid ID or UUID),name,dob,channel - Output:
session_id,home_address(structured with coordinates),treatment_types[](flat name list),service_types[](human-readable with code) - DOB verification uses actual date comparison (minimum 2 date tokens required)
- Creates a fresh BookingDraft in Valkey (24h TTL) – never reuses drafts from other sessions
Step 2: resolve_address (pickup)
Section titled “Step 2: resolve_address (pickup)”Resolve the pickup address through the 4-source cascade.
- Input:
session_id,address(free text),type: "pickup" - Output: ranked
candidates[]with street, city, state, zip, lat, lng, phone, source, confidence - For home address pickup, use the
home_addressobject returned byverify_memberand pass it directly as the structuredpickup_addressinset_booking_details
Step 3: resolve_address (dropoff)
Section titled “Step 3: resolve_address (dropoff)”Resolve the dropoff address.
- Input:
session_id,address(free text),type: "dropoff" - Output: ranked candidates (facilities are boosted for dropoff)
Step 4: set_booking_details
Section titled “Step 4: set_booking_details”Set booking fields incrementally. Can be called multiple times. Addresses must be structured objects.
- 6 required fields:
pickup_address,dropoff_address,appointment_time,trip_type,transport_mode(orservice_typeorservice_type_id),treatment_type(ortreatment_type_id) - Roundtrips also require
return_type(andreturn_timeif scheduled) - Addresses must be passed as structured objects:
{street, city, state, zip_code, latitude, longitude} - Use coordinates from resolve_address candidates or the home_address returned by verify_member
- Service type alias matching supported (e.g.
wc->wav,amb->ambulatory) - Treatment type fuzzy matching supported (case-insensitive contains match + word-prefix/stem match)
- Returns
suggested_promptfor conversational UX andmissing_fieldslist
Step 5: review_trip
Section titled “Step 5: review_trip”Generate a trip summary and TTS voice script for member confirmation.
- Validates all required fields are present
- Sets
draft.LastStep = "review"(sequence gate for confirm_trip) - Returns
voice_scriptfor AI to read aloud
Step 6: confirm_trip
Section titled “Step 6: confirm_trip”Create the real trip — OR a standing order, depending on trip_type on the draft.
- Validates
draft.LastStep == "review"(must review first) - Routes by
trip_type:standing_order→ standing-order creator (folds in the removedcreate_standing_ordertool); otherwise → trip creator - TP Rate Estimation: Automatically calls
trip_estimates_general.Facade.Performto get estimate IDs before trip creation. For roundtrips the outbound and return legs are estimated concurrently. Estimation failure is FATAL for roundtrips (the will-call return leg requires a customer estimate); for one-way it is non-fatal — the trip is still created without estimates. - Passenger counts (
adult_count,pca_count) are set on both outbound and return legs - Calls nemt-trip-service
TripsCreate() - Returns
trip_id,trip_friendly_id,return_trip_id,confirmation_number,spellable_confirmation, plus pickup/dropoff/appointment/transport/return/treatment/companion/special-needs/notes echo fields for AI readback - Deletes only the draft on success — the session stays alive so send_confirmation can authorize the follow-up email
- Populates session post-confirm fields:
LastConfirmedDraft,LastTripIDs,LastFriendlyIDs,IsStandingOrder,StandingOrderID,StandingOrderMeta—send_confirmationreads these to prove the caller is sending an email for THIS session’s trip (cross-session PHI leak guard)
Step 7: send_confirmation (optional)
Section titled “Step 7: send_confirmation (optional)”Email the trip confirmation to the member.
- Pre-condition:
session.LastConfirmedDraftmust be populated (set byconfirm_tripon success) - The supplied
trip_id(orstanding_order_id) MUST be in the session’sLastTripIDs/LastFriendlyIDs/StandingOrderIDallowlist — anything else is rejected as unauthorized - For standing orders, the email includes a branded trip schedule PDF and a blank Aetna mileage reimbursement form
- See the Trip Confirmation Flow for details
Booking Variants
Section titled “Booking Variants”Roundtrip with Will-Call Return
Section titled “Roundtrip with Will-Call Return”set_booking_details: trip_type: "roundtrip" return_type: "will_call"Both legs are created in a single TripsCreate() call. The return leg is OnDemand (no scheduled time). Activate later with activate_will_call.
Roundtrip with Scheduled Return
Section titled “Roundtrip with Scheduled Return”set_booking_details: trip_type: "roundtrip" return_type: "scheduled" return_time: "4:30 PM"With Companion
Section titled “With Companion”set_booking_details: companion_name: "Jane Doe" companion_type: "adult" # adult, child, or attendantTest: /test:companion
Mileage Reimbursement (MR) Trip
Section titled “Mileage Reimbursement (MR) Trip”MR trips require address validation AND driver selection before confirmation:
verify_member --> resolve_address (pickup) --> resolve_address (dropoff) --> set_booking_details (transport_mode: "mileage_reimbursement", addresses, times) --> get_member_drivers --> assign_driver (stores enrollment_id on draft) --> review_trip --> confirm_trip (validates EnrollmentID present, passes as DriverID)Driver types:
self_drive— member drives themselves (relationship: “self”)fnf— Friends & Family driver (relationship: “family”, “friend”)
Key: confirm_trip will FAIL with MISSING_PREREQUISITE if transport_mode=mileage_reimbursement but no driver selected. Always call get_member_drivers → assign_driver before confirm.
Test: /test:mr-booking, /convo:aboba-mr
Home Address Pickup
Section titled “Home Address Pickup”Use the home_address object from the verify_member response and pass it as the structured pickup_address in set_booking_details:
set_booking_details: pickup_address: street: "123 Main St" city: "Springfield" state: "IL" zip_code: "62701" latitude: 39.7817 longitude: -89.6501No resolve_address call needed when using the home address – coordinates are already included.
Error Recovery
Section titled “Error Recovery”| Error | Recovery |
|---|---|
TRIP_ALREADY_EXISTS |
Ask the member for a different date |
INVALID_SCHEDULE |
Reconfirm date and time with the member |
MISSING_PREREQUISITE |
Call the required prerequisite tool first |
INELIGIBLE |
Inform the member, check benefits |
TRIP_LIMIT_EXCEEDED |
Inform the member of their trip limit |
| Weekend appointment warning | Confirm with the member that weekend is intended |