code — stable machine
identifier. Switch on this, not on message.
message — human-readable
explanation. Wording may change.
details — endpoint-specific
extra fields (e.g. the offending parameter name, or the
required scope). May be empty {}.
request_id — unique per
request. Quote this when reporting an
issue.
The HTTP status is set per RFC 7231 — switch on it for routing
(5xx ⇒ retry, 4xx ⇒ fix the request)
and use code for granular handling.
Common error codes
Authentication (401)
Code
Meaning
invalid_token
Missing, malformed, or unknown bearer token.
token_expired
Token is past its expiry.
token_revoked
PAT or OAuth token has been revoked.
These responses also include
WWW-Authenticate: Bearer realm="42min", error="…"
— useful for clients that follow the RFC 6750 challenge
protocol.
Authorization (403)
Code
Meaning
insufficient_scope
Token is valid but missing the required scope.
details.required_scope names which one.
forbidden
Generic refusal — auth and scope are fine, but the actor
isn't allowed to do this.
Validation (400 / 422)
Code
Meaning
validation_error
Request body failed validation.
invalid_request
The request itself is malformed (bad headers, bad
shape).
invalid_query_param
A query parameter is missing or malformed.
details.param names which one.
attendee_email_invalid
attendee.email failed format check.
invalid_if_match
If-Match is not a valid integer.
field_immutable
A PATCH tried to write a field that can only change via
dedicated endpoints (e.g. start).
details.fields lists them.
event_type_disallows_reschedule
The event type has disableRescheduling.
Conflict / state (409)
Code
Meaning
slot_unavailable
Requested slot is no longer free.
event_type_inactive
Event type's status is not on.
booking_in_past
Booking starts (or started) in the past.
booking_already_cancelled
Reschedule attempted on a non-confirmed booking.
version_conflict
If-Match doesn't match the current booking
version.
idempotency_in_progress
Same Idempotency-Key still being processed.
Retry-After: 1.
idempotency_key_conflict
Same key, different body within the 24h window.
pat_name_taken
Another PAT in this account has the same name.
pat_limit_exceeded
Account has 42 active PATs already.
Not found (404)
Code
Meaning
not_found
Generic.
event_type_not_found
Event type doesn't exist or is in another account.
booking_not_found
Booking doesn't exist, was hard-deleted, or its UID is
malformed.
interaction_not_found
OAuth consent interaction expired or doesn't exist.
We deliberately collapse "wrong tenant" into
not_found — a 404 doesn't leak the existence of
resources in other accounts.
Precondition / payload (412 / 413 /
415 / 428)
Code
Meaning
missing_if_match
PATCH without If-Match. (428 Precondition Required.)
missing_idempotency_key
Write without Idempotency-Key.
(400.)
invalid_idempotency_key
Idempotency-Key longer than 255 chars.
(400.)
Rate-limiting (429)
Code
Meaning
rate_limited
Bucket exhausted. Retry-After header set;
see Rate limits.
OAuth (400 / 401)
Code
Meaning
invalid_client
Bad client_id / client_secret,
or unknown client.
invalid_grant
Bad auth code, bad refresh token, PKCE failure,
redirect-URI mismatch, or replay detected.
invalid_scope
Requested scope not allowed for this client, or unknown
scope name.
invalid_redirect_uri
redirect URI is not registered or fails scheme rules.
unsupported_grant_type
grant_type is not
authorization_code or
refresh_token.
unsupported_response_type
response_type is not code.
invalid_client_metadata
DCR request rejected (scope not in allowlist, etc.).
access_denied
User declined on the consent screen. Returned via
redirect, not a JSON body.
Server (5xx)
Code
Meaning
internal_error
Something went wrong server-side. Quote
request_id to support.
slot_lock_timeout
Could not acquire the per-slot lock when
creating/rescheduling a booking.
Retry-After: 1. (503.)
Recommended client handling
5xx or network failure — retry
with the same Idempotency-Key after a brief
delay (exponential backoff, capped). Writes are safe to
retry as long as the key stays the same.
429 — wait for
Retry-After or X-RateLimit-Reset,
then retry.
401 token_expired — refresh
(OAuth) or rotate (PAT). For OAuth, if the refresh attempt
itself returns invalid_grant with "session has
been revoked", start the authorize flow from scratch.
409 version_conflict —
re-GET and reapply your patch on the new
version.
409 slot_unavailable — the
slot was taken between your check and your create. Pick
another slot (the booking page or
/v1/slots will reflect the new state).
4xx other — surface to the
user; usually a bug in the request.
Always log request_id from
error.request_id (or
meta.request_id on success) — it's the fastest
way for support to trace what happened.