Getting started

Errors & rate limits

Errors use standard HTTP status codes and a stable, machine-readable code you can branch on.

Error format

409 Conflict
{
  "error": {
    "code": "slot_taken",
    "message": "This time slot was just booked by someone else. Please choose another slot."
  }
}

Branch on error.code; the message is written for people and may change.

Common codes

StatusCode
400missing_parameter / invalid_parameter

A required field is missing or malformed.

400invalid_json

The body isn't valid JSON.

400slot_in_past

The start time has already passed.

400booking_rule

The time breaks a booking rule (minimum notice, daily limit, ...).

401unauthorized

No key, or the key is invalid or revoked.

403insufficient_scope

The key doesn't have the scope this endpoint needs.

404not_found

No such object on this account.

409slot_unavailable

That time isn't offered. Pick a start from availability.

409event_type_inactive

The event type is turned off.

409slot_taken

Someone booked that time a moment ago.

409cannot_reschedule / cannot_cancel

The meeting is in the past or already cancelled.

429rate_limited

Too many requests. Wait for Retry-After seconds.

500internal_error

Something failed on our side. Safe to retry.

Rate limits

Each key can make 120 requests per minute. Every response tells you where you stand:

Response headers
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1791230400

Over the limit you'll get 429 rate_limited with a Retry-After header in seconds. Wait that long, then retry. For steady high volume, contact us.

Retrying safely

  • Retry 429 and 5xx responses with exponential backoff (1s, 2s, 4s...).
  • Don't retry 4xx errors other than 429; fix the request instead.
  • Before retrying a booking that timed out, list bookings for the guest (GET /bookings?guest_email=...) to check it wasn't created.