Scheduling links and bookings
Offer bookable slots across one or more accounts' calendars, book them for invitees and cancel bookings.
A scheduling link is a stored booking configuration: which accounts can be booked, for how long and when. List its open slots, show them to an invitee, and book the one they pick; Workwae creates the calendar event.
Links belong to the tenant, not to one account. They need the calendar module in the plan (403 plan_module_unavailable).
How it relates to finding a time
Find a time answers a one-off question: when are these people free in this range? A scheduling link stores that question (accounts, hours, buffers, notice, cap) so slots can be listed again at any time, and adds booking: re-checking the slot, creating the event and recording the booking.
Create a link
curl -X POST "https://api.workwae.com/v1/scheduling-links" \
-H "Authorization: Bearer $WORKWAE_API_KEY" \
-H "content-type: application/json" \
-d '{
"name": "Sales intro",
"accountIds": ["'"$ALICE_ACCOUNT_ID"'", "'"$BOB_ACCOUNT_ID"'"],
"mode": "any",
"durationMinutes": 30,
"timeZone": "America/New_York",
"hours": {
"mon": [{ "start": "09:00", "end": "12:00" }, { "start": "13:00", "end": "17:00" }],
"wed": [{ "start": "09:00", "end": "17:00" }]
},
"bufferAfterMinutes": 10,
"minimumNoticeMinutes": 240,
"maxPerDay": 6,
"title": "Intro call with {{invitee}}",
"onlineMeeting": true
}'Who is booked
accountIds lists 1 to 20 of the tenant's accounts, each once. An unknown account answers 422 unknown_account, listing it in data.
mode | Slot is offered when | The booking |
|---|---|---|
all (default) | Every account is free. | One event on the first account, inviting the others. |
any (round-robin) | At least one account is free. | Hosted by the free account with the fewest bookings of this link in the last 30 days (any status); ties go to the earliest in accountIds. |
When slots are offered
| Field | Default | Meaning |
|---|---|---|
timeZone | required | IANA zone that hours, step and daily cap are read in (invalid_time_zone). |
durationMinutes | 30 | Slot length, 5 to 1440. |
stepMinutes | 30 | Slots start on multiples of this many minutes after local midnight. |
windowDays | 14 | Days ahead slots are offered, up to 365. |
hours | Mon–Fri 09:00–17:00 | Up to 8 windows per weekday; a day left out has none. Each window's end must be after start (invalid_working_hours). |
bufferBeforeMinutes, bufferAfterMinutes | 0 | Free time an account needs around the slot, up to 1440. |
minimumNoticeMinutes | 0 | How far ahead a slot must start, up to 86400 (60 days). |
maxPerDay | null | Most bookings per local day, 1 to 1000; null is no limit. |
The event a booking creates
| Field | Default | Meaning |
|---|---|---|
title | {{invitee}} | Event subject, up to 255 characters. |
description | none | Plain-text description, up to 10,000 characters. |
location | none | Event location. |
onlineMeeting | false | Teams (Microsoft 365) or Meet (Google) link. |
onlineMeetingService | none | zoom or webex, created by Workwae; needs the meetings module. See Meetings. |
{{invitee}} and {{inviteeEmail}} in title and description are replaced at booking time. Setting both onlineMeeting and onlineMeetingService answers multiple_meeting_options.
Manage links
GET /v1/scheduling-linkslists links newest first;GET /v1/scheduling-links/{linkId}reads one.PATCH /v1/scheduling-links/{linkId}changes only the fields given;nullclearsdescription,location,onlineMeetingServiceandmaxPerDay. Existing bookings keep their events.DELETE /v1/scheduling-links/{linkId}deletes the link and its bookings. Their events are left as they are.
A missing link answers 404 scheduling_link_not_found.
List slots
curl "https://api.workwae.com/v1/scheduling-links/$LINK_ID/slots?from=2026-11-02T00:00:00Z&to=2026-11-09T00:00:00Z" \
-H "Authorization: Bearer $WORKWAE_API_KEY"{
"items": [
{
"start": "2026-11-02T14:00:00.000Z",
"end": "2026-11-02T14:30:00.000Z",
"accountIds": ["…alice", "…bob"]
}
]
}A slot is listed when it is:
- inside the link's window (
windowDaysahead of now, in its time zone) and not before the minimum notice; - inside the link's hours;
- clear of each account's own calendar once widened by the buffers;
- under
maxPerDay.
from and to narrow that range; to not after from, or a range longer than the link looks ahead, answers 400 invalid_range. limit caps the answer (default 200, up to 1000). A slot's accountIds are the accounts free for it, in the link's order.
Book a slot
Pass a slot's start and the invitee. Workwae re-checks the slot, picks the account, creates the event with the invitee as an attendee, and sends booking.created. notes (up to 2000 characters) is added to the event's description.
curl -X POST "https://api.workwae.com/v1/scheduling-links/$LINK_ID/bookings" \
-H "Authorization: Bearer $WORKWAE_API_KEY" \
-H "content-type: application/json" \
-d '{
"start": "2026-11-02T14:00:00Z",
"invitee": { "name": "Ada Lovelace", "address": "ada@example.com" },
"notes": "Interested in the team plan"
}'The event goes on the account's primary calendar, or the first calendar it can write. The slot is claimed in the database before the event is created, so two bookings of the same account and start cannot both succeed.
| Status | Reason | Meaning |
|---|---|---|
| 409 | slot_taken | The slot was booked meanwhile. List slots again and let the invitee pick another. |
| 409 | slot_unavailable | start is not a slot the link offers now, or no account is free for it. |
| 409 | calendar_disabled | The chosen account has calendar sync off. |
| 404 | calendar_not_found | The account has no calendar an event can be created in. |
| 403 | plan_module_unavailable | No calendar module, or the link creates a Zoom or Webex meeting without the meetings module. |
Meeting errors such as meeting_service_not_connected are in Meetings.
Cancel a booking
DELETE /v1/bookings/{bookingId} deletes the event, telling its attendees, marks the booking cancelled with cancelledAt, and sends booking.cancelled. An event already gone still cancels successfully, and eventId becomes null once the event is gone.
curl -X DELETE "https://api.workwae.com/v1/bookings/$BOOKING_ID" \
-H "Authorization: Bearer $WORKWAE_API_KEY"A missing booking answers 404 booking_not_found, one already cancelled 409 booking_cancelled, and an account with calendar sync off calendar_disabled.
Booking events
booking.created and booking.cancelled report bookings made and cancelled through links. Payloads are in Calendar and contacts events.