Calendar & appointments
Current release · Updated October 2, 2026
DryKraft Calendar & appointments reference: methods, permissions, request fields, response shapes, examples and current limits. Read authentication and error handling first.
/api/calendar/membersList possible calendar hosts
Access: Workspace member · Success: 200
Up to500 current workspace user IDs and names; emails are excluded.
No request body is required.
Response
object[].
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/members' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/calendar/calendarsList calendars
Access: Workspace member · Success: 200
Up to100 retained personal, team or service calendars, including disabled definitions.
No request body is required.
Response
Calendar[].
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/calendars' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/calendar/calendarsCreate calendar
Access: Owner or admin · Success: 201
Active billing required. Unique client UUID; duplicate IDs return409 rather than creating another definition. Public booking is opt-in. Working hours use the configured timezone.
JSON request
Use CalendarInput.
Response
Use Calendar.
curl --request POST \
--url 'https://app.drykraft.com/api/calendar/calendars' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"id": "00000000-0000-4000-8000-000000000001",
"name": "<Calendar name>",
"config": {
"kind": "personal",
"timezone": "<Valid IANA timezone>",
"duration": 15,
"buffer_before": 0,
"buffer_after": 0,
"notice_minutes": 0,
"horizon_days": 1,
"hosts": [
"00000000-0000-4000-8000-000000000001"
],
"assignment": "round_robin",
"availability": [
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
}
],
"exceptions": [],
"location": "<Public booking location or link>",
"description": "<Public booking description>",
"reminder_minutes": []
},
"enabled": false,
"public_enabled": false
}'/api/calendar/calendars/{id}Update availability
Access: Owner or admin · Success: 200
Current version and matching body ID required. Changes affect new bookings/reschedules; existing appointment host/time/location snapshots stay fixed. Disable instead of deleting.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
id | uuid | Yes | |
name | string | Yes | Calendar name Max 120 characters. |
config | CalendarConfig | Yes | |
enabled | boolean | Yes | Accept new appointments |
public_enabled | boolean | Yes | Explicitly publish availability and booking metadata |
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
Response
Use Calendar.
curl --request PUT \
--url 'https://app.drykraft.com/api/calendar/calendars/00000000-0000-4000-8000-000000000001' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"id": "00000000-0000-4000-8000-000000000001",
"name": "<Calendar name>",
"config": {
"kind": "personal",
"timezone": "<Valid IANA timezone>",
"duration": 15,
"buffer_before": 0,
"buffer_after": 0,
"notice_minutes": 0,
"horizon_days": 1,
"hosts": [
"00000000-0000-4000-8000-000000000001"
],
"assignment": "round_robin",
"availability": [
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
},
{
"day": 0,
"windows": []
}
],
"exceptions": [],
"location": "<Public booking location or link>",
"description": "<Public booking description>",
"reminder_minutes": []
},
"enabled": false,
"public_enabled": false,
"version": 1
}'/api/calendar/calendars/{id}/slotsRead available times
Access: Workspace member · Success: 200
15-minute grid, configured duration, notice, horizon, working windows/date overrides and buffers. Every host is checked across local calendars and fresh provider ranges. Stale provider cache blocks that host. Optional exclude must name an appointment in this calendar.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
date | date | Yes | Valid calendar date, YYYY-MM-DD. |
timezone | string | Yes | Valid IANA timezone Max 100 characters. |
exclude | uuid | No |
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
slots | object[] | Yes | |
unavailable | boolean | Yes | Some connected host availability is stale |
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/calendars/00000000-0000-4000-8000-000000000001/slots?date=2026-10-02&timezone=%3CValid%20IANA%20timezone%3E' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/calendar/local-timesResolve local clock time
Access: Workspace member · Success: 200
Returns zero instants for a nonexistent daylight-saving time, one normally, two for a repeated time. Choose an explicit returned offset/instant before booking outside working hours.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
date | date | Yes | Valid calendar date, YYYY-MM-DD. |
time | string | Yes | HH:MM |
timezone | string | Yes | Valid IANA timezone Max 100 characters. |
Response
| Field | Type | Required | Details |
|---|---|---|---|
choices | date-time[] | No |
curl --request POST \
--url 'https://app.drykraft.com/api/calendar/local-times' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"date": "2026-10-02",
"time": "<HH:MM>",
"timezone": "<Valid IANA timezone>"
}'/api/calendar/appointmentsList appointments
Access: Workspace member · Success: 200
Requested range must be positive and at most62days. Up to1000 rows plus more=true; narrow by calendar if truncated. Includes lifecycle, linked record metadata and calendar name.
Query parameters
| Parameter | Type | Required | Details |
|---|---|---|---|
from | date-time | Yes | ISO instant with explicit UTC offset. |
to | date-time | Yes | ISO instant with explicit UTC offset. |
calendar_id | uuid | No |
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
items | Appointment[] | No | |
more | boolean | No | Additional rows exist |
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/appointments?from=%3CISO%20instant%20with%20explicit%20UTC%20offset%3E&to=%3CISO%20instant%20with%20explicit%20UTC%20offset%3E' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/calendar/appointments/{id}Read appointment and history
Access: Workspace member · Success: 200
Tenant-scoped appointment plus latest50 append-only version snapshots. Snapshots exclude management keys and request hashes.
No request body is required.
Response
| Field | Type | Required | Details |
|---|---|---|---|
id | uuid | Yes | |
calendar_id | uuid | Yes | |
title | string | Yes | Title Max 160 characters. |
guest_name | string | No | Guest name Max 120 characters. |
guest_email | No | Max 200 characters. | |
record_id | string or null | No | |
starts_at | date-time | Yes | ISO instant with explicit UTC offset. |
timezone | string | Yes | Valid IANA timezone Max 100 characters. |
notes | string | No | Internal only Max 4000 characters. |
outside_hours | boolean | No | Workspace only: bypass working hours/notice/horizon, never host conflicts or stale provider availability. Defaults false. |
ends_at | date-time | Yes | ISO instant with explicit UTC offset. |
host_ids | uuid[] | No | |
state | booked | completed | no_show | cancelled | Yes | Lifecycle |
source | workspace | public | workflow | No | Creation source |
manage_key | uuid | No | |
location | string | No | Saved location |
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
created_at | date-time | No | ISO instant with explicit UTC offset. |
updated_at | date-time | No | ISO instant with explicit UTC offset. |
history | object[] | No |
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/appointments/00000000-0000-4000-8000-000000000001' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'/api/calendar/appointmentsBook appointment
Access: Owner, admin or member · Success: 201
Workspace scheduling lock prevents cross-calendar double booking and serializes round robin. Same UUID and original normalized request returns the committed appointment. Different content returns409. Linked CRM records resolve contact merges. Future times must be within one year.
JSON request
Use AppointmentInput.
Response
Use Appointment.
curl --request POST \
--url 'https://app.drykraft.com/api/calendar/appointments' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"id": "00000000-0000-4000-8000-000000000001",
"calendar_id": "00000000-0000-4000-8000-000000000001",
"title": "<Title>",
"guest_name": "<Guest name>",
"guest_email": "person@example.com",
"record_id": "00000000-0000-4000-8000-000000000001",
"starts_at": "<ISO instant with explicit UTC offset>",
"timezone": "<Valid IANA timezone>",
"notes": "<Internal only>"
}'/api/calendar/appointments/{id}Change appointment
Access: Owner, admin or member · Success: 200
Current version required. Rescheduling checks availability excluding this appointment and uses current calendar duration/buffers/location rules. Attendance is allowed only after start. Cancellation remains available after billing expiry. Notes-only edits do not repeat emitted reminders.
JSON request
| Field | Type | Required | Details |
|---|---|---|---|
version | integer | Yes | Positive optimistic version returned by the latest read. Refresh on 409; do not overwrite stale changes. Min 1. |
state | booked | cancelled | completed | no_show | Yes | Closed appointments cannot reopen |
starts_at | date-time | No | ISO instant with explicit UTC offset. |
timezone | string | No | Valid IANA timezone Max 100 characters. |
notes | string | No | Internal notes Max 4000 characters. |
outside_hours | boolean | No | Workspace only |
Response
Use Appointment.
curl --request PUT \
--url 'https://app.drykraft.com/api/calendar/appointments/00000000-0000-4000-8000-000000000001' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>' \
--header 'Content-Type: application/json' \
--data '{
"version": 1,
"state": "booked"
}'/api/calendar/appointments/{id}/icsDownload calendar event
Access: Workspace member · Success: 200
UTC event times, stable UID, lifecycle status and version. Excludes guest emails and internal notes; no invitation delivery.
No request body is required.
Response
string. RFC5545 event text, downloadable .ics
curl --request GET \
--url 'https://app.drykraft.com/api/calendar/appointments/00000000-0000-4000-8000-000000000001/ics' \
--cookie 'drykraft_session=<YOUR_SESSION_TOKEN>'