REST API
The REST API mounted at /api/v1 — endpoints, authentication, scopes and the error format.
A REST API mounted at /api/v1. Every request
needs an API key with the right scope; every response body — success
or error — is JSON, except a successful
DELETE, which returns
204 No Content with no body at all.
Authentication#
Send your key as a bearer token:
curl https://cal.mymeet.ai/api/v1/event-types \
-H "Authorization: Bearer pk_..."A key carries one or more scopes —
read, write, or
* for both. GET and HEAD requests need
read; everything else needs
write. A key without the required scope gets
403, never a silent downgrade.
Errors#
Errors are RFC 7807 problem documents,
application/problem+json:
{
"type": "urn:punctual:problem:invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "The request body did not validate.",
"errors": [
{ "field": "durationMinutes", "message": "Number must be a multiple of 5" }
]
}The type is a URN, not a
dereferenceable URL — a self-hoster’s error payloads never point at
the product website.
Endpoints#
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | /api/v1/event-types | read | List your event types |
| POST | /api/v1/event-types | write | Create an event type |
| GET | /api/v1/event-types/:id | read | Get one event type |
| PATCH | /api/v1/event-types/:id | write | Update fields on an event type |
| DELETE | /api/v1/event-types/:id | write | Delete an event type |
| GET | /api/v1/availability | read | Get the key holder’s weekly schedule and date overrides |
| PUT | /api/v1/availability | write | Replace the weekly schedule and overrides |
| GET | /api/v1/slots | read | List bookable start times for an event type in a time range |
| GET | /api/v1/bookings | read | List confirmed bookings in a time range |
| GET | /api/v1/bookings/:id | read | Get one booking, any status — cancelled and rescheduled included |
| POST | /api/v1/bookings | write | Create a booking directly, bypassing the public booking page |
| POST | /api/v1/bookings/:id/cancel | write | Cancel a confirmed booking |
| POST | /api/v1/bookings/:id/reschedule | write | Move a confirmed booking to a new time |
| GET | /api/v1/webhooks | read | List registered webhooks |
| POST | /api/v1/webhooks | write | Register a webhook; the response includes its signing secret once |
| DELETE | /api/v1/webhooks/:id | write | Remove a webhook |
Calendar answer privacy#
hideGuestAnswersInCalendar: true omits guest answers, including
the built-in agenda, from newly generated external calendar descriptions and
ICS invitations. The default is false; PATCH omission preserves
the setting. Meeting time, attendees and location remain. Answers stay saved
in Mymeet.ai Calendar and remain visible to the host; ordinary email bodies retain
their current content, while their ICS attachments follow this setting.
The setting applies when a calendar artifact is created or updated, including a reschedule. Saving the setting does not update every existing calendar event or revoke previously sent emails and downloaded ICS files.
Guest reminders#
reminders: {"24h": true, "1h": false} controls the two existing
guest email reminders independently. Omission on PATCH preserves the policy;
null restores both reminders. Current settings apply to existing
future bookings and are checked again before delivery. Confirmations,
reschedules and cancellations keep their existing notification behaviour.
In the local Node runtime, the durable outbox deduplicates reminders by booking and interval, including replay after a restart. Re-enabling a reminder does not resend one already processed or backfill a skipped window. Delivery needs a configured email provider; local preview only captures test messages.
Booking count limits#
maxPerDay (1–100) and maxPerWeek (1–700) accept
whole numbers or null for unlimited. Both count all confirmed
bookings for each assigned host, including other event types, in that host’s
applied schedule timezone. Weeks start Monday at midnight. Both limits apply
together; cancellation frees capacity and rescheduling excludes the original
booking from its replacement’s count. PATCH omission preserves either limit.
The booking write atomically enforces the caps, including concurrent requests.
When listing replacement times, pass rescheduleOf to
GET /slots or MCP get_available_slots. It must identify
a confirmed booking of this event type that you host. Ordinary slot searches
continue counting all bookings.
Booking date window#
bookingWindow: null uses maxHorizonDays.
A fixed {startDate: "2026-11-01", endDate: "2026-11-03"}
replaces that horizon. Both calendar dates are inclusive in each host’s
availability schedule timezone; the entire meeting must fit inside them.
Collective meetings must satisfy every host’s window; round-robin keeps
eligible hosts. Minimum notice, working hours and buffers still apply.
PATCH omission preserves the window; set null to restore the rolling horizon.
Conflict calendars#
Personal event types accept conflictSources on create/update:
null inherits connection settings; [] disables external
conflict checks. A selection is an array of {connectionId, calendarIds}:
Google and Yandex need a nonempty array of available calendar IDs; Microsoft uses
calendarIds: null for the connected mailbox. The dashboard provides
the source picker. Omitting this field in PATCH preserves it.
Explicit selections require all selected sources to be readable. A failed verification rejects a booking with a policy error (422). Inherited settings retain advisory outage behaviour. Internal bookings and holds always apply; calendar write destinations are configured separately.
Example: create a booking#
curl https://cal.mymeet.ai/api/v1/bookings \
-X POST \
-H "Authorization: Bearer pk_..." \
-H "Content-Type: application/json" \
-d '{
"eventTypeId": "evt_abc123",
"start": "2026-08-20T14:30:00Z",
"guestName": "Ada Lovelace",
"guestEmail": "ada@example.com"
}'start must be ISO-8601 with
an explicit offset (or epoch milliseconds) — an offsetless string is
rejected rather than silently read as UTC.
Ranges#
Any endpoint that takes
from/to
(/slots, /bookings)
caps the span at 62 days per request.
Full route definitions: src/http/api/rest.ts.