Skip to content

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 example
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.app

All 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

MethodDescription
initializeHandshake with the server. Returns protocol version and server capabilities.
notifications/initializedNotification sent after successful initialization.
tools/listList all available tools with schemas and annotations.
tools/callExecute a tool by name with the provided arguments.
pingHealth check. Returns a pong response.

Request Format

tools/call request
{
  "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.

tools/call response
{
  "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.

GET/api/mcp

Server discovery information. Returns protocol version, server name, and capabilities. Used by MCP clients during initial discovery.

Auth: None

GET/api/booking/{uid}/ics

Download an ICS calendar file for a specific booking. The {uid} parameter is the unique booking identifier.

Auth: None (public link)

POST/api/cron/reminders

Trigger processing of pending booking reminders. Sends reminder emails for upcoming bookings based on configured reminder windows.

Auth: CRON_SECRET header

GET/api/openapi

Download 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 TypesreadOnly

List all event types for the current user. Returns title, slug, duration, location type, active status, and booking link.

Parameters
statusstring

Filter by active status (default: all)

activeinactiveall
Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "list_event_types",
    "arguments": {
      "status": "active"
    }
  },
  "id": 1
}

get_event_type

Get Event TypereadOnly

Get full details of a specific event type by ID, including custom questions and scheduling rules.

Parameters
idstringrequired

Event 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 Typedestructive

Create a new event type. Requires title, slug, and duration. Returns the created event type.

Parameters
titlestringrequired

Event type title

slugstringrequired

URL-friendly slug (lowercase, hyphens only, e.g. 'quick-chat')

descriptionstring

Optional description of the event

durationintegerrequired

Duration in minutes (5-480, default 30)

colorstring

