Book, Cancel, Reschedule & Callback

API reference for booking, cancelling, rescheduling appointments, and requesting callbacks via FlowCaptain.

Four endpoints covering the full appointment lifecycle.

These endpoints follow your API key, not your assistant's capabilities. The Cancellation and Rescheduling switches under Assistant › Name › Settings govern what the phone assistant does for callers — and they apply to the autopilot endpoint as well. The endpoints described here, and the MCP tools, remain callable even when that capability is switched off on the assistant. What protects against unwanted changes here is your API key and SMS verification.

The verification code for cancellation and rescheduling is a calendar setting (under Notifications) and applies on every path — phone, API and MCP. Not to be confused with the assistant's verification mode (under Appointments & Calendars), which governs how a caller's identity is checked before the assistant names existing appointments at all.

Each of the following requests requires calendarId as a field in the JSON body. You can find it pre-filled under Calendar › Name › API, section Integration Guide. If your platform wraps the body in an envelope (e.g. Retell's args object), pass it as a URL query parameter instead — ?calendarId=YOUR_CALENDAR_ID — because the API only reads calendarId from the top-level body, the query string, or route parameters, never from a nested args object.


Book an Appointment

Creates a new appointment in the connected Google Calendar. FlowCaptain automatically verifies that the requested slot is actually available before booking.

POST /api/v1/book-appointment

Request body:

{
  "calendarId": "YOUR_CALENDAR_ID",
  "dateTime": "2026-03-03T10:00:00+01:00",
  "callerName": "Max Mustermann",
  "callerIdNumber": "+4917604069001",
  "reason": "Initial consultation"
}
FieldTypeRequiredDescription
calendarIdstringYesYour calendar ID — determines which calendar the request targets
dateTimestringYesDesired appointment time as an ISO 8601 timestamp
callerNamestringYesName of the person booking
callerPhonestringNoPhone number as spoken by the caller (for notifications)
callerIdNumberstringNoCaller ID from telephony (recommended — for appointment lookup and SMS)
reasonstringNoAppointment reason/description
serviceNamestringNoDesired service — determines the appointment duration
serviceNamesstring[]NoMultiple desired services
languagestringNo"de" or "en" (default: "de")

Success response (with "language": "en"):

{
  "action": "booked",
  "success": true,
  "humanReadable": "Appointment booked successfully: Tuesday, 03.03 at 10:00 AM",
  "result": "Appointment booked successfully",
  "day": "Tuesday",
  "date": "03.03",
  "time": "10:00",
  "appointmentId": "550e8400-e29b-41d4-a716-446655440000"
}

Drop-off calendar: On a drop-off calendar only the day counts. The response then has no time field but serviceType: "drop_off" — with a named service e.g. "humanReadable": "Job scheduled: Inspection on Tuesday, 03.03" and serviceName.

Slot taken: The response is action: "suggest" with alternative suggestions (time1–time3) — same as the availability check. If the day is fully booked, you get action: "reject".

Service not found: If serviceName matches no service of this calendar, the API responds with action: "suggest_service" (matching suggestions in suggestedServices) or with action: "clarify"; both responses include the list services of bookable services. Services of the type No appointment are never bookable.

Approval enabled: If the calendar uses Require Approval, the response is action: "pending_approval" instead of booked (e.g. "humanReadable": "Your appointment request for Tuesday, 03.03 at 10:00 AM has been submitted and is being reviewed.") — the appointment is entered as a request and only becomes final once the calendar owner approves it. On drop-off calendars the time is left out here too.


Cancel an Appointment

Cancels an existing appointment. The event is marked as cancelled in Google Calendar but not deleted — so it remains visible for your records.

POST /api/v1/cancel-appointment

Request body:

{
  "calendarId": "YOUR_CALENDAR_ID",
  "callerIdNumber": "+4917604069001",
  "callerName": "Max Mustermann",
  "appointmentDate": "2026-03-03"
}
FieldTypeRequiredDescription
calendarIdstringYesYour calendar ID — determines which calendar the request targets
callerIdNumberstringNo*Caller ID for the appointment lookup
callerPhonestringNo*Phone number as spoken by the caller
callerNamestringNo*Helps identify the appointment
appointmentDatestringNoDate of the appointment (ISO or natural language)
verificationCodestringNoSMS verification code, if requested (see below)
languagestringNo"de" or "en" (default: "de")

*FlowCaptain uses multiple attributes to identify the right appointment. The more information you pass (caller ID, name, date), the more reliable the match. If several appointments match, the API responds with action: "clarify" and an appointments[] list for follow-up.

Success response:

{
  "action": "cancelled",
  "success": true,
  "humanReadable": "Appointment cancelled successfully: Tuesday, 03.03 at 10:00 AM",
  "result": "Appointment cancelled successfully",
  "day": "Tuesday",
  "date": "03.03",
  "time": "10:00"
}

SMS verification: If the Verification Code is enabled on the calendar, the API requires a code before cancelling:

{
  "action": "verification_required",
  "success": false,
  "humanReadable": "For security, we sent a code to ***4567. Please provide the 4-digit code.",
  "verificationPhone": "***4567"
}

The code is sent via SMS to the number on file. Repeat the request with the verificationCode field. A wrong code results in action: "verification_failed".


Reschedule an Appointment

Moves an existing appointment to a new time. FlowCaptain verifies availability at the new time before rescheduling.

POST /api/v1/reschedule-appointment

Request body:

{
  "calendarId": "YOUR_CALENDAR_ID",
  "callerIdNumber": "+4917604069001",
  "callerName": "Max Mustermann",
  "newDateTime": "2026-03-04T14:00:00+01:00"
}
FieldTypeRequiredDescription
calendarIdstringYesYour calendar ID — determines which calendar the request targets
newDateTimestringYesNew appointment time as an ISO 8601 timestamp
callerIdNumberstringNo*Caller ID for the appointment lookup
callerPhonestringNo*Phone number as spoken by the caller
callerNamestringNo*Helps identify the appointment
appointmentDatestringNoDate of the existing appointment (ISO or natural language)
verificationCodestringNoSMS verification code, if requested
languagestringNo"de" or "en" (default: "de")

*Appointment lookup and SMS verification work the same as for cancellation.

Success response:

{
  "action": "rescheduled",
  "success": true,
  "humanReadable": "Appointment rescheduled successfully: from Tuesday, 03.03 at 10:00 AM to Wednesday, 04.03 at 2:00 PM",
  "result": "Appointment rescheduled successfully",
  "day": "Wednesday",
  "date": "04.03",
  "time": "14:00",
  "previousDay": "Tuesday",
  "previousDate": "03.03",
  "previousTime": "10:00"
}

New time taken: The response is action: "suggest" with alternative suggestions.


Request a Callback

Requests a callback from the business owner when the voice bot cannot resolve the caller's issue.

POST /api/v1/request-callback

Request body:

{
  "calendarId": "YOUR_CALENDAR_ID",
  "callerName": "Max Mustermann",
  "callerPhone": "+4917604069001",
  "issueDescription": "Wants a callback",
  "language": "en"
}
FieldTypeRequiredDescription
calendarIdstringYesYour calendar ID — determines which calendar the request targets
callerNamestringNo*Name of the caller
callerPhonestringNo*Phone number of the caller
callerIdNumberstringNo*Caller ID from telephony
issueDescriptionstringNoShort description of the issue (max. 500 characters)
languagestringNo"de" or "en" (default: "de")

*Pass at least one of callerName, callerPhone, or callerIdNumber so the business can call back.

Success response:

{
  "action": "callback_requested",
  "success": true,
  "humanReadable": "Callback request submitted",
  "result": "Callback request submitted"
}

The business owner receives an email with the caller's contact details — sent to the calendar's Notification Email (under Notifications). If no email is set there, the response does not promise a callback. Callback requests are rate-limited to protect against abuse.