WorkestraDocs
PlatformCalendar & Scheduling

Reschedule & Cancel

How attendees and hosts manage bookings after they're confirmed — token-protected pages, no support ticket required.

Every confirmed booking has two associated public URLs that don't require login:

  • /book/reschedule/<token> — pick a different slot
  • /book/cancel/<token> — cancel with an optional reason

These links are included in the confirmation email. The attendee can use them anytime up until the meeting starts; the host gets the same links in their notification email.

Reschedule page

Screenshot needed — /book/reschedule/<token> with the new slot picker and an explanation of which booking is being moved

How tokens work

Each scheduling_calendar_events row has a unique reschedule_token — a 32-char random hex string generated at booking time. The token is the only credential needed to act on the booking, so:

  • Treat the URL like a password. Anyone with the link can move or cancel the meeting.
  • Tokens rotate on reschedule. When a booking is rescheduled, the new event gets a new token. The old token is dead.
  • Tokens stay valid until the meeting starts. After that, neither page accepts the token — past meetings can't be self-modified by attendees.

Rescheduling

When the attendee opens /book/reschedule/<token>:

  1. The original slot is shown for context
  2. The slot picker reloads with the same availability rules as the booking link
  3. They pick a new slot
  4. Workestra:
    • Marks the original event as rescheduled (kept for audit trail; not double-counted in dashboards)
    • Creates a new confirmed event at the new time, with a fresh token
    • Updates the Google Calendar event in place (if the link uses Google Calendar)
    • Sends a "rescheduled" email to attendee + host with the new .ics

Same buffers, same min-notice, same max-days-ahead. The attendee can't pick a slot the host wouldn't normally offer.

Cancelling

When the attendee opens /book/cancel/<token>:

  1. They confirm and optionally type a reason
  2. Workestra marks the event as cancelled and stores the reason on the row
  3. Deletes the corresponding Google Calendar event
  4. Sends a "cancelled" email to attendee + host

Cancelled events stay in the database — they don't disappear. They show up in the Cancelled tab of the calendar dashboard, and they're available for reporting.

What the host can do

Hosts can also cancel from inside Workestra by visiting the calendar dashboard and clicking through to the event. Reschedule on behalf of the attendee is not yet a one-click action; today the host typically clicks the reschedule link from their notification email or sends the attendee a fresh link.

The auto-created CRM deal (if create_deal is enabled on the link) is not automatically cancelled when the meeting is cancelled. The deal stays in the pipeline — it's now a "no-show" or "cancelled before meeting" lead, which is meaningful sales data, not noise. Move it to a closed-lost stage manually if it's truly dead.

Idempotency

Both endpoints are idempotent:

  • Cancel twice → second call is a no-op, returns the same cancelled row
  • Reschedule twice in a row → second call rejects with "booking already rescheduled" (the token is dead after the first reschedule; the new event has its own new token)

Reconfirmation flow

A common workflow pattern is to ask "are you still attending?" 24 hours out and auto-cancel if the attendee doesn't click confirm. See Workflows → Reconfirmation flow for setup.

When configured, the attendee gets a /book/reconfirm/<token> URL in their reminder email or SMS. Clicking it sets reconfirmed_at on the booking row. If the deadline passes without a click, the booking is cancelled and a "your booking was cancelled because you didn't confirm" email goes out.

Calendar-side delete and reschedule sync

When a host deletes or moves a meeting directly in their Google or Microsoft calendar (not through Workestra), the change syncs back automatically.

Workestra registers a watch on Google Calendar (/api/calendar-providers/webhook/google) and a Graph API subscription on Microsoft (/api/calendar-providers/webhook/microsoft) for every connected user. When the calendar fires a change notification:

  1. Workestra fetches the affected event by its provider event id
  2. If it's deleted or has a status of cancelled, Workestra calls cancelBooking() on the matching scheduling_calendar_events row
  3. If the time changed, Workestra calls rescheduleBooking() with the new times
  4. The standard cancel/reschedule emails go out to the attendee

This means a host can drag a Workestra meeting to a different time in Google Calendar and the attendee will get the rescheduled email automatically. No separate "sync changes" step.

The watch tokens are renewed daily by /api/cron/calendar-subscriptions-renew. If a host's calendar token expires (re-auth needed), the <CalendarDisconnectBanner> surfaces on /calendar and /settings/integrations until they reconnect.

What about no-shows?

A "no-show" is just a status the host sets on a past confirmed event. There's no automated detection — Workestra doesn't know whether an attendee actually joined the call. From the calendar dashboard, find the past meeting, mark it No-show. It moves to the No-shows tab and out of the past-meetings count.

This is intentional: in many use cases (interviews, support escalations), "they came but were 20 min late" still counts as attended for SLA purposes, so we don't want to auto-mark from a calendar signal.

  • Booking Links — how confirmation, reminder, reschedule, and cancel emails are wired
  • Workflows — reconfirmation, no-show follow-up, and the trigger × action matrix
  • Calendar Dashboard — the host's view of confirmed / past / no-show / cancelled meetings