Reference

API

Build on Slotly with public booking endpoints, API-key access, and signed booking webhooks.

Quick start

Create a booking from an API key

Generate an API key from the Developer page, fetch your event types, then create bookings against an eventTypeId. Responses use a consistent { data: ... } shape.

OpenAPI JSON
curl https://slotly.to/api/v1/event-types \
  -H "Authorization: Bearer sk_slotly_live_xxx"

curl https://slotly.to/api/v1/bookings \
  -X POST \
  -H "Authorization: Bearer sk_slotly_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "eventTypeId": "evt_123",
    "startTime": "2026-06-18T20:30:00.000Z",
    "guestName": "Aisha Khan",
    "guestEmail": "aisha@example.com",
    "additionalGuestEmails": ["omar@example.com"],
    "guestTz": "America/Chicago",
    "notes": "Please send the prep deck.",
    "referrer": "https://example.com/resources",
    "utmSource": "newsletter",
    "utmMedium": "email",
    "utmCampaign": "summer-open-house"
  }'
Authentication

API keys

Create Bearer tokens from Dashboard -> Developer. Tokens are shown once, stored hashed, and can be revoked at any time.

Public links

Slot and booking endpoints for public pages use username, slug, teamSlug, or eventSlug instead of API keys.

Authorization: Bearer sk_slotly_live_xxx
Content-Type: application/json
Public booking endpoints

These power Slotly's public booking pages and embeds. They are rate-limited and only expose the details needed for scheduling.

GET/api/slots/week?username=:u&slug=:s&weekStart=YYYY-MM-DD&ranked=1

Returns a 7-day slot grid plus ranked recommended times.

GET/api/slots?username=:u&slug=:s&date=YYYY-MM-DD

Returns valid available times for one date.

POST/api/bookings

Creates a booking with username, slug, startTime, guestName, guestEmail, optional additionalGuestEmails, guestTz, notes, customAnswers, optional referrer attribution, and validated file-attachment answers.

POST/api/booking-attachments

Uploads a public booking attachment for FILE custom questions. Uses multipart form data with questionId and file; returns a Slotly-hosted attachment URL.

GET/api/team-slots/week?teamSlug=:team&eventSlug=:event&weekStart=YYYY-MM-DD&ranked=1

Returns round-robin or collective team availability.

POST/api/team-bookings

Creates a team booking, assigns the host for round-robin event types, supports optional additionalGuestEmails, and can store optional referrer attribution.

API-key endpoints

Use these endpoints to sync event types, bookings, and availability with your own systems. List endpoints return up to 100 records ordered by newest first and include pagination metadata.

GET/api/v1/me

Read the account identity attached to the API key. Useful for smoke tests and integration setup validation.

GET/api/v1/event-types?active=true&limit=50

List event types with cursor pagination. Optional active: true or false. Use pagination.nextCursor as cursor for the next page.

POST/api/v1/event-types

Create an event type with booking rules, location, paid-booking promo fields, active state, and customQuestions. Question types include TEXT, TEXTAREA, EMAIL, PHONE, URL, FILE, and SELECT.

GET/api/v1/event-types/:id

Read one event type and its public bookingUrl and embedUrl.

PATCH/api/v1/event-types/:id

Update event type fields, paid-booking promo fields, or replace its customQuestions array, including FILE upload questions.

DELETE/api/v1/event-types/:id

Delete an event type owned by the API key user.

POST/api/v1/event-types/:id/duplicate

Duplicate an existing event type with API-key auth, including rules, branding, questions, and event-specific workflows.

GET/api/v1/bookings?status=confirmed&limit=50

List bookings with cursor pagination. Optional status: pending, confirmed, cancelled, rescheduled, or no_show. Use pagination.nextCursor as cursor for the next page.

POST/api/v1/bookings

Create a booking after Slotly validates availability, buffers, notice, booking window, conflicts, and optional referrer attribution.

DELETE/api/v1/bookings/:id

