A REST API mounted at /api/v1. Every request needs an API key with the right scope; every response body — success or error — is JSON, except a successful DELETE, which returns 204 No Content with no body at all.
Authentication
Send your key as a bearer token:
curl https://book.cccrafts.ai/api/v1/event-types \
-H "Authorization: Bearer pk_..."
A key carries one or more scopes — read, write, or * for both. GET and HEAD requests need read; everything else needs write. A key without the required scope gets 403, never a silent downgrade.
Errors
Errors are RFC 7807 problem documents, application/problem+json:
{
"type": "urn:punctual:problem:invalid-request",
"title": "Invalid request",
"status": 400,
"detail": "The request body did not validate.",
"errors": [
{ "field": "durationMinutes", "message": "Number must be a multiple of 5" }
]
}
The type is a URN, not a dereferenceable URL — a self-hoster's error payloads never point at punctual's own domain.
Endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | /api/v1/event-types | read | List your event types |
| POST | /api/v1/event-types | write | Create an event type |
| GET | /api/v1/event-types/:id | read | Get one event type |
| PATCH | /api/v1/event-types/:id | write | Update fields on an event type |
| DELETE | /api/v1/event-types/:id | write | Delete an event type |
| GET | /api/v1/availability | read | Get the key holder's weekly schedule and date overrides |
| PUT | /api/v1/availability | write | Replace the weekly schedule and overrides |
| GET | /api/v1/slots | read | List bookable start times for an event type in a time range |
| GET | /api/v1/bookings | read | List confirmed bookings in a time range |
| GET | /api/v1/bookings/:id | read | Get one booking, any status — cancelled and rescheduled included |
| POST | /api/v1/bookings | write | Create a booking directly, bypassing the public booking page |
| POST | /api/v1/bookings/:id/cancel | write | Cancel a confirmed booking |
| POST | /api/v1/bookings/:id/reschedule | write | Move a confirmed booking to a new time |
| GET | /api/v1/webhooks | read | List registered webhooks |
| POST | /api/v1/webhooks | write | Register a webhook; the response includes its signing secret once |
| DELETE | /api/v1/webhooks/:id | write | Remove a webhook |
Example: create a booking
curl https://book.cccrafts.ai/api/v1/bookings \
-X POST \
-H "Authorization: Bearer pk_..." \
-H "Content-Type: application/json" \
-d '{
"eventTypeId": "evt_abc123",
"start": "2026-08-20T14:30:00Z",
"guestName": "Ada Lovelace",
"guestEmail": "ada@example.com"
}'
start must be ISO-8601 with an explicit offset (or epoch milliseconds) — an offsetless string is rejected rather than silently read as UTC.
Ranges
Any endpoint that takes from/to (/slots, /bookings) caps the span at 62 days per request.
Full route definitions: src/http/api/rest.ts.