---
title: "Book a slot, one of four ways, each checked the same way. With invite (a booking link's token, from ?invite= on the link the page's owner gave): booked, 201. With turnstileToken (the booking page's form): booked, 201. Signed by an allowlisted operator's agent (Web Bot Auth: Signature, Signature-Input and Signature-Agent headers from https://chatgpt.com or https://agent.bot.goog): booked, 201, whatever the body's turnstileToken. With none of these (an invitee's agent): nothing is booked or held; a 6-digit code is emailed to email, 202, and POST /api/pages/{handle}/bookings/confirm books. 409 slot_taken carries alternatives; 409 page_changed: the handle moved since the page was read (pageId)."
method: POST
path: "/api/pages/{handle}/bookings"
tags: ["public"]
---

# Book a slot, one of four ways, each checked the same way. With invite (a booking link's token, from ?invite= on the link the page's owner gave): booked, 201. With turnstileToken (the booking page's form): booked, 201. Signed by an allowlisted operator's agent (Web Bot Auth: Signature, Signature-Input and Signature-Agent headers from https://chatgpt.com or https://agent.bot.goog): booked, 201, whatever the body's turnstileToken. With none of these (an invitee's agent): nothing is booked or held; a 6-digit code is emailed to email, 202, and POST /api/pages/{handle}/bookings/confirm books. 409 slot_taken carries alternatives; 409 page_changed: the handle moved since the page was read (pageId).

`POST /api/pages/{handle}/bookings`

## Request

- Base URL: `https://daycal.io`
- URL: `https://daycal.io/api/pages/{handle}/bookings`
- Auth: none declared

## Path parameters

- `handle` string, required

## Request body

- union
  - object
    - `eventType` string, required
    - `start` string, date-time, required
    - `name` string, required
    - `email` string, required
    - `note` string
    - `tz` string, required
    - `pageId` string, required: The pageId GET /api/pages/{handle} gave: read the page first and send it on every booking, so a handle that names another account now is refused (409 page_changed) rather than booked with them. Required (400 invalid_request without it), except with invite: a booking link's token names its owner
    - `invite` string: A booking link's token: books once, no bot check, no code
    - `turnstileToken` string: Solved by the booking page's form only
  - object
    - `eventType` string, required
    - `start` string, date-time, required
    - `name` string, required
    - `email` string, required
    - `note` string
    - `tz` string, required
    - `pageId` string: The pageId GET /api/pages/{handle} gave: read the page first and send it on every booking, so a handle that names another account now is refused (409 page_changed) rather than booked with them. Required (400 invalid_request without it), except with invite: a booking link's token names its owner
    - `invite` string, required: A booking link's token: books once, no bot check, no code
    - `turnstileToken` string: Solved by the booking page's form only

## Response `201`

Booked

- Booked
  - `booking` Booking, required
    - `id` string, required
    - `start` string, date-time, required
    - `end` string, date-time, required
    - `eventType` string, required
    - `title` string, required
    - `manageUrl` string, required
    - `conferenceUrl` string, nullable, required
    - `status` 'confirmed' | 'cancelled' | 'rescheduled', required
  - `confirmation` string, required

## Other responses

- `202`: Code emailed to the invitee (10 minutes, 5 tries); nothing is booked or held yet
- `429`: Rate limited. Retry-After is set when a rate-limit window is spent (not on a booking's own budget)
- `default`: Error

---

[API](https://skmtc.dev/daycal/apis/daycal-api.md) · [All operations](https://skmtc.dev/daycal/apis/daycal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/daycal/apis/daycal-api/revisions/7103ffff4e8c?raw)