Cancel a future booking and dispatch cancellation webhooks.

POST/api/v1/bookings/:id/approval

Approve or decline a pending booking request with {"action":"approve"} or {"action":"decline","reason":"Optional note"}. Approval creates calendar events, sends confirmation email, and dispatches booking webhooks.

GET/api/v1/people?q=acme&limit=50

List saved contacts with cursor pagination and optional search across name, email, and company.

POST/api/v1/people

Create a contact with name, optional email, phone, company, and notes.

GET/api/v1/people/:id

Read one contact owned by the API key user.

PATCH/api/v1/people/:id

Update contact profile fields.

DELETE/api/v1/people/:id

Delete a contact owned by the API key user.

GET/api/v1/teams?limit=50

List teams where the API key user is an active member.

POST/api/v1/teams

Create a team when the account has team access.

GET/api/v1/teams/:id

Read team details, members, team event types, host assignments, and public booking links.

PATCH/api/v1/teams/:id

Update team name or slug. Owner or admin role required.

DELETE/api/v1/teams/:id

Delete a team. Owner role required.

GET/api/v1/teams/:id/members

List active and inactive members for a team.

POST/api/v1/teams/:id/members

Add or reactivate a Slotly user by username or email. Owner or admin role required.

PATCH/api/v1/teams/:id/members

Update member role, active state, scheduling access, or booking weight.

DELETE/api/v1/teams/:id/members?userId=:userId

Remove a non-owner team member.

GET/api/v1/teams/:id/event-types?active=true&limit=50

List team scheduling links with host assignments and public bookingUrl values.

POST/api/v1/teams/:id/event-types

Create round-robin or collective team event types with hosts and weights.

PATCH/api/v1/teams/:id/event-types?eventTypeId=:eventTypeId

Update a team event type, routing mode, status, or host assignments.

DELETE/api/v1/teams/:id/event-types?eventTypeId=:eventTypeId

Delete a team event type. Owner or admin role required.

GET/api/v1/teams/:id/calendar-events?start=2026-06-01T00:00:00.000Z&end=2026-07-01T00:00:00.000Z

List master-calendar events for a team, optionally filtered by date range or userId.

POST/api/v1/teams/:id/calendar-events

Create a team master-calendar event for yourself, or for another member when owner/admin.

GET/api/v1/teams/:id/calendar-events/:eventId

Read one team master-calendar event.

PATCH/api/v1/teams/:id/calendar-events/:eventId

Update a team master-calendar event. Members can edit their own; owners/admins can edit any.

DELETE/api/v1/teams/:id/calendar-events/:eventId

Delete a team master-calendar event. Members can delete their own; owners/admins can delete any.

GET/api/v1/teams/:id/analytics?from=2026-06-01&to=2026-06-30

Read team booking totals, manual calendar events, host utilization, team link performance, daily trends, and upcoming workload. Use days for quick ranges or from/to for a custom YYYY-MM-DD reporting window.

GET/api/v1/teams/:id/analytics/export?from=2026-06-01&to=2026-06-30

Download a CSV team analytics report with summary totals, member utilization, team link performance, daily trends, and upcoming items. Supports days or a custom from/to date range.

GET/api/teams/:id/bookings/export?type=event&calendarStatus=upcoming&from=2026-06-01&to=2026-06-30

Download a dashboard-authenticated CSV of team bookings and master-calendar events. Optional filters: q, type, calendarStatus, status, from, to, and limit. Date filters accept YYYY-MM-DD or ISO date-time values.

GET/api/v1/routing-forms?active=true&limit=50

List routing forms with target event type metadata and publicUrl values.

POST/api/v1/routing-forms

Create an intake routing form with questions, conditional routingRules, and a fallback target event type.

GET/api/v1/routing-forms/:id

Read one routing form owned by the API key user.

PATCH/api/v1/routing-forms/:id

Update routing form title, URL, questions, routingRules, target event type, or active state.

