https://api.cal.id and is authenticated with a bearer token. Work through it in order — each step produces a value the next one needs, and the last step will fail if you skip ahead and invent a time rather than using one the API gave you.
You need a Cal ID account with at least one event type. If you have none, create one in the dashboard first — this guide reads an existing event type rather than creating one.
1
Get an API key
In the Cal ID dashboard, go to Settings → Developer → API Keys and create a key. Keys are prefixed with
calid_ and are shown once, so copy it somewhere safe immediately.See Get your API key for the full walkthrough, including expiry options.2
Confirm the key works
Call A working key returns your profile inside If you get
GET /users/me. It is the cheapest way to prove your key and header are correct before you debug anything else.data:401 with error.code: "UNAUTHORIZED", the header is wrong or the key is invalid or expired. If you get a 404 whose body has no success field, you have mistyped the URL — that response comes from the router, not the API. See Error codes.GET /users/me returns data as an object. Its sibling GET /users/{userslug} returns data as an array — read that one as data[0].3
Find an event type ID
Every booking is made against an event type. List yours and pick one.The list arrives in
data, with paging state in meta.pagination. Note the id of the event type you want to book, and its length in minutes — you need both.4
Fetch real bookable slots
Ask the API which times are actually available. Do not compute this yourself: availability is the product of schedules, buffers, minimum notice, booking limits, connected-calendar busy times, and timezone rules, and a reimplementation will not match.The response nests slots two levels deep: Read your chosen time as
data.slots is an object keyed by date ("YYYY-MM-DD"), and each value is an array of slot objects whose bookable time is in time.data.slots["2026-09-08"][0].time — not data[0] and not data.slots[0].If the date key you expected is missing, or its array is empty, there is genuinely nothing bookable in that window. Widen start/end or check the event type’s schedule before moving on.5
Create the booking
Post the slot you just read. The created booking comes back in
start, end, and responses (with at least name and email) are required, and end is start plus the event type’s length in minutes.data, including its uid.If the booking fails with a 500
The most common failure in this flow is:500, this is not a Cal ID outage — it means the start you sent is not a time the scheduling rules will accept. Almost always the cause is that start did not come from Step 4.
Two things that look fine but are not:
- A time that is obviously free on your calendar. Availability is not the same as “not busy” — buffers, minimum notice, and booking limits all remove otherwise-empty times.
- A time echoed back from a booking object. Booking responses use
startTimeandendTime; the request body usesstartandend. You cannot round-trip a booking object straight back intoPOST /booking/.
What you just learned
Go deeper with the API
API integration
The conventions that apply across every endpoint — envelopes, pagination, and the traps.
Error codes
Every
error.code the API returns, and what to do about each.Reserve a slot before booking
Hold a time while the booker completes checkout, so nobody else takes it.
Reschedule and cancel
Move or cancel a booking you created.
Webhooks
Get booking events pushed to you instead of polling.
API Reference
Every endpoint, with schemas and a live “Try it” playground.