# Callback scheduling (/docs/agents/scheduling)

> For the complete documentation index, see [llms.txt](https://docs.tandemcx.ai/llms.txt). Any page on this site can be fetched as Markdown by appending `.md` to its URL.

<Callout type="info">
    **This page is being rolled out.** If **Scheduling** isn't in your sidebar, it isn't enabled for
    your organization yet — contact support.
</Callout>

## What a calendar is

A calendar is a public booking page where customers pick a time for a callback. It has one set
of weekly hours, one time zone, and a limit on how many callbacks can share a time slot. The
calendar does not belong to a person: whoever handles the callbacks works from its bookings.

Calendars live under **Scheduling → Calendars**. The list shows each calendar's status
(**Active** or **Paused**), its booking link, and how many confirmed callbacks it has in the next
7 days. Each row's actions copy the booking link, open the booking page in a new tab, and edit the
calendar. On a phone or a narrow window each calendar is a card instead, with its status beside
its count as `N in the next 7 days`. The calendar's name opens it, so a card has no edit icon.
Booked callbacks from every calendar are under **Scheduling → Bookings**.

## Creating a calendar

On **Scheduling → Calendars**, click **New Calendar** and fill in three fields:

- **Calendar name** — up to 100 characters. Customers see it on the booking page.
- **Booking link** — the last part of the page's address. It comes prefilled with a random
  five-character link; change it to something readable if you like. A link is 3 to 40 lowercase
  letters, digits, or dashes, and can't start or end with a dash. A few words the booking page
  uses itself (`m`, `embed`, `assets`, `api`, `static`, and some file names) are reserved, and
  each link can belong to one calendar only: the field says `That link is already in use` when
  another calendar has it. A link stays with your organization after its calendar is deleted or
  switches to another link: another organization can't take it, and any of your calendars can.
- **Time zone** — the zone your hours are in. Customers see times in their own zone.

**Create Calendar** opens the new calendar's editor. It starts with these settings:

| Setting                          | Starts as                                                              |
| -------------------------------- | ---------------------------------------------------------------------- |
| Weekly hours                     | Monday to Friday, 9:00–17:00                                           |
| Slot duration                    | 30 minutes                                                             |
| Slot capacity                    | 1                                                                      |
| Lead time                        | No minimum                                                             |
| Days shown                       | 3                                                                      |
| Paging                           | On, 14 days ahead                                                      |
| ASAP option                      | On                                                                     |
| Email                            | Optional                                                               |
| Notes                            | Optional                                                               |
| Reasons                          | None (not asked)                                                       |
| Max upcoming callbacks per phone | 3                                                                      |
| Email messages                   | On                                                                     |
| SMS                              | Off                                                                    |
| Reminders                        | 1 day and 1 hour before                                                |
| Calls enabled                    | Off                                                                    |
| Sender name                      | Your organization's name, or the calendar name if that isn't available |

The calendar takes bookings as soon as it is created. The editor has six tabs: **Basic Info**,
**Availability**, **Booking Page**, **Notifications**, **Call**, and **Webhooks**. The first five
share one **Save**. Changes on **Webhooks** save as you make them (see
[Webhooks](/docs/agents/scheduling/webhooks)), **Notifications** is covered in
[Booking messages](/docs/agents/scheduling/messages), and **Call** is covered in
[Calls](/docs/agents/scheduling/calls). If the calendar changes while your save is
in progress, **Save** says `This calendar changed. Reload and try again.` and saves
nothing; reload the page and make the change again.

## Basic Info

- **Calendar name** and **Booking link** — as above. Changing the link breaks the old one,
  including links in messages you have already sent. The old link stays reserved to your
  organization, so you can change back to it.
- **Color** — the dot beside the calendar's name in the list, the accent color of its
  booking page, and the left border of its callbacks on the Bookings calendar view.
- **Active** — turn off to pause the calendar. See
  [Pausing or deleting a calendar](#pausing-or-deleting-a-calendar).

## Availability

- **Time zone** — the zone the hours below are in.
- **Weekly hours** — one row per window, each with a **Day**, a **Start**, and an **End**.
  **Add Hours** adds a row copied from the last one. A day can have several windows (9:00–12:00
  and 13:00–17:00, for example), but windows on the same day can't overlap, and each must end
  after it starts on the same day. A day with no hours takes no callbacks.
- **Blocked dates** — single days with no callbacks, such as a closure. Pick a date to add it.
- **Holidays** — tick any of New Year's Day, MLK Day, Presidents' Day, Memorial Day, Juneteenth,
  Independence Day, Labor Day, Columbus Day, Veterans Day, Thanksgiving, and Christmas Day. A
  ticked holiday blocks the date it falls on. When a holiday falls on a weekend, the weekday
  observed in its place is not blocked; add that day under **Blocked dates** if you close on it.
- **Lead time** — how far ahead a time must be to show: no minimum, 15 or 30 minutes, 1, 2,
  or 4 hours, or 1 day. It does not apply to **As soon as possible**.
- **Slot duration** — 15, 30, 45, or 60 minutes. Times start at the beginning of each window
  and step by this length. A window that doesn't divide evenly leaves its remainder unused: with
  30-minute callbacks, a 9:00–10:45 window offers 9:00, 9:30, and 10:00.
- **Slot capacity** — how many customers can book the same time, from 1 to 1,000, or
  **Unlimited**. A time that is full stops showing.

## Booking Page

- **Days shown** — how many days of open times the page shows at once, from 1 to 7.
- **Paging** — lets customers page forward past the first days.
- **Booking window (days)** — shown when later days are on, from 1 to 60. A customer can book
  through the end of the day that many days after today, in the calendar's time zone. With 14,
  someone looking on the 1st of the month can book any open time up to the end of the 15th.
- **ASAP option** — lets a customer ask to be called now instead of picking a
  time. See [What customers see](#what-customers-see).
- **Email** — **Required**, **Optional**, or **Hidden**.
- **Notes** — **Optional** or **Hidden**. A customer can write up to 1,000 characters.
- **Reasons** — choices for why someone wants a callback, up to 20, each up to 80 characters.
  Leave it empty and the page doesn't ask. When there are reasons, picking one is optional.
- **Max upcoming callbacks per phone** — how many callbacks one phone number can hold on this
  calendar at a time, from 1 to 50. Only confirmed callbacks that haven't happened yet count, and
  a customer past the limit sees
  `This number already has the most callbacks this calendar allows.`

The **Share** section at the bottom has the saved booking link and the two embed snippets. See
[Sharing and embedding](/docs/agents/scheduling/sharing-and-embedding).

## What customers see

The booking page opens on the times. It shows them in the time zone of the customer's browser,
with a picker to change zone. If the browser reports a zone the platform doesn't recognize, the
page uses the calendar's zone and says so. Changing the zone clears any time the customer has
picked, because that time may not be on the new zone's page.

The day cards are the next days that have at least one open time, so a weekend or a blocked date
doesn't use up a card. When the cards don't all fit, as on a phone, the arrows beside them move
through the hidden cards first and select the first one they bring into view. Past the last card
they show the next days; before the first, the earlier days, ending on the last of them. When **As
soon as possible** is on and the current moment falls inside your hours in a time slot that has
room, a **Call me now** card (`We'll call you shortly`) sits above the days, with `or pick a time`
below it. Nothing is selected to start with. The customer taps **Call me now** or a time, and the
**Continue** button at the bottom of the page names the choice, such as `Continue · Call me now`.
**Continue** is off until something is picked.

**Continue** opens a form that asks for a full name and a phone number, both required, and for an
email, a reason, and notes as set on the **Booking Page** tab. An **As soon as possible**
callback is booked starting at the moment the customer submits, and takes a place in the current
time slot.

The browser remembers the name, phone number, and email for the customer's next booking. Notes
and the reason are not kept.

If nothing is open, the page says `No times are available right now. Check back soon.` If two
customers go for the last place in a slot, the second sees
`That time was just taken. Pick another.` and the times reload.

## The confirmation

After booking, the page shows **You're booked**, the calendar's name, and the time (or
`We'll call you shortly` for **As soon as possible**), followed by:

- **Add to calendar** and **Google Calendar** for a picked time. **Add to calendar** downloads an
  `.ics` file. An **As soon as possible** callback has neither.
- **What happens next**, with up to three lines: when Tandem will call the number the customer
  entered, the number the call comes from, and what confirmation was sent.
- Your **Note** from the **Notifications** tab, if you set one.
- The customer's details, and **Reschedule** and **Cancel callback** links. **Cancel callback**
  opens the callback's page on the cancel step.

The confirmation line follows what the calendar's settings allow, as checked when the customer
books:

| Line                                                                    | When                   |
| ----------------------------------------------------------------------- | ---------------------- |
| `We texted and emailed you this confirmation with a link to change it.` | Both channels can send |
| `We texted you this confirmation with a link to change it.`             | Only SMS can send      |
| `We emailed you this confirmation with a link to change it.`            | Only email can send    |

Email can send when **Email messages** is on, the customer gave an address, and your organization
has a verified default sender. SMS can send when **SMS** is on and the calendar's text number has
texting enabled. The line says a message can go out, not that it did: the daily and per-number
caps in [Booking messages](/docs/agents/scheduling/messages) can still skip one after the page has
said so, and a customer who opted out of your texts gets no text even though the page says one
was sent. The page does not check opt-outs, so it never reveals whether a number opted out.

When neither can send, the page says `We didn't send you a confirmation. Bookmark this page or
copy the link to change or cancel later.` with a **Copy link** button. On a hosted page, the
address of the page changes to the callback's own page after booking, so a bookmark or reload
lands there. In an embed the sentence reads `We didn't send you a confirmation. Copy the link to
change or cancel later.` and the host page's address is left alone. If the browser blocks
copying, **Copy link** shows the link in a field, selected, to copy by hand.

The call line, `The call comes from {number}.`, shows the **Number customers see** from the
calendar's **Call** tab. It is omitted when none is set, or when the number has since been
deleted. See [Calls](/docs/agents/scheduling/calls#number-customers-see).

Every booking page carries a **Powered by Tandem** link at the bottom.

## Rescheduling and cancelling

The **Reschedule** and **Cancel callback** links on the confirmation page open the callback's own
page.
The confirmation and reminder messages carry the same link (see
[Booking messages](/docs/agents/scheduling/messages)). The page shows the same **What happens next** lines
as the confirmation (the phone number is partly hidden, and the confirmation line is not shown),
and your **Note**. From it a customer can pick a new time, or cancel with an optional reason of
up to 500 characters. After a move the page says `Moved to {time} {time zone name}.`, or `Moved. We'll call you
shortly.` for **As soon as possible**.

A scheduled callback can be changed until it starts. An **As soon as possible** callback can be
changed until its callback length has run out. After that the page says
`This callback time has passed.` with a link to book a new time. The link itself stops working
7 days after the callback ends, and then shows `This link is no longer valid.` A cancelled
callback's page says `This callback is cancelled.` with the same link to book a new time.

## The Bookings page

**Scheduling → Bookings** lists callbacks across all your calendars. Filter by calendar, by date
range (today through 14 days ahead to start), and by **Confirmed**, **Cancelled**, or **Needs
Follow-up**. **Load More** at the bottom fetches the next page.

Each row shows when the callback is, in your time zone with the customer's time and zone under
it, plus the calendar, the customer's name and phone number, and whether it is **Scheduled** or
**As soon as possible**.

The **Status** column says what happened to the callback's call:

- **Upcoming** — the callback's time hasn't arrived.
- **Due now** — the time has passed and no call has been placed yet. When the calendar places
  calls, Tandem tries until 15 minutes after the start, or until the slot ends for an **As soon
  as possible** callback.
- **Call started** — Tandem started the calendar's workflow, which places the call. It doesn't
  say whether the customer picked up. Open the callback's conversation from its sidebar to see
  what happened on the call.
- **Call failed** — the workflow couldn't be started.
- **Not called** — Tandem skipped the call. The reason shows when you hover over the badge, for
  example that it was too late to call, or that calls were turned off after the callback came
  due.
- **Call status unknown** — Tandem lost track of the request. Check **Call Logs**.
- **No call made** — the time passed with no call placed. A calendar with calls turned off on
  its **Call** tab never places one, so its callbacks go from **Due now** to this.
- **Handled** — someone marked it handled (see below).
- **Cancelled**.

Click a row to open the callback's sidebar: its details, its history of moves and cancellations,
and the messages sent to the customer about it (see
[Seeing what was sent](/docs/agents/scheduling/messages#seeing-what-was-sent)).

**New Callback** at the top right books a callback for a customer. Pick a calendar and one of its
open times, shown in your time zone, then enter the customer's name and phone number, and their
email, reason, and notes when the calendar's booking page asks for them. **Customer time zone**
sets the zone their messages show times in; it starts at the calendar's zone. The calendar's
rules apply as on the booking page: only open times are offered, and a phone number that already
has the most callbacks the calendar allows is refused with `This number already has the most
callbacks this calendar allows.` The customer gets the same confirmation, reminders, and call as
when they book themselves, and the callback's sidebar shows **Booked By** **Admin**.

**Follow Up** in a callback's sidebar opens **Schedule Follow-up**, the same form with the
calendar, name, phone number, email, reason, and customer time zone filled in from the callback.
It is at the top of every callback's sidebar, beside **Reschedule** and **Cancel Callback** while
the callback is still open. **Cancel Callback** asks you to confirm, then cancels it, as the icon
in the **Actions** column does.

The calendar icon at the right of the filters switches to a calendar of the same callbacks: a
week grid in your time zone. **Day** shows a single day. The arrows move back or forward a week
(or a day), and **Today** returns to the current one. The calendar and status filters still
apply. With **All calendars** selected, a row is half an hour. With one calendar selected, a row
is that calendar's time slot length (15 minutes for a 45-minute slot, 30 minutes for a 60-minute
slot whose window starts on the half hour, such as 9:30, and 15 minutes when a window starts at a
quarter hour that the slot length doesn't line up with, such as 9:15 with 30-minute slots). A row with more than two
callbacks shows two and a **+N more** button that opens a list of every callback in that row.
Past and cancelled callbacks are dimmed. Click a callback to open its sidebar. Drag a callback
to another row to open **Reschedule** with the first open time in that row selected. With one
calendar selected, a row that a time covers selects that time, even when the row starts after
the time does. Nothing
changes until you click **Move Callback**. When the row has no open time, the dialog says so and
lists the calendar's open times to pick from. Past and cancelled callbacks can't be dragged. The
list icon goes back to the list, with its date range as you left it.

A confirmed callback has two icons in its **Actions** column until its time arrives, and one
after. Hover over or focus one for its name.

- **Reschedule** (a calendar with a pencil) — opens the calendar's open times in your time zone.
  Pick a day from the row at the top, then a time, and click **Move Callback**. **Earlier Times**
  and **Later Times** page through more days.
- **Cancel Callback** (a calendar with an X) — asks you to confirm, then cancels it.
- **Schedule Follow-up** (a calendar with a circular arrow) — opens **Schedule Follow-up** for
  the same customer. Shown in place of the other two once the callback's time has passed or it
  is cancelled.

A scheduled callback loses both actions at its start time. An as-soon-as-possible callback
loses them when its slot ends. A callback that has passed still appears under the **Confirmed**
filter.

The customer gets a rescheduled or cancellation notice by the channels the calendar's
**Notifications** tab has on.

### Needs Follow-up

**Needs Follow-up** in the status filter lists confirmed callbacks that someone still has to
deal with: **Call failed**, **Not called**, **Call status unknown**, and **No call made**. With
no date range in the link, it shows the last 14 days through today. It combines with the
calendar filter and the date range, and the calendar view honors it.

Open one and click **Mark Handled** when someone has dealt with it. The callback leaves the
list and its badge reads **Handled**. Marking a callback handled doesn't cancel it, doesn't
message the customer, and doesn't send a webhook. **Reopen** puts it back on the list, unless the
callback was cancelled. The callback's history shows `Marked handled` and `Reopened`.

**Follow Up** from a callback that needs follow-up marks it handled when the new
callback is booked, and its sidebar links to the new one with **View follow-up**. If the
callback was cancelled or handled in the meantime, the new callback is still booked and the
original is left alone.

Rescheduling a callback clears its call result and its handled mark, so the callback at its new
time starts as **Upcoming**.

### Open times on the calendar

Pick one calendar in the filter and its open times show on the grid. Open times are tinted, and
times that are full are greyed. A legend above the grid reads **Open** and **Full**. A time that
isn't bookable at all (before the calendar's lead time, past how far ahead it takes bookings, or
outside its weekly hours) is left plain.

On a calendar with more than one seat per time, the row where a time starts carries a note once
a seat is booked: `2 of 3` for two of three seats booked, `2 booked` when the calendar has no
seat limit, and `Full` when no seats are left. A time with no bookings and a one-seat calendar
show no note.

Click a row that an open time covers to open **New Callback** with that time selected, even
when the row starts after the time does (a 45-minute time spans three 15-minute rows). Rows of
full or unbookable times can't be clicked. With **All calendars** selected nothing is shaded, the grid says
`Pick a calendar to see its open times.`, and a click on any empty half hour opens **New
Callback** with the first open time in that half hour selected, as before. If the calendar's open
times don't load, the page says `Couldn't load open times.` and the grid works as it does with
**All calendars**, except that rows follow the calendar's slot length.

A paused calendar shows `This calendar is paused. Customers can't book it.` and no open times.

### On a phone

On a phone or a narrow window the Bookings page changes:

- The list shows each callback as a card: time, status, name, calendar, and phone number. Tap a
  card to open its sidebar.
- The filters wrap, and the calendar filter takes a full-width line of its own.
- The calendar shows one day as a list, in time order, instead of a grid. Each callback is a card;
  tap it to open its sidebar. The arrows and **Today** move one day. The **Week** view isn't
  offered on a phone.
- With one calendar selected, the list also shows its open times, with notes such as `2 of 3`.
  **New Callback** on an open time opens the form on that time. A full time says `Full`.
- The page scrolls as one, so the title and filters scroll away.
- Dragging is off. Open the callback and use **Reschedule** in its sidebar.
- **Reschedule** and **Cancel Callback** are in the sidebar, which opens over the page.

## Pausing or deleting a calendar

Turn off **Active** on **Basic Info** and save to pause a calendar. Its booking page
then says `This calendar isn't taking bookings right now.` Customers who already booked can
still open their callback's page and cancel, but there are no times to move to. Turn
**Active** back on to reopen it with the same link.

To delete a calendar, click the trash icon on its row in **Calendars**, or open it and click
**Delete Calendar** at the bottom of **Basic Info**. Deleting removes the calendar and its
booking link stops working. The link stays reserved to
your organization: a new calendar of yours can use it, and no other organization can. A
calendar with upcoming callbacks can't be deleted: cancel them on the **Bookings** page first,
or pause it instead.

## Booking from an agent

A voice or chat agent can check a calendar's open times and book a callback for the caller. Turn
on **Schedule callbacks** on the agent's **Built-in Tools** row and pick the calendar. Agent
bookings follow the same calendar rules as the booking page, except that an agent can't book **As
soon as possible**, never books a time less than 15 minutes away, and books at most one callback
per call or chat. They show **Booked By**
**Agent** on **Bookings**. See [Schedule
callbacks](/docs/agents/voice-agents/built-in-tools#schedule-callbacks).

## Next steps

- [Sharing and embedding](/docs/agents/scheduling/sharing-and-embedding) — put the booking page
  on your own website.
- [Booking messages](/docs/agents/scheduling/messages) — the confirmation, reminders, and notices
  customers get.
- [Webhooks](/docs/agents/scheduling/webhooks) — send booking events to your own systems.
- [Calls](/docs/agents/scheduling/calls) — have Tandem call the customer when a callback is due.
