API reference/POST /v1/bookings

POST /v1/bookings

requires akidempotentaudited decision

Create a booking directly, without a prior hold.

Request


POST /v1/bookings HTTP/1.1
Authorization: Bearer ak_01HX7QQM…
Content-Type: application/json

{
  "start": "2026-06-01T14:00:00Z",
  "end": "2026-06-01T14:45:00Z",
  "meeting_class": "recruiting_interview",
  "title": "Demo call with Acme",
  "owner_email": "alex@acme.com",
  "calendar_type": "work",
  "description": "…"
}
owner_email
string:emailEmail address.
calendar_type
string
startreq
string:date-timeUTC date-time string.
endreq
string:date-timeUTC date-time string.
meeting_classreq
string
titlereq
stringMust not be empty.
description
string
attendees
object[]Contains email, displayName.
attendees[].emailreq
string:emailEmail address.
attendees[].displayName
string

Response


Returns 200 OK with the response body below. Successful booking arbitration writes an audit row you can query through the audit log.

200 OK · example

HTTP/1.1 200 OK
Content-Type: application/json

{
  "booking_id":            "3f0659cf-bb67-4947-99de-7b18cc77153a",
  "correlation_id":        "ea752c87-0969-4a15-96b7-46f1badb2359",
  "start":                 "2026-06-01T14:00:00.000Z",
  "end":                   "2026-06-01T14:45:00.000Z",
  "title":                 "Demo call with Acme",
  "description":           null,
  "calendar_type":         "work",
  "attendees":             [{ "email": "guest@example.com", "displayName": "Jane Guest" }],
  "status":                "committed",
  "pending_notifications": []
}

Errors


CodeDescription
400Validation failed — body is malformed or missing required fields.
401Missing or invalid API key. Send the raw key as a Bearer token in the Authorization header.
403Agent does not hold the permission scope required for this call (e.g. preempt on a higher-priority class).
404Calendar owner or booking id not found.
409Conflict — the requested slot was already committed at higher priority. Inspect alternatives[] in the response body.
422Validation error — the request body is structurally valid but semantically rejected. Common causes: earliest_start is in the past (PAST_TIME), the window is shorter than the requested duration (WINDOW_TOO_NARROW), the chosen slot is outside the hold window (SLOT_OUTSIDE_HOLD), or an idempotency key was reused with a different body (IDEMPOTENCY_CONFLICT). The error code field names the specific cause.