---
title: "Create a new appointment in a connected calendar after explicit user confirmation; checks the slot is still free right before writing"
method: POST
path: "/v1/integrations/{id}/events"
---

# Create a new appointment in a connected calendar after explicit user confirmation; checks the slot is still free right before writing

`POST /v1/integrations/{id}/events`

## Request

- Base URL: `https://volai.cz`
- URL: `https://volai.cz/v1/integrations/{id}/events`
- Auth: HTTP bearer

Creates an appointment in a connected calendar after explicit user confirmation (confirm: true). Provide exactly one of end or durationMinutes. idempotencyKey is optional - the same value sent again returns the already-created event instead of a second write. The slot is checked to still be free right before writing; the response is the freshly read event, the same shape as GET .../events/{eventId}.

## Path parameters

- `id` string, required

## Request body

- object
  - `calendarId` string, required: Calendar id from list_calendars, for example primary.
  - `busyCalendarIds` string[]: Other calendars in the same connection whose events also block a slot; nothing is written into them, so read-only calendars are fine. At most 4, without duplicates and without calendarId itself.
  - `start` string, date-time, required: Start of the appointment, RFC 3339 with an offset.
  - `end` string, date-time: End of the appointment, RFC 3339 with an offset. Provide exactly one of end or durationMinutes.
  - `durationMinutes` union: Length of the appointment in minutes. Provide exactly one of end or durationMinutes.
    - 15
    - 30
    - 45
    - 60
    - 90
    - 120
  - `title` string, required: Event title shown in the calendar.
  - `description` string: Additional details about the appointment, shown next to the title in the calendar entry.
  - `idempotencyKey` string: Optional booking key without control characters, semicolons, commas or backslashes. Sending the same value again returns the already-created event instead of creating a second one.
  - `confirm` boolean: Must be true, confirming the user has explicitly approved this exact date, time and title. Without it the request is rejected with calendar_confirmation_required.

## Response `201`

The newly created event, freshly read back from the provider

- object
  - `event` object, required
    - `calendarId` string, required
    - `externalId` string, required: Opaque event ID from the event list. Pass unchanged as eventId; Apple resource IDs are not iCalendar UIDs.
    - `title` string, required
    - `start` string, required
    - `end` string, required
    - `timezone` string
    - `recurring` boolean
    - `status` string, required
    - `sourceRevision` string, required
    - `provider` 'google-calendar' | 'apple-calendar', required
    - `sourceUrl` string, required
    - `fetchedAt` string, required
    - `etag` string

## Other responses

- `400`: Error codes: calendar_unsupported (request), validation (request), calendar_invalid_calendar (request), calendar_invalid_range (request), calendar_confirmation_required (request).
- `401`: Error codes: unauthorized (request).
- `403`: Error codes: account_suspended (account).
- `404`: Error codes: calendar_not_found (account).
- `409`: Error codes: calendar_read_only (account), calendar_busy (busy), calendar_refresh_in_progress (busy), calendar_unauthorized (account), calendar_oauth_failed (account), calendar_credentials_unavailable (account), calendar_invalid_credentials (account), calendar_slot_taken (busy).
- `429`: Error codes: rate_limited (busy).
- `500`: Error codes: internal_error (service).
- `502`: Error codes: calendar_provider_error (service), calendar_invalid_provider_response (service).
- `503`: Error codes: calendar_not_configured (service), calendar_unavailable (service).

---

[API](https://skmtc.dev/volai/apis/volai-rest-api.md) · [All operations](https://skmtc.dev/volai/apis/volai-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/volai/apis/volai-rest-api/revisions/12029b05e2fa?raw)
