Voice Automation Intermediate

Voice Agent Confirms Booking Without an Appointment

Gate voice-agent confirmations on successful CRM appointment creation, validate empty payloads, route new contacts correctly, and alert on failed writes.

Voice Automation Intermediate Updated August 12, 2026

Voice agent says "you're all set" but no appointment is created

Summary

The agent speaks a confirmation off its own words, not off a real write. Gate every confirmation behind the CRM's created-appointment result, add a validation branch so an empty payload can't crash the booking step, and alert on any failed write. After that, a bad call ends with a spoken correction instead of a false confirmation.

Symptoms

  • Callers are told "you're all set" but no appointment record exists.
  • The booking workflow throws on the upsert step; the run shows an invalid URL (a relative /contacts/upsert with no base URL).
  • An anonymous or new caller produces a PUT /contacts/ 404.
  • The team hears about the miss from the customer, not from an alert.

Environment

  • n8n handling the booking, a marketing CRM for contacts/appointments, and an AI voice agent that collects fields during the call.

Cause

The agent flags fields as confirmed and speaks a confirmation regardless of what the automation returns. When phone, name, city and ZIP arrive blank, validation returns no config, so the upsert step assembles an invalid URL and crashes — but because nothing gated the spoken confirmation, the agent still said the booking was done.

Solution

  1. Add a "Validation OK?" branch immediately after the parse step.
  2. On the failure side, return the validation response as text so the agent gets a spoken correction and never reaches a CRM call with empty config.
  3. On the success side, continue to the existing upsert path unchanged.
  4. For the update path, change the branch condition from exists to is not empty so anonymous/new callers are routed to create instead of a 404'd update, and turn on Continue On Fail on the update node as a backstop.
  5. Trigger the confirmation SMS/email only when the CRM returns a created appointment.
  6. Wire each failure branch to post failed_booking (caller + error) to the notification dispatcher so the team is alerted instantly.

Example

Booking step, guarded:

Parse Booking Request
   └─ Validation OK?
        ├─ false → Respond Validation Error  ={{ JSON.stringify($json) }}   (agent re-asks)
        └─ true  → GHL Upsert Contact → Book Appointment → Handle Result
                        └─ success:true → send confirmation
                        └─ any failure → POST dispatcher {outcome:"failed_booking"}

Verification

Re-run the same three-call scenario: an empty/partial payload ends cleanly at the validation response with no crash and no confirmation; a full valid booking creates the appointment and fires the confirmation off the real write; an anonymous caller creates a contact instead of 404ing; and a failed-write alert lands in the test inbox.

Caveats

  • Keep edits additive (no node deletions) so production originals stay intact.
  • This hardens the automation side only. The agent must actually send the collected values and confirm only on success — that lives in the conversation config, not here.
  • Leave test mode on during the build so alerts route to a test inbox, not the client.
  • Why a Zapier or GHL webhook can't return a live answer to a voice agent mid-call.
  • Preventing double-booking when the platform has no concurrency control.

Was this article helpful? Thanks for your feedback.

Ready to build your first automation?

Get started with Octacer and transform how your team works.

Schedule Consultation