Carly API

A small, predictable REST API for booking pages, event types, calendars, bookings, and availability. The same surface powers the Carly CLI and the MCP server.

Base URL & versioning

https://carlyassistant.com/api/v1

All endpoints are versioned under /api/v1. We keep v1 stable once published; breaking changes ship under a new version with advance notice.

Authentication

Authenticate with a Bearer token. Mint an API key from the Carly dashboard under Booking Pages → "Generate API key", then send it on every request:

Authorization: Bearer <your-api-key>

Read endpoints work with any key. Write endpoints (create / update / delete booking pages, and calendar select) require a key with the booking_pages:write scope. Keep keys secret — treat them like a password.

Responses & errors

Responses are JSON. Standard HTTP status codes apply: 401/403 authentication or scope, 404 not found, 400/422 validation, 429 rate limited (honor Retry-After). Error bodies include a message.

Endpoints

Profile

Identify the account a key belongs to.

GET /whoami

Return the user the API key belongs to.

curl https://carlyassistant.com/api/v1/whoami \
  -H "Authorization: Bearer $CARLY_API_KEY"

Calendars

List connected calendars and control which ones count against availability.

GET /calendars

List connected calendars. The `selected` field mirrors "Check for conflicts on" — selected calendars count against booking-page availability.

curl https://carlyassistant.com/api/v1/calendars \
  -H "Authorization: Bearer $CARLY_API_KEY"
POST /calendars/select booking_pages:write

Toggle whether a calendar counts against availability. Send `selected: true` to select, `false` to unselect. Account-wide.

ParameterTypeNotes
calendar_keyrequired string Calendar key from GET /calendars (e.g. "google::371::primary").
selectedrequired boolean true to count this calendar for conflicts, false to stop.
curl -X POST https://carlyassistant.com/api/v1/calendars/select \
  -H "Authorization: Bearer $CARLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"calendar_key":"google::371::primary","selected":true}'

Event types

Read event types for the caller or any public profile.

GET /event-types

Without `username`, returns the caller's own event types. With `username`, returns that public profile's active event types.

ParameterTypeNotes
username string Filter to a public profile's active event types.
curl "https://carlyassistant.com/api/v1/event-types?username=bailey" \
  -H "Authorization: Bearer $CARLY_API_KEY"

Booking pages

Full CRUD over your bookable event types (public booking links).

GET /booking-pages

List the authenticated user's booking pages.

curl https://carlyassistant.com/api/v1/booking-pages \
  -H "Authorization: Bearer $CARLY_API_KEY"
GET /booking-pages/{eventTypeId}

Get a single booking page by event type ID.

curl https://carlyassistant.com/api/v1/booking-pages/42 \
  -H "Authorization: Bearer $CARLY_API_KEY"
POST /booking-pages booking_pages:write

Create a booking page.

ParameterTypeNotes
titlerequired string Page title.
slug string URL slug (e.g. "15min").
duration integer Meeting length in minutes.
videoProvider string google_meet, teams, zoom, …
availability array Weekly availability, e.g. [{"days":[1,2,3,4,5],"start_time":"09:00","end_time":"17:00"}] (days: Sun=0…Sat=6).
customQuestions array e.g. [{"label":"Company","type":"text","required":true}].
durationOptions array Bookable durations, e.g. [15,30,60].
curl -X POST https://carlyassistant.com/api/v1/booking-pages \
  -H "Authorization: Bearer $CARLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"15 minute intro","duration":15,"slug":"15min"}'
PATCH /booking-pages/{eventTypeId} booking_pages:write

Update a booking page. Only fields you send are changed. Nested fields replace the previous value.

ParameterTypeNotes
isActive boolean Enable or disable the page.
various Any field accepted by POST /booking-pages.
curl -X PATCH https://carlyassistant.com/api/v1/booking-pages/42 \
  -H "Authorization: Bearer $CARLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"duration":45,"minNoticeMinutes":60}'
DELETE /booking-pages/{eventTypeId} booking_pages:write

Soft-delete (pause) a booking page — sets is_active=false. Re-activate with PATCH … {"isActive":true}.

curl -X DELETE https://carlyassistant.com/api/v1/booking-pages/42 \
  -H "Authorization: Bearer $CARLY_API_KEY"

Bookings

Read scheduled bookings.

GET /bookings

List the authenticated user's bookings, with optional filters.

ParameterTypeNotes
status string Filter by booking status.
eventTypeId integer Filter by event type.
limit integer 1–1000 (default 100).
startTime string Range start (ISO 8601).
endTime string Range end (ISO 8601).
curl "https://carlyassistant.com/api/v1/bookings?status=accepted&limit=25" \
  -H "Authorization: Bearer $CARLY_API_KEY"
GET /bookings/{uid}

Get a single booking by its UID.

curl https://carlyassistant.com/api/v1/bookings/abc123xyz \
  -H "Authorization: Bearer $CARLY_API_KEY"

Slots

Query bookable availability.

GET /slots

List available slots in a time range. Provide either `eventTypeId`, or both `username` and `eventTypeSlug`.

ParameterTypeNotes
eventTypeId integer Event type ID (or use username + eventTypeSlug).
username string Profile username (with eventTypeSlug).
eventTypeSlug string Event type slug (with username).
startTimerequired string Range start (ISO 8601).
endTimerequired string Range end (ISO 8601).
duration integer Override slot duration (minutes).
curl "https://carlyassistant.com/api/v1/slots?eventTypeId=42&startTime=2026-05-01T00:00:00Z&endTime=2026-05-07T23:59:59Z" \
  -H "Authorization: Bearer $CARLY_API_KEY"

Integrations

Don't want to call the API directly? Reach Carly through the tools you already use:

Ready to automate your busywork?

Carly schedules, researches, and briefs you—so you can focus on what matters.

See what people say

"Before Carly, I relied on a Calendly link, but the whole process felt impersonal and not very professional. Carly changed that by handling all the back-and-forth, so I'm no longer stuck in endless email threads trying to line up schedules.

Now Carly reaches out to candidates, shares my real-time availability, lets them pick a slot, then sends a Zoom link and drops it straight into my calendar. She sends reminders to both of us before each call, which has significantly reduced no-shows and last-minute confusion.

On top of scheduling, Carly acts like a full executive assistant, sending me my schedule the night before so I can prepare for each call. It reminds me of the old x.ai assistant, but Carly is noticeably smarter, faster, and better suited to my healthcare recruitment business."

Gus Ibrahim, Founder & Director, IHR