Hex color code (default #6366f1)

locationTypestring

Meeting location type (default google_meet)

google_meetmicrosoft_teamsin_personphonecustom
locationValuestring

Location details (address, phone, URL) — required for non-google_meet types

bufferBeforeinteger

Buffer minutes before event (0-120, default 0)

bufferAfterinteger

Buffer minutes after event (0-120, default 0)

minNoticeinteger

Minimum notice in minutes before booking (default 240 = 4 hours)

maxDaysAheadinteger

Max days into the future for booking (default 60)

requiresConfirmationboolean

Require host confirmation for bookings (default false)

slotIntervalinteger

Slot interval in minutes. If omitted, uses duration.

dailyLimitinteger

Max bookings per day for this event type

weeklyLimitinteger

Max bookings per week for this event type

allowRescheduleboolean

Allow invitees to reschedule (default true)

allowCancellationboolean

Allow invitees to cancel (default true)

reminderEnabledboolean

Enable email reminders (default true)

reminderHoursBeforenumber[]

Hours before meeting to send reminders (default [24, 1])

recurringEnabledboolean

Allow recurring bookings (default false)

recurringConfigobject

Recurring event configuration

maxInviteesinteger

Max invitees per slot. 1=1:1, >1=group, 0=unlimited (default 1)

schedulingTypestring

Scheduling type (default individual)

individualround_robincollective
isSecretboolean

Hide from public booking page (only accessible via direct link)

durationOptionsnumber[]

Additional duration options invitees can choose from (e.g. [15, 30, 60])

monthlyLimitinteger

Max bookings per month for this event type

maxDaysAheadModestring

How to calculate the booking window cutoff (default 'days')

rollingrangeindefinite
maxDaysAheadEndstring

Fixed end date for booking window (YYYY-MM-DD). Only used when maxDaysAheadMode is 'date'.

roundRobinModestring

Round-robin assignment mode: strict rotation or most-available-first

round_robinavailability
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 Typedestructiveidempotent

Update fields on an existing event type. Only provided fields are changed.

Parameters
idstringrequired

Event type UUID to update

titlestring

New title

descriptionstring

New description

durationinteger

New duration in minutes

colorstring

New hex color

locationTypestring
google_meetmicrosoft_teamsin_personphonecustom
locationValuestring
bufferBeforeinteger
bufferAfterinteger
minNoticeinteger
maxDaysAheadinteger
requiresConfirmationboolean
allowRescheduleboolean
allowCancellationboolean
slotIntervalinteger

Slot interval in minutes

dailyLimitinteger

Max bookings per day

weeklyLimitinteger

Max bookings per week

reminderEnabledboolean

Enable email reminders

reminderHoursBeforenumber[]

Hours before to send reminders

recurringEnabledboolean

Allow recurring bookings

recurringConfigobject
maxInviteesinteger

Max invitees per slot

schedulingTypestring
individualround_robincollective
isSecretboolean

Hide from public booking page

durationOptionsnumber[]

Additional duration options for invitees

monthlyLimitinteger

Max bookings per month

maxDaysAheadModestring

Booking window cutoff mode

rollingrangeindefinite
maxDaysAheadEndstring

Fixed end date for booking window (YYYY-MM-DD)

roundRobinModestring

Round-robin assignment mode

round_robinavailability
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 Typedestructiveidempotent

Enable or disable an event type. Disabled types cannot be booked.

Parameters
idstringrequired

Event type UUID

isActivebooleanrequired

true 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 Typedestructive

Permanently delete an event type. This cannot be undone. Existing bookings are preserved.

Parameters
idstringrequired

Event 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 BookingsreadOnly

List bookings for the current user. Can filter by status and time period.

Parameters
statusstring

Filter by booking status (default: confirmed)

confirmedpendingcancelledall
timeframestring

Filter by time period relative to now (default: upcoming)

upcomingpastall
limitinteger

Max results to return (default: 50)

startDatestring

Filter bookings on or after this date (YYYY-MM-DD)

endDatestring

Filter 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 BookingreadOnly

Get full details of a specific booking by UID, including invitee info, responses, and meeting link.

Parameters
uidstringrequired

Booking 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 BookingdestructiveopenWorld

Cancel a confirmed booking as the host. Optionally provide a cancellation reason.

Parameters
uidstringrequired

Booking UID to cancel

reasonstring

Optional 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 SlotsreadOnly

Get available time slots for a specific event type on a given date. Returns times formatted in the specified timezone.

Parameters
eventTypeIdstringrequired

Event type UUID to check

datestringrequired

Date in ISO format (YYYY-MM-DD)

timezonestring

IANA timezone for display (e.g. 'America/New_York'). Defaults to user's timezone.

durationinteger

Override 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 SchedulereadOnly

Get the user's availability schedule with all rules (days and time windows).

Parameters
scheduleIdstring

Specific 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 Availabilitydestructiveidempotent

Update availability rules for a schedule. Replaces all rules for the specified days.

Parameters
scheduleIdstringrequired

Schedule UUID to update

daysobjectrequired

Map 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 CalendarsreadOnly

List 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 ProfilereadOnly

Get 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 Profiledestructiveidempotent

Update the current user's profile (name, username, timezone, bio, branding).

Parameters
namestring

Display name

usernamestring

Unique username for booking page URL (lowercase, no spaces)

timezonestring

IANA timezone (e.g. 'America/New_York')

biostring

Short bio displayed on booking page

brandColorstring

Hex color for booking page branding (e.g. '#6366f1')

brandLogoUrlstring

Logo URL for booking page branding

hideBrandingboolean

Hide '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 PolldestructiveopenWorld

Create a scheduling poll with proposed time slots. Invitees vote on which slots work for them. Returns a public voting URL to share.

Parameters
titlestringrequired

Poll title (e.g. 'IDRS Discussion')

descriptionstring

Optional description

durationinteger

Meeting duration in minutes (default 30)

locationTypestring

Meeting location type (default google_meet)

google_meetmicrosoft_teamsin_personphonecustom
locationValuestring

Location details (address, phone, URL)

eventTypeIdstring

Event type UUID. Required for booking creation when poll resolves. If omitted, must be provided at resolve time.

slotsobject[]required

Proposed time slots for voting

inviteeEmailsstring[]

Expected voter email addresses. When all have voted, auto-resolve triggers (if enabled).

autoResolveboolean

Automatically book the best slot when all invitees have voted (default true)

deadlinestring

Optional 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 Polldestructiveidempotent

Update an open scheduling poll's details or time slots. Only open polls can be edited. Slots with votes cannot be removed.

Parameters
pollIdstringrequired

Poll UUID or UID to update

titlestring

New poll title

descriptionstring

New description (or null to clear)

locationTypestring

New meeting location type

google_meetmicrosoft_teamsin_personphonecustom
locationValuestring

New location details

deadlinestring

New voting deadline (ISO 8601) or null to remove

autoResolveboolean

Enable/disable auto-resolve when all invitees vote

eventTypeIdstring

Event type UUID for booking creation at resolve time

inviteeEmailsstring[]

Replace expected voter emails. Existing voters are preserved.

addSlotsobject[]

New time slots to add to the poll

removeSlotIdsstring[]

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 ResultsreadOnly

Get vote tallies per slot, who has/hasn't voted, and the best matching slot for a scheduling poll.

Parameters
pollIdstringrequired

Poll UUID or UID

Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "get_poll_results",
    "arguments": {
      "pollId": "<pollId>"
    }
  },
  "id": 1
}

