Meridian API Reference
Getting Started
Meridian provides a powerful API built on the Model Context Protocol (MCP) with JSON-RPC 2.0 for AI tool integrations, plus standard REST endpoints for specific operations. The API exposes 40 tools covering event types, bookings, availability, scheduling polls, links, webhooks, and more.
All MCP tool calls are made via a single POST /api/mcp endpoint using JSON-RPC 2.0. You can also browse and download the OpenAPI 3.1 specification for use with code generators and API clients.
Authentication
Meridian supports three authentication methods. Choose the one that best fits your integration.
API Keys (Recommended)
Generate API keys in Dashboard > Settings > API Keys. Keys are prefixed with mk_ and should be sent as a Bearer token in the Authorization header.
curl -X POST https://your-domain/api/mcp \
-H "Authorization: Bearer mk_your_api_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":1}'OAuth 2.1
For MCP-compatible clients that support OAuth-based authentication. Discovery metadata is available at /.well-known/oauth-protected-resource. The authorization server metadata is auto-discovered per RFC 8414.
Session Cookie
For browser-based access. When authenticated via the Meridian dashboard, API calls from the same browser session are automatically authenticated using the session cookie.
Base URL
Production
https://i60-meridian-production.up.railway.appAll API endpoints are relative to this base URL. For local development, use http://localhost:3000.
MCP Protocol
Meridian implements the Model Context Protocol (MCP) over HTTP using JSON-RPC 2.0. All tool interactions go through a single endpoint: POST /api/mcp
Supported Methods
| Method | Description |
|---|---|
| initialize | Handshake with the server. Returns protocol version and server capabilities. |
| notifications/initialized | Notification sent after successful initialization. |
| tools/list | List all available tools with schemas and annotations. |
| tools/call | Execute a tool by name with the provided arguments. |
| ping | Health check. Returns a pong response. |
Request Format
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_event_types",
"arguments": {
"status": "active"
}
},
"id": 1
}Response Envelope
All tool responses are wrapped in a profiled envelope that includes success status, the data payload, and contextual metadata.
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "{\"success\":true,\"status\":\"completed\",\"data\":[\"...\"],\"context\":{\"warnings\":[],\"itemsProcessed\":3,\"suggestedNextActions\":[\"get_event_type\",\"create_event_type\"]}}"
}
]
},
"id": 1
}REST Endpoints
In addition to the MCP protocol, Meridian provides the following REST endpoints for specific operations.
/api/mcpServer discovery information. Returns protocol version, server name, and capabilities. Used by MCP clients during initial discovery.
Auth: None
/api/booking/{uid}/icsDownload an ICS calendar file for a specific booking. The {uid} parameter is the unique booking identifier.
Auth: None (public link)
/api/cron/remindersTrigger processing of pending booking reminders. Sends reminder emails for upcoming bookings based on configured reminder windows.
Auth: CRON_SECRET header
/api/openapiDownload the OpenAPI 3.1 specification for the Meridian API. Useful for code generation and API client libraries.
Auth: None
Tool Reference
Meridian exposes 40 tools through the MCP protocol, organized into the categories below. Each tool can be called via the tools/call JSON-RPC method.
Event Types6 tools
list_event_types
List Event TypesreadOnlyList all event types for the current user. Returns title, slug, duration, location type, active status, and booking link.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | stringactiveinactiveall | No | Filter by active status (default: all) |
stringFilter by active status (default: all)
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_event_types",
"arguments": {
"status": "active"
}
},
"id": 1
}get_event_type
Get Event TypereadOnlyGet full details of a specific event type by ID, including custom questions and scheduling rules.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Event type UUID |
stringrequiredEvent type UUID
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_event_type",
"arguments": {
"id": "<id>"
}
},
"id": 1
}create_event_type
Create Event TypedestructiveCreate a new event type. Requires title, slug, and duration. Returns the created event type.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Event type title |
| slug | string | Yes | URL-friendly slug (lowercase, hyphens only, e.g. 'quick-chat') |
| description | string | No | Optional description of the event |
| duration | integer | Yes | Duration in minutes (5-480, default 30) |
| color | string | No | Hex color code (default #6366f1) |
| locationType | stringgoogle_meetmicrosoft_teamsin_personphonecustom | No | Meeting location type (default google_meet) |
| locationValue | string | No | Location details (address, phone, URL) — required for non-google_meet types |
| bufferBefore | integer | No | Buffer minutes before event (0-120, default 0) |
| bufferAfter | integer | No | Buffer minutes after event (0-120, default 0) |
| minNotice | integer | No | Minimum notice in minutes before booking (default 240 = 4 hours) |
| maxDaysAhead | integer | No | Max days into the future for booking (default 60) |
| requiresConfirmation | boolean | No | Require host confirmation for bookings (default false) |
| slotInterval | integer | No | Slot interval in minutes. If omitted, uses duration. |
| dailyLimit | integer | No | Max bookings per day for this event type |
| weeklyLimit | integer | No | Max bookings per week for this event type |
| allowReschedule | boolean | No | Allow invitees to reschedule (default true) |
| allowCancellation | boolean | No | Allow invitees to cancel (default true) |
| reminderEnabled | boolean | No | Enable email reminders (default true) |
| reminderHoursBefore | number[] | No | Hours before meeting to send reminders (default [24, 1]) |
| recurringEnabled | boolean | No | Allow recurring bookings (default false) |
| recurringConfig | object | No | Recurring event configuration |
| maxInvitees | integer | No | Max invitees per slot. 1=1:1, >1=group, 0=unlimited (default 1) |
| schedulingType | stringindividualround_robincollective | No | Scheduling type (default individual) |
| isSecret | boolean | No | Hide from public booking page (only accessible via direct link) |
| durationOptions | number[] | No | Additional duration options invitees can choose from (e.g. [15, 30, 60]) |
| monthlyLimit | integer | No | Max bookings per month for this event type |
| maxDaysAheadMode | stringrollingrangeindefinite | No | How to calculate the booking window cutoff (default 'days') |
| maxDaysAheadEnd | string | No | Fixed end date for booking window (YYYY-MM-DD). Only used when maxDaysAheadMode is 'date'. |
| roundRobinMode | stringround_robinavailability | No | Round-robin assignment mode: strict rotation or most-available-first |
stringrequiredEvent type title
stringrequiredURL-friendly slug (lowercase, hyphens only, e.g. 'quick-chat')
stringOptional description of the event
integerrequiredDuration in minutes (5-480, default 30)
stringHex color code (default #6366f1)
stringMeeting location type (default google_meet)
stringLocation details (address, phone, URL) — required for non-google_meet types
integerBuffer minutes before event (0-120, default 0)
integerBuffer minutes after event (0-120, default 0)
integerMinimum notice in minutes before booking (default 240 = 4 hours)
integerMax days into the future for booking (default 60)
booleanRequire host confirmation for bookings (default false)
integerSlot interval in minutes. If omitted, uses duration.
integerMax bookings per day for this event type
integerMax bookings per week for this event type
booleanAllow invitees to reschedule (default true)
booleanAllow invitees to cancel (default true)
booleanEnable email reminders (default true)
number[]Hours before meeting to send reminders (default [24, 1])
booleanAllow recurring bookings (default false)
objectRecurring event configuration
integerMax invitees per slot. 1=1:1, >1=group, 0=unlimited (default 1)
stringScheduling type (default individual)
booleanHide from public booking page (only accessible via direct link)
number[]Additional duration options invitees can choose from (e.g. [15, 30, 60])
integerMax bookings per month for this event type
stringHow to calculate the booking window cutoff (default 'days')
stringFixed end date for booking window (YYYY-MM-DD). Only used when maxDaysAheadMode is 'date'.
stringRound-robin assignment mode: strict rotation or most-available-first
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_event_type",
"arguments": {
"title": "<title>",
"slug": "<slug>"
}
},
"id": 1
}update_event_type
Update Event TypedestructiveidempotentUpdate fields on an existing event type. Only provided fields are changed.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Event type UUID to update |
| title | string | No | New title |
| description | string | No | New description |
| duration | integer | No | New duration in minutes |
| color | string | No | New hex color |
| locationType | stringgoogle_meetmicrosoft_teamsin_personphonecustom | No | -- |
| locationValue | string | No | -- |
| bufferBefore | integer | No | -- |
| bufferAfter | integer | No | -- |
| minNotice | integer | No | -- |
| maxDaysAhead | integer | No | -- |
| requiresConfirmation | boolean | No | -- |
| allowReschedule | boolean | No | -- |
| allowCancellation | boolean | No | -- |
| slotInterval | integer | No | Slot interval in minutes |
| dailyLimit | integer | No | Max bookings per day |
| weeklyLimit | integer | No | Max bookings per week |
| reminderEnabled | boolean | No | Enable email reminders |
| reminderHoursBefore | number[] | No | Hours before to send reminders |
| recurringEnabled | boolean | No | Allow recurring bookings |
| recurringConfig | object | No | -- |
| maxInvitees | integer | No | Max invitees per slot |
| schedulingType | stringindividualround_robincollective | No | -- |
| isSecret | boolean | No | Hide from public booking page |
| durationOptions | number[] | No | Additional duration options for invitees |
| monthlyLimit | integer | No | Max bookings per month |
| maxDaysAheadMode | stringrollingrangeindefinite | No | Booking window cutoff mode |
| maxDaysAheadEnd | string | No | Fixed end date for booking window (YYYY-MM-DD) |
| roundRobinMode | stringround_robinavailability | No | Round-robin assignment mode |
stringrequiredEvent type UUID to update
stringNew title
stringNew description
integerNew duration in minutes
stringNew hex color
stringstringintegerintegerintegerintegerbooleanbooleanbooleanintegerSlot interval in minutes
integerMax bookings per day
integerMax bookings per week
booleanEnable email reminders
number[]Hours before to send reminders
booleanAllow recurring bookings
objectintegerMax invitees per slot
stringbooleanHide from public booking page
number[]Additional duration options for invitees
integerMax bookings per month
stringBooking window cutoff mode
stringFixed end date for booking window (YYYY-MM-DD)
stringRound-robin assignment mode
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_event_type",
"arguments": {
"id": "<id>",
"title": "<title>"
}
},
"id": 1
}toggle_event_type
Toggle Event TypedestructiveidempotentEnable or disable an event type. Disabled types cannot be booked.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Event type UUID |
| isActive | boolean | Yes | true to enable, false to disable |
stringrequiredEvent type UUID
booleanrequiredtrue to enable, false to disable
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "toggle_event_type",
"arguments": {
"id": "<id>",
"isActive": true
}
},
"id": 1
}delete_event_type
Delete Event TypedestructivePermanently delete an event type. This cannot be undone. Existing bookings are preserved.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Event type UUID to delete |
stringrequiredEvent type UUID to delete
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "delete_event_type",
"arguments": {
"id": "<id>"
}
},
"id": 1
}Bookings3 tools
list_bookings
List BookingsreadOnlyList bookings for the current user. Can filter by status and time period.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | stringconfirmedpendingcancelledall | No | Filter by booking status (default: confirmed) |
| timeframe | stringupcomingpastall | No | Filter by time period relative to now (default: upcoming) |
| limit | integer | No | Max results to return (default: 50) |
| startDate | string | No | Filter bookings on or after this date (YYYY-MM-DD) |
| endDate | string | No | Filter bookings on or before this date (YYYY-MM-DD, inclusive) |
stringFilter by booking status (default: confirmed)
stringFilter by time period relative to now (default: upcoming)
integerMax results to return (default: 50)
stringFilter bookings on or after this date (YYYY-MM-DD)
stringFilter bookings on or before this date (YYYY-MM-DD, inclusive)
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_bookings",
"arguments": {
"status": "confirmed",
"timeframe": "upcoming"
}
},
"id": 1
}get_booking
Get BookingreadOnlyGet full details of a specific booking by UID, including invitee info, responses, and meeting link.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uid | string | Yes | Booking UID (the short public-facing ID) |
stringrequiredBooking UID (the short public-facing ID)
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_booking",
"arguments": {
"uid": "<uid>"
}
},
"id": 1
}cancel_booking
Cancel BookingdestructiveopenWorldCancel a confirmed booking as the host. Optionally provide a cancellation reason.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uid | string | Yes | Booking UID to cancel |
| reason | string | No | Optional cancellation reason |
stringrequiredBooking UID to cancel
stringOptional cancellation reason
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "cancel_booking",
"arguments": {
"uid": "<uid>",
"reason": "<reason>"
}
},
"id": 1
}Availability & Slots3 tools
get_available_slots
Get Available SlotsreadOnlyGet available time slots for a specific event type on a given date. Returns times formatted in the specified timezone.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID to check |
| date | string | Yes | Date in ISO format (YYYY-MM-DD) |
| timezone | string | No | IANA timezone for display (e.g. 'America/New_York'). Defaults to user's timezone. |
| duration | integer | No | Override event type duration in minutes. Useful when the event type offers multiple duration options. |
stringrequiredEvent type UUID to check
stringrequiredDate in ISO format (YYYY-MM-DD)
stringIANA timezone for display (e.g. 'America/New_York'). Defaults to user's timezone.
integerOverride event type duration in minutes. Useful when the event type offers multiple duration options.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_available_slots",
"arguments": {
"eventTypeId": "<eventTypeId>",
"date": "<date>"
}
},
"id": 1
}get_availability_schedule
Get Availability SchedulereadOnlyGet the user's availability schedule with all rules (days and time windows).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| scheduleId | string | No | Specific schedule UUID. If omitted, returns the default schedule. |
stringSpecific schedule UUID. If omitted, returns the default schedule.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_availability_schedule",
"arguments": {
"scheduleId": "<scheduleId>"
}
},
"id": 1
}update_availability
Update AvailabilitydestructiveidempotentUpdate availability rules for a schedule. Replaces all rules for the specified days.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| scheduleId | string | Yes | Schedule UUID to update |
| days | object | Yes | Map of day-of-week (0=Sun..6=Sat) to availability. Each value: { "enabled": boolean, "windows": [{ "start": "HH:MM", "end": "HH:MM" }] } |
stringrequiredSchedule UUID to update
objectrequiredMap of day-of-week (0=Sun..6=Sat) to availability. Each value: { "enabled": boolean, "windows": [{ "start": "HH:MM", "end": "HH:MM" }] }
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_availability",
"arguments": {
"scheduleId": "<scheduleId>"
}
},
"id": 1
}Calendar Integration1 tool
list_connected_calendars
List Connected CalendarsreadOnlyList Google calendars connected to the user's account, showing which are used for conflict checking and booking creation.
Parameters
No parameters required.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_connected_calendars",
"arguments": {}
},
"id": 1
}User Profile2 tools
get_user_profile
Get User ProfilereadOnlyGet the current user's profile including name, email, username, and timezone.
Parameters
No parameters required.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_user_profile",
"arguments": {}
},
"id": 1
}update_profile
Update ProfiledestructiveidempotentUpdate the current user's profile (name, username, timezone, bio, branding).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | No | Display name |
| username | string | No | Unique username for booking page URL (lowercase, no spaces) |
| timezone | string | No | IANA timezone (e.g. 'America/New_York') |
| bio | string | No | Short bio displayed on booking page |
| brandColor | string | No | Hex color for booking page branding (e.g. '#6366f1') |
| brandLogoUrl | string | No | Logo URL for booking page branding |
| hideBranding | boolean | No | Hide 'Powered by Meridian' footer on booking pages |
stringDisplay name
stringUnique username for booking page URL (lowercase, no spaces)
stringIANA timezone (e.g. 'America/New_York')
stringShort bio displayed on booking page
stringHex color for booking page branding (e.g. '#6366f1')
stringLogo URL for booking page branding
booleanHide 'Powered by Meridian' footer on booking pages
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_profile",
"arguments": {
"name": "<name>",
"username": "<username>"
}
},
"id": 1
}Scheduling Polls7 tools
create_poll
Create Scheduling PolldestructiveopenWorldCreate a scheduling poll with proposed time slots. Invitees vote on which slots work for them. Returns a public voting URL to share.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Poll title (e.g. 'IDRS Discussion') |
| description | string | No | Optional description |
| duration | integer | No | Meeting duration in minutes (default 30) |
| locationType | stringgoogle_meetmicrosoft_teamsin_personphonecustom | No | Meeting location type (default google_meet) |
| locationValue | string | No | Location details (address, phone, URL) |
| eventTypeId | string | No | Event type UUID. Required for booking creation when poll resolves. If omitted, must be provided at resolve time. |
| slots | object[] | Yes | Proposed time slots for voting |
| inviteeEmails | string[] | No | Expected voter email addresses. When all have voted, auto-resolve triggers (if enabled). |
| autoResolve | boolean | No | Automatically book the best slot when all invitees have voted (default true) |
| deadline | string | No | Optional voting deadline as ISO 8601 timestamp |
stringrequiredPoll title (e.g. 'IDRS Discussion')
stringOptional description
integerMeeting duration in minutes (default 30)
stringMeeting location type (default google_meet)
stringLocation details (address, phone, URL)
stringEvent type UUID. Required for booking creation when poll resolves. If omitted, must be provided at resolve time.
object[]requiredProposed time slots for voting
string[]Expected voter email addresses. When all have voted, auto-resolve triggers (if enabled).
booleanAutomatically book the best slot when all invitees have voted (default true)
stringOptional voting deadline as ISO 8601 timestamp
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_poll",
"arguments": {
"title": "<title>",
"description": "<description>"
}
},
"id": 1
}update_poll
Update PolldestructiveidempotentUpdate an open scheduling poll's details or time slots. Only open polls can be edited. Slots with votes cannot be removed.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| pollId | string | Yes | Poll UUID or UID to update |
| title | string | No | New poll title |
| description | string | No | New description (or null to clear) |
| locationType | stringgoogle_meetmicrosoft_teamsin_personphonecustom | No | New meeting location type |
| locationValue | string | No | New location details |
| deadline | string | No | New voting deadline (ISO 8601) or null to remove |
| autoResolve | boolean | No | Enable/disable auto-resolve when all invitees vote |
| eventTypeId | string | No | Event type UUID for booking creation at resolve time |
| inviteeEmails | string[] | No | Replace expected voter emails. Existing voters are preserved. |
| addSlots | object[] | No | New time slots to add to the poll |
| removeSlotIds | string[] | No | Slot UUIDs to remove. Fails if any slot has votes. |
stringrequiredPoll UUID or UID to update
stringNew poll title
stringNew description (or null to clear)
stringNew meeting location type
stringNew location details
stringNew voting deadline (ISO 8601) or null to remove
booleanEnable/disable auto-resolve when all invitees vote
stringEvent type UUID for booking creation at resolve time
string[]Replace expected voter emails. Existing voters are preserved.
object[]New time slots to add to the poll
string[]Slot UUIDs to remove. Fails if any slot has votes.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_poll",
"arguments": {
"pollId": "<pollId>",
"title": "<title>"
}
},
"id": 1
}get_poll_results
Get Poll ResultsreadOnlyGet vote tallies per slot, who has/hasn't voted, and the best matching slot for a scheduling poll.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| pollId | string | Yes | Poll UUID or UID |
stringrequiredPoll UUID or UID
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_poll_results",
"arguments": {
"pollId": "<pollId>"
}
},
"id": 1
}resolve_poll
Resolve PolldestructiveopenWorldResolve a scheduling poll by selecting a winning slot. Creates a real booking for that slot and discards the rest.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| pollId | string | Yes | Poll UUID or UID |
| slotId | string | No | Winning slot UUID. If omitted, auto-picks the best match. |
| eventTypeId | string | No | Event type UUID for the booking. Required if not set on the poll. |
stringrequiredPoll UUID or UID
stringWinning slot UUID. If omitted, auto-picks the best match.
stringEvent type UUID for the booking. Required if not set on the poll.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "resolve_poll",
"arguments": {
"pollId": "<pollId>",
"slotId": "<slotId>"
}
},
"id": 1
}list_polls
List PollsreadOnlyList scheduling polls for the current user. Can filter by status.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | stringopenclosedbookedall | No | Filter by poll status (default: all) |
stringFilter by poll status (default: all)
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_polls",
"arguments": {
"status": "open"
}
},
"id": 1
}close_poll
Close PolldestructiveidempotentClose an open poll to stop voting. Does not create a booking. Use resolve_poll to pick a winner first if needed.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| pollId | string | Yes | Poll UUID or UID to close |
stringrequiredPoll UUID or UID to close
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "close_poll",
"arguments": {
"pollId": "<pollId>"
}
},
"id": 1
}delete_poll
Delete PolldestructivePermanently delete a scheduling poll and all its votes. This cannot be undone.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| pollId | string | Yes | Poll UUID or UID to delete |
stringrequiredPoll UUID or UID to delete
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "delete_poll",
"arguments": {
"pollId": "<pollId>"
}
},
"id": 1
}Scheduling Links6 tools
create_scheduling_link
Create Scheduling LinkdestructiveopenWorldCreate a scheduling link (single-use or offer-times). Optionally sends an invitation email. Returns the shareable booking URL.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID for this link |
| type | stringsingle_useoffer_times | Yes | Link type: single_use (one booking) or offer_times (invitee picks from offered slots) |
| inviteeName | string | No | Name of the invitee |
| inviteeEmail | string | No | Email of the invitee (required if sendEmail is true) |
| offeredSlots | object[] | No | Specific time slots to offer (required for offer_times type) |
| allowOutsideAvailability | boolean | No | Allow booking outside normal availability hours (default false) |
| reserveHolds | boolean | No | Create tentative calendar holds for offered slots (default false) |
| singleUse | boolean | No | Link can only be used once (default true for single_use type) |
| expiresIn | string24h48h7d30d | No | Link expiry duration |
| sendEmail | boolean | No | Send invitation email to invitee (default false) |
| message | string | No | Optional message included in the invitation email |
stringrequiredEvent type UUID for this link
stringrequiredLink type: single_use (one booking) or offer_times (invitee picks from offered slots)
stringName of the invitee
stringEmail of the invitee (required if sendEmail is true)
object[]Specific time slots to offer (required for offer_times type)
booleanAllow booking outside normal availability hours (default false)
booleanCreate tentative calendar holds for offered slots (default false)
booleanLink can only be used once (default true for single_use type)
stringLink expiry duration
booleanSend invitation email to invitee (default false)
stringOptional message included in the invitation email
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_scheduling_link",
"arguments": {
"eventTypeId": "<eventTypeId>",
"type": "single_use"
}
},
"id": 1
}list_scheduling_links
List Scheduling LinksreadOnlyList scheduling links for the current user. Can filter by status and event type.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| status | stringallactiveusedexpiredcancelled | No | Filter by link status (default: all) |
| eventTypeId | string | No | Filter by event type UUID |
stringFilter by link status (default: all)
stringFilter by event type UUID
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_scheduling_links",
"arguments": {
"status": "all",
"eventTypeId": "<eventTypeId>"
}
},
"id": 1
}get_scheduling_link
Get Scheduling LinkreadOnlyGet full details of a scheduling link by ID or token, including calendar holds.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| linkId | string | No | Scheduling link UUID |
| token | string | No | Scheduling link token |
stringScheduling link UUID
stringScheduling link token
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_scheduling_link",
"arguments": {
"linkId": "<linkId>",
"token": "<token>"
}
},
"id": 1
}cancel_scheduling_link
Cancel Scheduling LinkdestructiveCancel an active scheduling link. Releases any calendar holds.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| linkId | string | Yes | Scheduling link UUID to cancel |
stringrequiredScheduling link UUID to cancel
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "cancel_scheduling_link",
"arguments": {
"linkId": "<linkId>"
}
},
"id": 1
}delete_scheduling_link
Delete Scheduling LinkdestructivePermanently delete a non-active scheduling link. Active links must be cancelled first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| linkId | string | Yes | Scheduling link UUID to delete |
stringrequiredScheduling link UUID to delete
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "delete_scheduling_link",
"arguments": {
"linkId": "<linkId>"
}
},
"id": 1
}offer_times
Offer TimesdestructiveopenWorldConvenience tool: create an offer-times scheduling link from a list of start times. Automatically calculates end times from duration, reserves calendar holds, and sends an invitation email.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID |
| inviteeEmail | string | Yes | Email of the invitee |
| inviteeName | string | No | Name of the invitee |
| slots | string[] | Yes | Array of ISO 8601 UTC start times to offer (e.g. ['2025-01-15T10:00:00Z', '2025-01-15T14:00:00Z']) |
| duration | integer | No | Meeting duration in minutes. If omitted, uses the event type's default duration. |
| reserveHolds | boolean | No | Create tentative calendar holds for offered slots (default true) |
| sendEmail | boolean | No | Send invitation email to invitee (default true) |
| expiresIn | string24h48h7d30d | No | Link expiry duration (default '48h') |
| message | string | No | Optional message included in the invitation email |
stringrequiredEvent type UUID
stringrequiredEmail of the invitee
stringName of the invitee
string[]requiredArray of ISO 8601 UTC start times to offer (e.g. ['2025-01-15T10:00:00Z', '2025-01-15T14:00:00Z'])
integerMeeting duration in minutes. If omitted, uses the event type's default duration.
booleanCreate tentative calendar holds for offered slots (default true)
booleanSend invitation email to invitee (default true)
stringLink expiry duration (default '48h')
stringOptional message included in the invitation email
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "offer_times",
"arguments": {
"eventTypeId": "<eventTypeId>",
"inviteeEmail": "<inviteeEmail>"
}
},
"id": 1
}Availability Overrides1 tool
add_availability_override
Add Availability OverridedestructiveidempotentBlock off a specific date or set custom hours for a date. Omit start/end times to block the entire day.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| date | string | Yes | Date to override (YYYY-MM-DD) |
| startTime | string | No | Custom start time (HH:MM). Omit to block the entire day. |
| endTime | string | No | Custom end time (HH:MM). Omit to block the entire day. |
| scheduleId | string | No | Schedule UUID. If omitted, uses the default schedule. |
stringrequiredDate to override (YYYY-MM-DD)
stringCustom start time (HH:MM). Omit to block the entire day.
stringCustom end time (HH:MM). Omit to block the entire day.
stringSchedule UUID. If omitted, uses the default schedule.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "add_availability_override",
"arguments": {
"date": "<date>",
"startTime": "<startTime>"
}
},
"id": 1
}Webhooks4 tools
register_webhook
Register WebhookdestructiveRegister a new outbound webhook to receive booking events. Returns the webhook ID and signing secret.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | Endpoint URL to receive webhook POSTs |
| events | string[] | Yes | Events to subscribe to |
stringrequiredEndpoint URL to receive webhook POSTs
string[]requiredEvents to subscribe to
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "register_webhook",
"arguments": {
"url": "<url>"
}
},
"id": 1
}list_webhooks
List WebhooksreadOnlyList all registered webhooks for the current user.
Parameters
No parameters required.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_webhooks",
"arguments": {}
},
"id": 1
}delete_webhook
Delete WebhookdestructiveDelete a registered webhook.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Webhook UUID to delete |
stringrequiredWebhook UUID to delete
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "delete_webhook",
"arguments": {
"id": "<id>"
}
},
"id": 1
}test_webhook
Test WebhookdestructiveopenWorldSend a test delivery to a registered webhook.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Webhook UUID to test |
stringrequiredWebhook UUID to test
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "test_webhook",
"arguments": {
"id": "<id>"
}
},
"id": 1
}Team Members3 tools
add_event_type_member
Add Event Type MemberdestructiveAdd a team member to an event type for round-robin or collective scheduling.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID |
| userId | string | Yes | User ID of the team member to add |
stringrequiredEvent type UUID
stringrequiredUser ID of the team member to add
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "add_event_type_member",
"arguments": {
"eventTypeId": "<eventTypeId>",
"userId": "<userId>"
}
},
"id": 1
}remove_event_type_member
Remove Event Type MemberdestructiveRemove a team member from an event type.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID |
| userId | string | Yes | User ID of the member to remove |
stringrequiredEvent type UUID
stringrequiredUser ID of the member to remove
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "remove_event_type_member",
"arguments": {
"eventTypeId": "<eventTypeId>",
"userId": "<userId>"
}
},
"id": 1
}list_event_type_members
List Event Type MembersreadOnlyList all team members assigned to an event type.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| eventTypeId | string | Yes | Event type UUID |
stringrequiredEvent type UUID
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_event_type_members",
"arguments": {
"eventTypeId": "<eventTypeId>"
}
},
"id": 1
}Routing Forms4 tools
create_routing_form
Create Routing FormdestructiveCreate a routing form to qualify leads and direct them to the right event type.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| title | string | Yes | Form title |
| slug | string | Yes | URL slug (lowercase, hyphens) |
| description | string | No | Optional form description |
| fields | object[] | Yes | Form fields |
| rules | object[] | Yes | Routing rules (first match wins) |
stringrequiredForm title
stringrequiredURL slug (lowercase, hyphens)
stringOptional form description
object[]requiredForm fields
object[]requiredRouting rules (first match wins)
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "create_routing_form",
"arguments": {
"title": "<title>",
"slug": "<slug>"
}
},
"id": 1
}update_routing_form
Update Routing FormdestructiveidempotentUpdate an existing routing form's fields, rules, or settings.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Routing form UUID |
| title | string | No | -- |
| slug | string | No | -- |
| description | string | No | -- |
| fields | object[] | No | -- |
| rules | object[] | No | -- |
| isActive | boolean | No | -- |
stringrequiredRouting form UUID
stringstringstringobject[]object[]booleanExample request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "update_routing_form",
"arguments": {
"id": "<id>",
"title": "<title>"
}
},
"id": 1
}list_routing_forms
List Routing FormsreadOnlyList all routing forms for the current user.
Parameters
No parameters required.
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "list_routing_forms",
"arguments": {}
},
"id": 1
}delete_routing_form
Delete Routing FormdestructivePermanently delete a routing form.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | string | Yes | Routing form UUID to delete |
stringrequiredRouting form UUID to delete
Example request
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "delete_routing_form",
"arguments": {
"id": "<id>"
}
},
"id": 1
}Error Codes
The API uses standard JSON-RPC 2.0 error codes. When an error occurs, the response will contain an error object instead of a result.
| Code | Name | Description |
|---|---|---|
| -32700 | Parse error | Invalid JSON was received by the server. |
| -32600 | Invalid request | The JSON sent is not a valid JSON-RPC request. |
| -32601 | Method not found | The method does not exist or is not available. |
| -32602 | Invalid params | Invalid method parameter(s). Check required fields and types. |
| -32001 | Authentication error | Missing or invalid authentication credentials. |
| -32603 | Internal error | Internal JSON-RPC error. An unexpected server-side issue. |
{
"jsonrpc": "2.0",
"error": {
"code": -32001,
"message": "Authentication required"
},
"id": 1
}Rate Limiting
Limits are applied per client IP on a rolling one-minute window. Exceeding a limit returns 429 Too Many Requests with a Retry-After header (seconds until the window reopens).
| Endpoint | Limit | Window |
|---|---|---|
| /api/mcp | 60 req | 1 min |
| /api/auth/* (POST) | 5 req | 1 min |
| createBooking (public) | 10 req | 1 min |
429 responses include headers: X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After. Build exponential backoff into your client for robustness.
40 tools across 11 categories
Back to top