Skip to content

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#

MethodPathScopeDescription
GET/api/v1/event-typesreadList your event types
POST/api/v1/event-typeswriteCreate an event type
GET/api/v1/event-types/:idreadGet one event type
PATCH/api/v1/event-types/:idwriteUpdate fields on an event type
DELETE/api/v1/event-types/:idwriteDelete an event type
GET/api/v1/availabilityreadGet the key holder’s weekly schedule and date overrides
PUT/api/v1/availabilitywriteReplace the weekly schedule and overrides
GET/api/v1/slotsreadList bookable start times for an event type in a time range
GET/api/v1/bookingsreadList confirmed bookings in a time range
GET/api/v1/bookings/:idreadGet one booking, any status — cancelled and rescheduled included
POST/api/v1/bookingswriteCreate a booking directly, bypassing the public booking page
POST/api/v1/bookings/:id/cancelwriteCancel a confirmed booking
POST/api/v1/bookings/:id/reschedulewriteMove a confirmed booking to a new time
GET/api/v1/webhooksreadList registered webhooks
POST/api/v1/webhookswriteRegister a webhook; the response includes its signing secret once
DELETE/api/v1/webhooks/:idwriteRemove 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.