{
  "openapi": "3.1.0",
  "info": {
    "title": "Zaptime API",
    "version": "1.0.0",
    "summary": "Public booking API for Zaptime event types.",
    "description": "Zaptime is an online meeting scheduling and booking calendar (https://zaptime.cz, English: https://zaptime.app).\n\nThis API lets you read available time slots of an event type and create, reschedule, confirm or cancel reservations. Every event type has its own API token; get it in the app at https://my.zaptime.app/calendars and send it as a Bearer token. When the event type is disabled, all event type related endpoints return 403.\n\nHuman readable docs: https://docs.zaptime.app/",
    "contact": {
      "name": "Zaptime support",
      "email": "support@zaptime.app",
      "url": "https://zaptime.cz"
    },
    "termsOfService": "https://zaptime.cz/terms/",
    "license": {
      "name": "Proprietary",
      "url": "https://zaptime.cz/terms/"
    }
  },
  "externalDocs": {
    "description": "Zaptime developer documentation",
    "url": "https://docs.zaptime.app/"
  },
  "servers": [
    {
      "url": "https://api.zaptime.app",
      "description": "Production"
    },
    {
      "url": "https://zaptime.app/api",
      "description": "Production (path based alias)"
    }
  ],
  "tags": [
    {
      "name": "Time slots"
    },
    {
      "name": "Reservations"
    },
    {
      "name": "Event types"
    },
    {
      "name": "Payments"
    },
    {
      "name": "Reference data"
    }
  ],
  "paths": {
    "/time-slots": {
      "get": {
        "tags": [
          "Time slots"
        ],
        "operationId": "listTimeSlots",
        "summary": "List available time slots",
        "description": "Returns bookable time slots of the event type between `from` (start of day) and `until` (end of day).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-09-01"
          },
          {
            "name": "until",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date"
            },
            "example": "2026-09-30"
          }
        ],
        "responses": {
          "200": {
            "description": "Available time slots.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TimeSlot"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations": {
      "post": {
        "tags": [
          "Reservations"
        ],
        "operationId": "createReservation",
        "summary": "Create a confirmed reservation",
        "description": "Books the given time slot immediately. Use `/reservations/prepare` + `/reservations/{reservationUuid}/confirm` for a two step flow (for example when a payment is required).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReservationInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reservation result. `success` is false when the slot is no longer available or is being booked concurrently.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ReservationResult"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations/prepare": {
      "post": {
        "tags": [
          "Reservations"
        ],
        "operationId": "prepareReservation",
        "summary": "Prepare a reservation waiting for confirmation",
        "description": "Holds the time slot. Unconfirmed prepared reservations are cancelled automatically after the timespan configured in the app.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReservationInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Prepared reservation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ReservationResult"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations/{reservationUuid}": {
      "put": {
        "tags": [
          "Reservations"
        ],
        "operationId": "rescheduleReservation",
        "summary": "Reschedule a reservation",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "reservationUuid",
            "in": "path",
            "required": true,
            "description": "UUID of the reservation.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "start",
                  "end"
                ],
                "properties": {
                  "start": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "end": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "timezone": {
                    "type": "string",
                    "example": "Europe/Prague"
                  },
                  "overrideToken": {
                    "type": "string",
                    "description": "Organizer override token that allows rescheduling outside the public reschedule rules."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reschedule result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "$ref": "#/components/schemas/ReservationResult"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      },
      "delete": {
        "tags": [
          "Reservations"
        ],
        "operationId": "cancelReservation",
        "summary": "Cancel a reservation",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "reservationUuid",
            "in": "path",
            "required": true,
            "description": "UUID of the reservation.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancellation result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations/{reservationUuid}/confirm": {
      "post": {
        "tags": [
          "Reservations"
        ],
        "operationId": "confirmReservation",
        "summary": "Confirm a prepared reservation",
        "description": "Confirms a reservation created via `/reservations/prepare`. Passed attributes update the reservation. If the event type requires payment, a successful payment must exist first (422 otherwise).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "reservationUuid",
            "in": "path",
            "required": true,
            "description": "UUID of the reservation.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone": {
                    "type": "string"
                  },
                  "firstname": {
                    "type": "string"
                  },
                  "lastname": {
                    "type": "string"
                  },
                  "customFields": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/CustomFieldValue"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmation result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/ReservationResult"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "meetLink": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Google Meet link when the location is Google Meet."
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations/{reservationUuid}/refresh": {
      "post": {
        "tags": [
          "Reservations"
        ],
        "operationId": "refreshReservation",
        "summary": "Refresh a prepared reservation",
        "description": "Extends the hold of a reservation that is waiting for confirmation or has expired.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "reservationUuid",
            "in": "path",
            "required": true,
            "description": "UUID of the reservation.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Refresh result.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {},
                      "maxItems": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/reservations/{reservationUuid}/payments": {
      "post": {
        "tags": [
          "Payments"
        ],
        "operationId": "createReservationPayment",
        "summary": "Create a Stripe payment intent for a reservation",
        "description": "Only available when Stripe is configured for the event type (400 otherwise). The returned client secret is used with Stripe.js on the connected account.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "reservationUuid",
            "in": "path",
            "required": true,
            "description": "UUID of the reservation.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "name": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "street": {
                    "type": "string"
                  },
                  "city": {
                    "type": "string"
                  },
                  "postalCode": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string",
                    "description": "ISO 3166-1 alpha-2 country code."
                  },
                  "taxId": {
                    "type": "string"
                  },
                  "crn": {
                    "type": "string",
                    "description": "Company registration number."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Payment intent created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "clientSecret": {
                          "type": "string"
                        },
                        "paymentIntentId": {
                          "type": "string"
                        },
                        "stripeAccountId": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "integer",
                          "description": "Amount in the smallest currency unit."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Stripe is not configured for this event type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/configuration": {
      "get": {
        "tags": [
          "Event types"
        ],
        "operationId": "getEventTypeConfiguration",
        "summary": "Get event type configuration",
        "description": "Returns the booking calendar configuration (locale, theme, texts, calendar title) of the event type that belongs to the token.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Event type configuration.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "configuration": {
                          "$ref": "#/components/schemas/EventTypeConfiguration"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/event-types/init": {
      "post": {
        "tags": [
          "Event types"
        ],
        "operationId": "initEventType",
        "summary": "Initialize event type",
        "description": "Returns configuration, custom fields and, when `reservationUuid` is passed, the reservation to reschedule. This is the only endpoint that also works for disabled event types (`disabled: true`).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reservationUuid": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event type initialized.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "disabled": {
                          "type": "boolean"
                        },
                        "configuration": {
                          "$ref": "#/components/schemas/EventTypeConfiguration"
                        },
                        "customFields": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/CustomField"
                          }
                        },
                        "reservation": {
                          "$ref": "#/components/schemas/Reservation"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthenticated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          }
        }
      }
    },
    "/timezones": {
      "get": {
        "tags": [
          "Reference data"
        ],
        "operationId": "listTimezones",
        "summary": "List supported IANA timezones",
        "responses": {
          "200": {
            "description": "Timezone identifiers.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "Europe/Prague",
                        "UTC"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "security": []
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Event type API token from https://my.zaptime.app/calendars."
      }
    },
    "responses": {
      "Unauthenticated": {
        "description": "Missing or invalid token.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "success"
              ],
              "properties": {
                "success": {
                  "type": "boolean"
                },
                "message": {
                  "type": "string"
                }
              }
            },
            "example": {
              "success": false,
              "message": "Unauthenticated."
            }
          }
        }
      },
      "Forbidden": {
        "description": "The event type is disabled or the action is not allowed.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Validation failed.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "message": {
                  "type": "string"
                },
                "errors": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "TimeSlot": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "dateIso8601": {
            "type": "string",
            "format": "date-time"
          },
          "readable_start": {
            "type": "string",
            "example": "07:00"
          },
          "start": {
            "type": "string",
            "format": "date-time"
          },
          "startIso8601": {
            "type": "string",
            "format": "date-time"
          },
          "readable_end": {
            "type": "string",
            "example": "07:30"
          },
          "end": {
            "type": "string",
            "format": "date-time"
          },
          "endIso8601": {
            "type": "string",
            "format": "date-time"
          },
          "seats": {
            "type": "integer"
          },
          "available_seats": {
            "type": "integer"
          },
          "booked": {
            "type": "boolean"
          },
          "calendar_id": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "readable_type": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        }
      },
      "Location": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "Must match one of the locations enabled on the event type, for example `google-meet`, `phone`, `address`.",
            "example": "google-meet"
          },
          "value": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "CustomFieldValue": {
        "type": "object",
        "required": [
          "uuid"
        ],
        "properties": {
          "uuid": {
            "type": "string"
          },
          "value": {
            "description": "Value of the custom field; type depends on the field."
          }
        }
      },
      "CustomField": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "mergeTag": {
            "type": "string",
            "example": "FIRST_NAME"
          },
          "type": {
            "type": "string",
            "example": "text"
          },
          "order": {
            "type": "integer"
          },
          "required": {
            "type": "boolean"
          }
        }
      },
      "ReservationInput": {
        "type": "object",
        "required": [
          "start",
          "end",
          "email"
        ],
        "properties": {
          "start": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-10T11:30:00+00:00"
          },
          "end": {
            "type": "string",
            "format": "date-time",
            "example": "2026-09-10T12:00:00+00:00"
          },
          "timezone": {
            "type": "string",
            "example": "Europe/Prague"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "firstname": {
            "type": "string"
          },
          "lastname": {
            "type": "string"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "guests": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "customFields": {
            "type": "array",
            "description": "Values for custom fields; required custom fields of the event type must be present.",
            "items": {
              "$ref": "#/components/schemas/CustomFieldValue"
            }
          }
        }
      },
      "ReservationResult": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "userId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "userName": {
            "type": [
              "string",
              "null"
            ]
          },
          "userEmail": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Reservation": {
        "type": "object",
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string"
          },
          "firstname": {
            "type": "string"
          },
          "lastname": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "start": {
            "type": "string",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          }
        }
      },
      "EventTypeConfiguration": {
        "type": "object",
        "description": "Booking calendar configuration. Additional keys may be present.",
        "properties": {
          "min": {
            "type": "integer"
          },
          "max": {
            "type": "integer"
          },
          "closestBookableDay": {
            "type": "integer"
          },
          "locale": {
            "type": "object",
            "properties": {
              "preset": {
                "type": "string"
              },
              "startDayOfWeek": {
                "type": "string"
              },
              "texts": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          },
          "theme": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string"
              },
              "borderRadius": {
                "type": "string"
              },
              "colors": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          },
          "profileImage": {
            "type": "string"
          },
          "externalBooking": {
            "type": "boolean"
          },
          "compact": {
            "type": "boolean"
          },
          "calendarTitle": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "additionalProperties": true
      }
    }
  }
}
