Base URL
All requests are made to
https://api.cal.id.Authentication
Cal ID authenticates requests with an API key sent as a Bearer token in theAuthorization header.
1
Create an API key
In the Cal ID dashboard, go to Settings → Developer → API keys and create a key. Keys are prefixed with
calid_. See Get your API key for the full walkthrough.2
Send it with every request
Include the key in the
Authorization header:To manage a team’s resources (team event types, memberships, and schedules), use an API key belonging to a team owner or admin.
Sending a request body
POST and PATCH requests must carry a Content-Type: application/json header. Without it the request is rejected with 415 Unsupported Media Type before the body is parsed, even when the JSON you sent is perfectly valid.
Quickstart
Retrieve the authenticated user’s profile to confirm your key works:Response format
Most responses are a JSON envelope built fromsuccess, data, message, and meta — but not every endpoint returns all four, and error responses from outside the API’s routing layer do not use the envelope at all. Write your client to read data defensively rather than assuming a fixed shape.
The
data field holds the resource or resources you requested. Read it rather than the top level.
data is not always an object or a list of objects with the shape you expect. GET /users/{userslug} returns data as an array, not a single user object — even though it looks up one user by slug. Index into it (data[0]) rather than reading fields off data directly.Status codes
See Error codes for every
error.code value and the details shape that comes with each.
Pagination
Pagination is not uniform across the API. There are three different behaviours, and the default page size is not the same everywhere — so check this table before you write a paging loop.The standard envelope shape
/event-types/, /booking/, /teams/*, and /webhook/ page with page and limit and report progress in a top-level meta.pagination object.
Contacts nest their pagination, with different key names
GET /contacts/ and GET /contacts/{id}/meetings put the records under data.rows and the counts under data.meta. The keys are not the ones used above — there is no total, page, or totalPages.
offset while data.meta.hasMore is true.
Schedules are not paginated at all
GET /schedule/ and GET /teams/{teamId}/schedules return the complete list in data and carry no meta object. They accept page and limit in the query string without complaint, but ignore them — passing ?limit=1 still returns every schedule. Do not write a paging loop against these endpoints; it will either never terminate or silently re-read the same full list.
Limit ceilings
For/event-types/, /contacts/, and /teams/*, the maximum limit is 100. Asking for more is rejected:
The
100 ceiling is confirmed for /event-types/, /contacts/, and /teams/*. It was not tested on /booking/ or /webhook/, which already default to 100 — assume the same ceiling until you have verified otherwise.Dates and times
Almost every endpoint sends and receives timestamps as ISO-8601 strings —2026-09-08T03:30:00.000Z.
GET /availability/ is the exception. It returns RFC-1123 date strings instead:
GET /availability/ also requires the dateFrom query parameter. Calling it without one returns 400, not an unbounded list:
Filtering and sorting
Most list endpoints accept filters and sort keys as query parameters. For example, List bookings supports filtering bystatus, eventTypeIds, attendeeEmail, and date ranges (afterStartDate, beforeEndDate, afterCreatedDate, …), plus sorting with sortStart, sortCreated, and sortUpdated. See each endpoint’s Query Parameters for the full set.
GET /booking/ defaults to status=upcoming. With no status parameter you will not see past bookings, and there is no “all” value — page each bucket (upcoming, past, cancelled, unconfirmed, recurring) separately.Developer guides and references
Quickstart
From a fresh API key to a confirmed booking in five requests.
Error codes
Every
error.code the API returns, and what to do about each.Get your API key
Create and manage the keys that authenticate your requests.
Find your Event Type ID
Locate the IDs you’ll pass to booking and event-type endpoints.
Webhooks
Subscribe to booking and meeting events in real time.
Integration overview
How the API is structured, from servers to authentication.
Rate limits
Stay under your allowance and recover cleanly from a
429.Guides
Task-shaped recipes for bookings, slots, schedules, teams, and contacts.