DELETE/api/v1/routing-forms/:id

Delete a routing form owned by the API key user.

GET/api/v1/analytics?from=2026-06-01&to=2026-06-30

Read booking totals, conversion, revenue, top event types, source attribution, daily buckets, and upcoming meetings. Use days for quick ranges or from/to for a custom YYYY-MM-DD reporting window.

GET/api/v1/analytics/export?from=2026-06-01&to=2026-06-30

Download a CSV analytics report with summary totals, event performance, traffic sources, daily trends, routing performance, team utilization, and upcoming meetings. Supports days or a custom from/to date range.

GET/api/v1/one-off-links?status=ACTIVE&limit=50

List private one-off booking links with usage counts, expiry, and publicUrl values.

POST/api/v1/one-off-links

Create a limited-use private booking link for an active event type.

GET/api/v1/one-off-links/:id

Read one one-off link owned by the API key user.

PATCH/api/v1/one-off-links/:id

Update label, max uses, status, or expiry.

DELETE/api/v1/one-off-links/:id

Delete a one-off link owned by the API key user.

GET/api/v1/meeting-polls?status=OPEN&limit=50

List meeting polls with options, vote counts, responses, finalized booking info, and publicUrl values.

POST/api/v1/meeting-polls

Create a meeting poll with 2-12 proposed start times for an active event type.

GET/api/v1/meeting-polls/:id

Read one meeting poll owned by the API key user.

PATCH/api/v1/meeting-polls/:id

Update title, description, open/closed status, or expiry for an unfinalized poll.

POST/api/v1/meeting-polls/:id/finalize

Finalize a poll option into a confirmed booking with connected calendar and Zoom writeback.

DELETE/api/v1/meeting-polls/:id

Delete an unfinalized meeting poll.

GET/api/v1/availability

Read timezone, weekly blocks, active date ranges, and date overrides.

PUT/api/v1/availability

Replace weekly availability and overrides using the dashboard validator.

{
  "timezone": "America/Chicago",
  "activeFrom": "2026-06-01",
  "activeUntil": "2026-08-31",
  "days": [
    {
      "dayOfWeek": 1,
      "enabled": true,
      "blocks": [
        { "startTime": 540, "endTime": 1020, "priority": "IDEAL" }
      ]
    }
  ],
  "overrides": [
    {
      "date": "2026-07-04",
      "unavailable": true,
      "priority": "IDEAL",
      "note": "Holiday"
    }
  ]
}
SCIM provisioning

Team workspaces can generate a SCIM bearer token from Settings. Tokens are scoped to one team and support directory-style member listing, provisioning, pending invite visibility, and active-status lifecycle updates. Groups expose the configured provisioning team and its active members. SCIM list endpoints support startIndex, count, and simple eq filters for userName and displayName.

GET/api/scim/v2/ServiceProviderConfig

Expose Slotly SCIM capabilities for IdP discovery, including patch support, bearer-token auth, and filter limits.

GET/api/scim/v2/ResourceTypes

List supported SCIM resource types: User and Group.

GET/api/scim/v2/Schemas

List the supported User and Group schema attributes.

GET/api/scim/v2/Users

List team members as a SCIM 2.0 ListResponse. Supports filter=userName eq "member@example.com". Requires Authorization: Bearer scim_slotly_xxx.

POST/api/scim/v2/Users

Provision an existing Slotly user by email, or create a pending team invite when the email does not have an account yet.

GET/api/scim/v2/Users/{userId}

Fetch one provisioned team member. The id can be the SCIM user id or externalId returned by the list endpoint.

PATCH/api/scim/v2/Users/{userId}

Update supported SCIM user attributes. Slotly currently supports active true/false to reactivate or deactivate team access.

DELETE/api/scim/v2/Users/{userId}

Deactivate team access for a provisioned user without deleting the Slotly account. For pending invites, this revokes the invite.

GET/api/scim/v2/Groups