resolve_poll

Resolve PolldestructiveopenWorld

Resolve a scheduling poll by selecting a winning slot. Creates a real booking for that slot and discards the rest.

Parameters
pollIdstringrequired

Poll UUID or UID

slotIdstring

Winning slot UUID. If omitted, auto-picks the best match.

eventTypeIdstring

Event 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 PollsreadOnly

List scheduling polls for the current user. Can filter by status.

Parameters
statusstring

Filter by poll status (default: all)

openclosedbookedall
Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "list_polls",
    "arguments": {
      "status": "open"
    }
  },
  "id": 1
}

close_poll

Close Polldestructiveidempotent

Close an open poll to stop voting. Does not create a booking. Use resolve_poll to pick a winner first if needed.

Parameters
pollIdstringrequired

Poll 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 Polldestructive

Permanently delete a scheduling poll and all its votes. This cannot be undone.

Parameters
pollIdstringrequired

Poll UUID or UID to delete

Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "delete_poll",
    "arguments": {
      "pollId": "<pollId>"
    }
  },
  "id": 1
}

Availability Overrides1 tool

add_availability_override

Add Availability Overridedestructiveidempotent

Block off a specific date or set custom hours for a date. Omit start/end times to block the entire day.

Parameters
datestringrequired

Date to override (YYYY-MM-DD)

startTimestring

Custom start time (HH:MM). Omit to block the entire day.

endTimestring

Custom end time (HH:MM). Omit to block the entire day.

scheduleIdstring

Schedule 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 Webhookdestructive

Register a new outbound webhook to receive booking events. Returns the webhook ID and signing secret.

Parameters
urlstringrequired

Endpoint URL to receive webhook POSTs

eventsstring[]required

Events to subscribe to

Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "register_webhook",
    "arguments": {
      "url": "<url>"
    }
  },
  "id": 1
}

list_webhooks

List WebhooksreadOnly

List 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 Webhookdestructive

Delete a registered webhook.

Parameters
idstringrequired

Webhook UUID to delete

Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "delete_webhook",
    "arguments": {
      "id": "<id>"
    }
  },
  "id": 1
}

test_webhook

Test WebhookdestructiveopenWorld

Send a test delivery to a registered webhook.

Parameters
idstringrequired

Webhook 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 Memberdestructive

Add a team member to an event type for round-robin or collective scheduling.

Parameters
eventTypeIdstringrequired

Event type UUID

userIdstringrequired

User 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 Memberdestructive

Remove a team member from an event type.

Parameters
eventTypeIdstringrequired

Event type UUID

userIdstringrequired

User 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 MembersreadOnly

List all team members assigned to an event type.

Parameters
eventTypeIdstringrequired

Event 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 Formdestructive

Create a routing form to qualify leads and direct them to the right event type.

Parameters
titlestringrequired

Form title

slugstringrequired

URL slug (lowercase, hyphens)

descriptionstring

Optional form description

fieldsobject[]required

Form fields

rulesobject[]required

Routing 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 Formdestructiveidempotent

Update an existing routing form's fields, rules, or settings.

Parameters
idstringrequired

Routing form UUID

titlestring
slugstring
descriptionstring
fieldsobject[]
rulesobject[]
isActiveboolean
Example request
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "update_routing_form",
    "arguments": {
      "id": "<id>",
      "title": "<title>"
    }
  },
  "id": 1
}

list_routing_forms

List Routing FormsreadOnly

List 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 Formdestructive

Permanently delete a routing form.

Parameters
idstringrequired

Routing 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.

CodeNameDescription
-32700Parse errorInvalid JSON was received by the server.
-32600Invalid requestThe JSON sent is not a valid JSON-RPC request.
-32601Method not foundThe method does not exist or is not available.
-32602Invalid paramsInvalid method parameter(s). Check required fields and types.
-32001Authentication errorMissing or invalid authentication credentials.
-32603Internal errorInternal JSON-RPC error. An unexpected server-side issue.
Error response example
{
  "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).

EndpointLimitWindow
/api/mcp60 req1 min
/api/auth/* (POST)5 req1 min
createBooking (public)10 req1 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