List the SCIM provisioning team as a Group resource. Supports filter=displayName eq "Team name".

GET/api/scim/v2/Groups/{teamId}

Fetch the configured provisioning team as a SCIM Group with active member references.

PATCH/api/scim/v2/Groups/{teamId}

Add or remove existing Slotly users from the provisioning team with SCIM PatchOp member operations. Seat limits are enforced.

PUT/api/scim/v2/Groups/{teamId}

Replace the active provisioning group membership with a complete members list. Members omitted from the request are deactivated from the team.

curl https://slotly.to/api/scim/v2/ServiceProviderConfig

curl 'https://slotly.to/api/scim/v2/Users?startIndex=1&count=50' \
  -H "Authorization: Bearer scim_slotly_xxx"

curl https://slotly.to/api/scim/v2/Users \
  -X POST \
  -H "Authorization: Bearer scim_slotly_xxx" \
  -H "Content-Type: application/scim+json" \
  -d '{ "userName": "member@example.com", "active": true }'

curl https://slotly.to/api/scim/v2/Users/usr_123 \
  -X PATCH \
  -H "Authorization: Bearer scim_slotly_xxx" \
  -H "Content-Type: application/scim+json" \
  -d '{ "active": false }'

curl https://slotly.to/api/scim/v2/Groups \
  -H "Authorization: Bearer scim_slotly_xxx"

curl https://slotly.to/api/scim/v2/Groups/team_123 \
  -X PATCH \
  -H "Authorization: Bearer scim_slotly_xxx" \
  -H "Content-Type: application/scim+json" \
  -d '{ "Operations": [{ "op": "add", "value": { "members": [{ "value": "usr_123" }] } }] }'

curl https://slotly.to/api/scim/v2/Groups/team_123 \
  -X PUT \
  -H "Authorization: Bearer scim_slotly_xxx" \
  -H "Content-Type: application/scim+json" \
  -d '{ "displayName": "Sales", "members": [{ "value": "usr_123" }] }'
Webhooks

Signed booking lifecycle events

Configure webhooks from Dashboard → Developer. Slotly sendsBOOKING_CREATED, BOOKING_APPROVED, BOOKING_DECLINED, BOOKING_PAYMENT_REQUESTED, BOOKING_PAID, BOOKING_CANCELLED, BOOKING_RESCHEDULED, and BOOKING_NO_SHOW to active endpoints.

Headers

Each delivery includes Slotly-Event and Slotly-Signature. The signature is sha256=<hex hmac> of the raw JSON body.

Retries

The Developer page shows recent deliveries and lets you manually retry failed or test deliveries.

const crypto = require("crypto");

function verifySlotlyWebhook(rawBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");

  return signatureHeader === `sha256=${expected}`;
}
View Zapier and Make recipes
{
  "id": "evt_booking_123_booking_created",
  "type": "BOOKING_CREATED",
  "createdAt": "2026-06-03T19:00:00.000Z",
  "data": {
    "booking": {
      "id": "booking_123",
      "guestName": "Aisha Khan",
      "guestEmail": "aisha@example.com",
      "additionalGuestEmails": ["omar@example.com"],
      "guestTz": "America/Chicago",
      "startTime": "2026-06-18T20:30:00.000Z",
      "endTime": "2026-06-18T21:00:00.000Z",
      "status": "CONFIRMED"
    },
    "eventType": {
      "id": "evt_123",
      "title": "30 Minute Meeting",
      "slug": "intro",
      "duration": 30
    }
  }
}
Errors and limits

400 Bad Request

Returned when JSON is invalid, validation fails, or a time range is not allowed.

401 Unauthorized

Returned when the Bearer token is missing, invalid, or revoked.

404 Not Found

Returned when a resource is missing or belongs to another user.

409 Conflict

Returned when a booking slot is no longer available or a slug already exists.

Public booking endpoints are rate-limited per IP. API keys should be kept server-side and rotated from the Developer page if they are exposed.

Open Developer page