From ae7f8f1653613c4c220c6e35d3011e6da108926d Mon Sep 17 00:00:00 2001 From: Lauris Skraucis Date: Tue, 16 Sep 2025 16:27:42 +0200 Subject: [PATCH] feat: v2 show hidden attendees for authenticated requests (#23868) * refactor: return attendees when fetching all bookings * refactor: v2 show hidden attendees for authenticated requests * chore: regenerate docs * chore: add test --- .../controllers/bookings.controller.ts | 73 ++- .../e2e/seated-bookings.e2e-spec.ts | 254 +++++++-- .../2024-08-13/services/bookings.service.ts | 132 +++-- .../2024-08-13/services/output.service.ts | 31 +- apps/api/v2/swagger/documentation.json | 514 +++++++++++------- docs/api-reference/v2/openapi.json | 514 +++++++++++------- 6 files changed, 977 insertions(+), 541 deletions(-) diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts index 092b4f9c4a..64ed229bcf 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/bookings.controller.ts @@ -11,7 +11,12 @@ import { BookingReferencesService_2024_08_13 } from "@/ee/bookings/2024-08-13/se import { BookingsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/bookings.service"; import { CalVideoService } from "@/ee/bookings/2024-08-13/services/cal-video.service"; import { VERSION_2024_08_13_VALUE, VERSION_2024_08_13 } from "@/lib/api-versions"; -import { API_KEY_OR_ACCESS_TOKEN_HEADER } from "@/lib/docs/headers"; +import { + API_KEY_OR_ACCESS_TOKEN_HEADER, + OPTIONAL_API_KEY_OR_ACCESS_TOKEN_HEADER, + OPTIONAL_X_CAL_CLIENT_ID_HEADER, + OPTIONAL_X_CAL_SECRET_KEY_HEADER, +} from "@/lib/docs/headers"; import { PlatformPlan } from "@/modules/auth/decorators/billing/platform-plan.decorator"; import { AuthOptionalUser, @@ -22,8 +27,8 @@ import { Permissions } from "@/modules/auth/decorators/permissions/permissions.d import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard"; import { OptionalApiAuthGuard } from "@/modules/auth/guards/optional-api-auth/optional-api-auth.guard"; import { PermissionsGuard } from "@/modules/auth/guards/permissions/permissions.guard"; +import { ApiAuthGuardUser } from "@/modules/auth/strategies/api-auth/api-auth.strategy"; import { UsersService } from "@/modules/users/services/users.service"; -import { UserWithProfile } from "@/modules/users/users.repository"; import { Controller, Post, @@ -101,6 +106,9 @@ export class BookingsController_2024_08_13 { @Post("/") @UseGuards(OptionalApiAuthGuard) + @ApiHeader(OPTIONAL_X_CAL_CLIENT_ID_HEADER) + @ApiHeader(OPTIONAL_X_CAL_SECRET_KEY_HEADER) + @ApiHeader(OPTIONAL_API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Create a booking", description: ` @@ -122,6 +130,9 @@ export class BookingsController_2024_08_13 { And 2 ways to book and event type belonging to a team: 1. Provide \`eventTypeId\` in the request body. 2. Provide \`eventTypeSlug\` and \`teamSlug\` and optionally \`organizationSlug\` if the team with the teamSlug is within an organization. + + If you are creating a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or + you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner. `, }) @ApiBody({ @@ -161,7 +172,10 @@ export class BookingsController_2024_08_13 { } @Get("/:bookingUid") - @UseGuards(BookingUidGuard) + @UseGuards(BookingUidGuard, OptionalApiAuthGuard) + @ApiHeader(OPTIONAL_X_CAL_CLIENT_ID_HEADER) + @ApiHeader(OPTIONAL_X_CAL_SECRET_KEY_HEADER) + @ApiHeader(OPTIONAL_API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Get a booking", description: `\`:bookingUid\` can be @@ -170,10 +184,17 @@ export class BookingsController_2024_08_13 { 2. uid of one of the recurring booking recurrences - 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences).`, + 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences). + + If you are fetching a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or + you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner. + `, }) - async getBooking(@Param("bookingUid") bookingUid: string): Promise { - const booking = await this.bookingsService.getBooking(bookingUid); + async getBooking( + @Param("bookingUid") bookingUid: string, + @GetOptionalUser() user: AuthOptionalUser + ): Promise { + const booking = await this.bookingsService.getBooking(bookingUid, user); return { status: SUCCESS_STATUS, @@ -218,7 +239,7 @@ export class BookingsController_2024_08_13 { @ApiOperation({ summary: "Get all bookings" }) async getBookings( @Query() queryParams: GetBookingsInput_2024_08_13, - @GetUser() user: UserWithProfile + @GetUser() user: ApiAuthGuardUser ): Promise { const profile = this.usersService.getUserMainProfile(user); @@ -236,7 +257,10 @@ export class BookingsController_2024_08_13 { } @Post("/:bookingUid/reschedule") - @UseGuards(BookingUidGuard) + @UseGuards(BookingUidGuard, OptionalApiAuthGuard) + @ApiHeader(OPTIONAL_X_CAL_CLIENT_ID_HEADER) + @ApiHeader(OPTIONAL_X_CAL_SECRET_KEY_HEADER) + @ApiHeader(OPTIONAL_API_KEY_OR_ACCESS_TOKEN_HEADER) @ApiOperation({ summary: "Reschedule a booking", description: "Reschedule a booking or seated booking", @@ -248,17 +272,20 @@ export class BookingsController_2024_08_13 { { $ref: getSchemaPath(RescheduleSeatedBookingInput_2024_08_13) }, ], }, - description: - "Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2)", + description: `Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2). + + If you are rescheduling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or + you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.`, }) @ApiExtraModels(RescheduleBookingInput_2024_08_13, RescheduleSeatedBookingInput_2024_08_13) async rescheduleBooking( @Param("bookingUid") bookingUid: string, @Body(new RescheduleBookingInputPipe()) body: RescheduleBookingInput, - @Req() request: Request + @Req() request: Request, + @GetOptionalUser() user: AuthOptionalUser ): Promise { - const newBooking = await this.bookingsService.rescheduleBooking(request, bookingUid, body); + const newBooking = await this.bookingsService.rescheduleBooking(request, bookingUid, body, user); await this.bookingsService.billRescheduledBooking(newBooking, bookingUid); return { @@ -268,7 +295,10 @@ export class BookingsController_2024_08_13 { } @Post("/:bookingUid/cancel") - @UseGuards(BookingUidGuard) + @UseGuards(BookingUidGuard, OptionalApiAuthGuard) + @ApiHeader(OPTIONAL_X_CAL_CLIENT_ID_HEADER) + @ApiHeader(OPTIONAL_X_CAL_SECRET_KEY_HEADER) + @ApiHeader(OPTIONAL_API_KEY_OR_ACCESS_TOKEN_HEADER) @HttpCode(HttpStatus.OK) @ApiOperation({ summary: "Cancel a booking", @@ -281,7 +311,11 @@ export class BookingsController_2024_08_13 { \nCancelling recurring seated bookings: For recurring seated bookings it is not possible to cancel all of them with 1 call - like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid.`, + like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid. + + If you are cancelling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or + you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner. + `, }) @ApiBody({ schema: { @@ -298,9 +332,10 @@ export class BookingsController_2024_08_13 { @Req() request: Request, @Param("bookingUid") bookingUid: string, @Body(new CancelBookingInputPipe()) - body: CancelBookingInput + body: CancelBookingInput, + @GetOptionalUser() user: AuthOptionalUser ): Promise { - const cancelledBooking = await this.bookingsService.cancelBooking(request, bookingUid, body); + const cancelledBooking = await this.bookingsService.cancelBooking(request, bookingUid, body, user); return { status: SUCCESS_STATUS, @@ -342,7 +377,7 @@ export class BookingsController_2024_08_13 { }) async reassignBooking( @Param("bookingUid") bookingUid: string, - @GetUser() user: UserWithProfile + @GetUser() user: ApiAuthGuardUser ): Promise { const booking = await this.bookingsService.reassignBooking(bookingUid, user); @@ -392,7 +427,7 @@ export class BookingsController_2024_08_13 { }) async confirmBooking( @Param("bookingUid") bookingUid: string, - @GetUser() user: UserWithProfile + @GetUser() user: ApiAuthGuardUser ): Promise { const booking = await this.bookingsService.confirmBooking(bookingUid, user); @@ -414,7 +449,7 @@ export class BookingsController_2024_08_13 { async declineBooking( @Param("bookingUid") bookingUid: string, @Body() body: DeclineBookingInput_2024_08_13, - @GetUser() user: UserWithProfile + @GetUser() user: ApiAuthGuardUser ): Promise { const booking = await this.bookingsService.declineBooking(bookingUid, user, body.reason); diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/seated-bookings.e2e-spec.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/seated-bookings.e2e-spec.ts index 34ef629779..1addb6a80c 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/seated-bookings.e2e-spec.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/e2e/seated-bookings.e2e-spec.ts @@ -437,61 +437,209 @@ describe("Bookings Endpoints 2024-08-13", () => { }); }); - it("should book an event type with attendees disabled", async () => { - const body: CreateBookingInput_2024_08_13 = { - start: new Date(Date.UTC(2030, 0, 9, 14, 0, 0)).toISOString(), - eventTypeId: seatedEventTypeIdAttendeesDisabledId, - attendee: { - name: nameAttendeeOne, - email: emailAttendeeOne, - timeZone: "Europe/Rome", - language: "it", - }, - bookingFieldsResponses: { - codingLanguage: "TypeScript", - }, - metadata: { - userId: "100", - }, - }; + describe("book an event type with attendees disabled but auth provided", () => { + let booking: CreateSeatedBookingOutput_2024_08_13; + it("should book an event type with attendees disabled and no auth provided", async () => { + const body: CreateBookingInput_2024_08_13 = { + start: new Date(Date.UTC(2030, 0, 9, 14, 0, 0)).toISOString(), + eventTypeId: seatedEventTypeIdAttendeesDisabledId, + attendee: { + name: nameAttendeeOne, + email: emailAttendeeOne, + timeZone: "Europe/Rome", + language: "it", + }, + bookingFieldsResponses: { + codingLanguage: "TypeScript", + }, + metadata: { + userId: "100", + }, + }; - return request(app.getHttpServer()) - .post("/v2/bookings") - .send(body) - .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) - .expect(201) - .then(async (response) => { - const responseBody: CreateBookingOutput_2024_08_13 = response.body; - expect(responseBody.status).toEqual(SUCCESS_STATUS); - expect(responseBody.data).toBeDefined(); - expect(responseDataIsCreateSeatedBooking(responseBody.data)).toBe(true); + return request(app.getHttpServer()) + .post("/v2/bookings") + .send(body) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(201) + .then(async (response) => { + const responseBody: CreateBookingOutput_2024_08_13 = response.body; + expect(responseBody.status).toEqual(SUCCESS_STATUS); + expect(responseBody.data).toBeDefined(); + expect(responseDataIsCreateSeatedBooking(responseBody.data)).toBe(true); - if (responseDataIsCreateSeatedBooking(responseBody.data)) { - const data: CreateSeatedBookingOutput_2024_08_13 = responseBody.data; - expect(data.seatUid).toBeDefined(); - expect(data.id).toBeDefined(); - expect(data.uid).toBeDefined(); - expect(data.hosts[0].id).toEqual(user.id); - expect(data.status).toEqual("accepted"); - expect(data.start).toEqual(body.start); - expect(data.end).toEqual( - DateTime.fromISO(body.start, { zone: "utc" }).plus({ hours: 1 }).toISO() - ); - expect(data.duration).toEqual(60); - expect(data.eventTypeId).toEqual(seatedEventTypeIdAttendeesDisabledId); - expect(data.eventType).toEqual({ - id: seatedEventTypeIdAttendeesDisabledId, - slug: seatedEventSlugAttendeesDisabled, - }); - expect(data.attendees.length).toEqual(0); - expect(data.location).toBeDefined(); - expect(data.absentHost).toEqual(false); - } else { - throw new Error( - "Invalid response data - expected seated booking but received non array response" - ); - } - }); + if (responseDataIsCreateSeatedBooking(responseBody.data)) { + const data: CreateSeatedBookingOutput_2024_08_13 = responseBody.data; + expect(data.seatUid).toBeDefined(); + expect(data.id).toBeDefined(); + expect(data.uid).toBeDefined(); + expect(data.hosts[0].id).toEqual(user.id); + expect(data.status).toEqual("accepted"); + expect(data.start).toEqual(body.start); + expect(data.end).toEqual( + DateTime.fromISO(body.start, { zone: "utc" }).plus({ hours: 1 }).toISO() + ); + expect(data.duration).toEqual(60); + expect(data.eventTypeId).toEqual(seatedEventTypeIdAttendeesDisabledId); + expect(data.eventType).toEqual({ + id: seatedEventTypeIdAttendeesDisabledId, + slug: seatedEventSlugAttendeesDisabled, + }); + expect(data.attendees.length).toEqual(0); + expect(data.location).toBeDefined(); + expect(data.absentHost).toEqual(false); + booking = data; + } else { + throw new Error( + "Invalid response data - expected seated booking but received non array response" + ); + } + }); + }); + + it("should fetch booking and not have attendees because no auth provided", async () => { + return request(app.getHttpServer()) + .get(`/v2/bookings/${booking.uid}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .expect(200) + .then(async (response) => { + const responseBody: GetBookingOutput_2024_08_13 = response.body; + expect(responseBody.status).toEqual(SUCCESS_STATUS); + expect(responseBody.data).toBeDefined(); + expect(responseDataIsGetSeatedBooking(responseBody.data)).toBe(true); + + if (responseDataIsGetSeatedBooking(responseBody.data)) { + const data: GetSeatedBookingOutput_2024_08_13 = responseBody.data; + expect(data.id).toBeDefined(); + expect(data.uid).toBeDefined(); + expect(data.hosts.length).toEqual(1); + expect(data.hosts[0].id).toEqual(user.id); + expect(data.status).toEqual("accepted"); + expect(data.start).toEqual(booking.start); + expect(data.end).toEqual(booking.end); + expect(data.duration).toEqual(60); + expect(data.eventTypeId).toEqual(seatedEventTypeIdAttendeesDisabledId); + expect(data.eventType).toEqual({ + id: seatedEventTypeIdAttendeesDisabledId, + slug: seatedEventSlugAttendeesDisabled, + }); + expect(data.attendees.length).toEqual(0); + expect(data.location).toBeDefined(); + expect(data.absentHost).toEqual(false); + await bookingsRepositoryFixture.deleteById(data.id); + } else { + throw new Error("Invalid response data - expected booking but received array response"); + } + }); + }); + }); + + describe("book an event type with attendees disabled but auth provided", () => { + let booking: CreateSeatedBookingOutput_2024_08_13; + + it("should book an event type with attendees disabled and owner auth provided", async () => { + const body: CreateBookingInput_2024_08_13 = { + start: new Date(Date.UTC(2030, 0, 9, 14, 0, 0)).toISOString(), + eventTypeId: seatedEventTypeIdAttendeesDisabledId, + attendee: { + name: nameAttendeeOne, + email: emailAttendeeOne, + timeZone: "Europe/Rome", + language: "it", + }, + bookingFieldsResponses: { + codingLanguage: "TypeScript", + }, + metadata: { + userId: "100", + }, + }; + + return request(app.getHttpServer()) + .post("/v2/bookings") + .send(body) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .set("Authorization", apiKeyString) + .expect(201) + .then(async (response) => { + const responseBody: CreateBookingOutput_2024_08_13 = response.body; + expect(responseBody.status).toEqual(SUCCESS_STATUS); + expect(responseBody.data).toBeDefined(); + expect(responseDataIsCreateSeatedBooking(responseBody.data)).toBe(true); + + if (responseDataIsCreateSeatedBooking(responseBody.data)) { + const data: CreateSeatedBookingOutput_2024_08_13 = responseBody.data; + expect(data.seatUid).toBeDefined(); + expect(data.id).toBeDefined(); + expect(data.uid).toBeDefined(); + expect(data.hosts[0].id).toEqual(user.id); + expect(data.status).toEqual("accepted"); + expect(data.start).toEqual(body.start); + expect(data.end).toEqual( + DateTime.fromISO(body.start, { zone: "utc" }).plus({ hours: 1 }).toISO() + ); + expect(data.duration).toEqual(60); + expect(data.eventTypeId).toEqual(seatedEventTypeIdAttendeesDisabledId); + expect(data.eventType).toEqual({ + id: seatedEventTypeIdAttendeesDisabledId, + slug: seatedEventSlugAttendeesDisabled, + }); + expect(data.attendees.length).toEqual(1); + expect(data.attendees[0].email).toEqual(emailAttendeeOne); + expect(data.attendees[0].name).toEqual(nameAttendeeOne); + expect(data.attendees[0].language).toEqual("it"); + expect(data.attendees[0].seatUid).toBeDefined(); + expect(data.location).toBeDefined(); + expect(data.absentHost).toEqual(false); + booking = data; + } else { + throw new Error( + "Invalid response data - expected seated booking but received non array response" + ); + } + }); + }); + + it("should fetch booking and have attendees", async () => { + return request(app.getHttpServer()) + .get(`/v2/bookings/${booking.uid}`) + .set(CAL_API_VERSION_HEADER, VERSION_2024_08_13) + .set("Authorization", apiKeyString) + .expect(200) + .then(async (response) => { + const responseBody: GetBookingOutput_2024_08_13 = response.body; + expect(responseBody.status).toEqual(SUCCESS_STATUS); + expect(responseBody.data).toBeDefined(); + expect(responseDataIsGetSeatedBooking(responseBody.data)).toBe(true); + + if (responseDataIsGetSeatedBooking(responseBody.data)) { + const data: GetSeatedBookingOutput_2024_08_13 = responseBody.data; + expect(data.id).toBeDefined(); + expect(data.uid).toBeDefined(); + expect(data.hosts.length).toEqual(1); + expect(data.hosts[0].id).toEqual(user.id); + expect(data.status).toEqual("accepted"); + expect(data.start).toEqual(booking.start); + expect(data.end).toEqual(booking.end); + expect(data.duration).toEqual(60); + expect(data.eventTypeId).toEqual(seatedEventTypeIdAttendeesDisabledId); + expect(data.eventType).toEqual({ + id: seatedEventTypeIdAttendeesDisabledId, + slug: seatedEventSlugAttendeesDisabled, + }); + expect(data.attendees.length).toEqual(1); + expect(data.attendees[0].email).toEqual(emailAttendeeOne); + expect(data.attendees[0].name).toEqual(nameAttendeeOne); + expect(data.attendees[0].language).toEqual("it"); + expect(data.attendees[0].seatUid).toBeDefined(); + expect(data.location).toBeDefined(); + expect(data.absentHost).toEqual(false); + await bookingsRepositoryFixture.deleteById(data.id); + } else { + throw new Error("Invalid response data - expected booking but received array response"); + } + }); + }); }); describe("cancel seated booking", () => { diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts index e28c4ec32f..b6093c0be4 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/bookings.service.ts @@ -7,6 +7,7 @@ import { PlatformBookingsService } from "@/ee/bookings/shared/platform-bookings. import { EventTypesRepository_2024_06_14 } from "@/ee/event-types/event-types_2024_06_14/event-types.repository"; import { getPagination } from "@/lib/pagination/pagination"; import { AuthOptionalUser } from "@/modules/auth/decorators/get-optional-user/get-optional-user.decorator"; +import { ApiAuthGuardUser } from "@/modules/auth/strategies/api-auth/api-auth.strategy"; import { BillingService } from "@/modules/billing/services/billing.service"; import { BookingSeatRepository } from "@/modules/booking-seat/booking-seat.repository"; import { KyselyReadService } from "@/modules/kysely/kysely-read.service"; @@ -120,7 +121,10 @@ export class BookingsService_2024_08_13 { if (!eventType) { this.errorsBookingsService.handleEventTypeToBeBookedNotFound(body); } - await this.checkBookingRequiresAuthenticationSetting(eventType, authUser); + const userIsEventTypeAdminOrOwner = authUser + ? await this.userIsEventTypeAdminOrOwner(authUser, eventType) + : false; + await this.checkBookingRequiresAuthenticationSetting(eventType, authUser, userIsEventTypeAdminOrOwner); if (eventType.schedulingType === "MANAGED") { throw new BadRequestException( @@ -140,13 +144,13 @@ export class BookingsService_2024_08_13 { await this.hasRequiredBookingFieldsResponses(body, eventType); if (isRecurring && isSeated) { - return await this.createRecurringSeatedBooking(request, body, eventType); + return await this.createRecurringSeatedBooking(request, body, eventType, userIsEventTypeAdminOrOwner); } if (isRecurring && !isSeated) { return await this.createRecurringBooking(request, body, eventType); } if (isSeated) { - return await this.createSeatedBooking(request, body, eventType); + return await this.createSeatedBooking(request, body, eventType, userIsEventTypeAdminOrOwner); } return await this.createRegularBooking(request, body, eventType); @@ -157,7 +161,8 @@ export class BookingsService_2024_08_13 { async checkBookingRequiresAuthenticationSetting( eventType: EventTypeWithOwnerAndTeam, - authUser: AuthOptionalUser + authUser: AuthOptionalUser, + userIsEventTypeAdminOrOwner: boolean ) { if (!eventType.bookingRequiresAuthentication) return true; if (!authUser) { @@ -166,15 +171,23 @@ export class BookingsService_2024_08_13 { ); } + if (!userIsEventTypeAdminOrOwner) { + throw new ForbiddenException( + "checkBookingRequiresAuthentication - user is not authorized to access this event type. User has to be either event type owner, host, team admin or owner or org admin or owner." + ); + } + } + + async userIsEventTypeAdminOrOwner(authUser: ApiAuthGuardUser, eventType: EventType) { const authUserId = authUser.id; const authUserRole = authUser.role; const eventTypeId = eventType.id; const teamId = eventType.teamId; - const bookingUserId = eventType.owner?.id || null; + const eventTypeOwnerId = eventType.userId || null; - if (authUserRole === "ADMIN") return; + if (authUserRole === "ADMIN") return true; - if (bookingUserId === authUserId) return; + if (eventTypeOwnerId === authUserId) return true; if (eventTypeId) { const [isUserHost, isUserAssigned] = await Promise.all([ @@ -182,7 +195,7 @@ export class BookingsService_2024_08_13 { this.eventTypesRepository.isUserAssignedToEventType(authUserId, eventTypeId), ]); - if (isUserHost || isUserAssigned) return; + if (isUserHost || isUserAssigned) return true; } if (teamId) { @@ -190,19 +203,17 @@ export class BookingsService_2024_08_13 { authUserId, teamId ); - if (membership) return; + if (membership) return true; } if ( - bookingUserId && - (await this.membershipsService.isUserOrgAdminOrOwnerOfAnotherUser(authUserId, bookingUserId)) + eventTypeOwnerId && + (await this.membershipsService.isUserOrgAdminOrOwnerOfAnotherUser(authUserId, eventTypeOwnerId)) ) { - return; + return true; } - throw new ForbiddenException( - "checkBookingRequiresAuthentication - user is not authorized to access this event type. User has to be either event type owner, host, team admin or owner or org admin or owner." - ); + return false; } async getBookedEventType(body: CreateBookingInput) { @@ -476,7 +487,8 @@ export class BookingsService_2024_08_13 { async createRecurringSeatedBooking( request: Request, body: CreateRecurringBookingInput_2024_08_13, - eventType: EventTypeWithOwnerAndTeam + eventType: EventTypeWithOwnerAndTeam, + userIsEventTypeAdminOrOwner: boolean ) { const bookingRequest = await this.inputService.createRecurringBookingRequest(request, body, eventType); const bookings = await handleNewRecurringBooking({ @@ -491,7 +503,8 @@ export class BookingsService_2024_08_13 { areCalendarEventsEnabled: bookingRequest.areCalendarEventsEnabled, }); return this.outputService.getOutputCreateRecurringSeatedBookings( - bookings.map((booking) => ({ uid: booking.uid || "", seatUid: booking.seatReferenceUid || "" })) + bookings.map((booking) => ({ uid: booking.uid || "", seatUid: booking.seatReferenceUid || "" })), + userIsEventTypeAdminOrOwner ); } @@ -528,7 +541,8 @@ export class BookingsService_2024_08_13 { async createSeatedBooking( request: Request, body: CreateBookingInput_2024_08_13, - eventType: EventTypeWithOwnerAndTeam + eventType: EventTypeWithOwnerAndTeam, + userIsEventTypeAdminOrOwner: boolean ) { const bookingRequest = await this.inputService.createBookingRequest(request, body, eventType); try { @@ -554,7 +568,11 @@ export class BookingsService_2024_08_13 { throw new Error(`Booking with uid=${booking.uid} was not found in the database`); } - return this.outputService.getOutputCreateSeatedBooking(databaseBooking, booking.seatReferenceUid || ""); + return this.outputService.getOutputCreateSeatedBooking( + databaseBooking, + booking.seatReferenceUid || "", + userIsEventTypeAdminOrOwner + ); } catch (error) { if (error instanceof Error) { if (error.message === "booking_seats_full_error") { @@ -565,8 +583,12 @@ export class BookingsService_2024_08_13 { } } - async getBooking(uid: string) { + async getBooking(uid: string, authUser: AuthOptionalUser) { const booking = await this.bookingsRepository.getByUidWithAttendeesWithBookingSeatAndUserAndEvent(uid); + const userIsEventTypeAdminOrOwner = + authUser && booking?.eventType + ? await this.userIsEventTypeAdminOrOwner(authUser, booking.eventType) + : false; if (booking) { const isRecurring = !!booking.recurringEventId; @@ -576,13 +598,12 @@ export class BookingsService_2024_08_13 { return this.outputService.getOutputRecurringBooking(booking); } if (isRecurring && isSeated) { - return this.outputService.getOutputRecurringSeatedBooking( - booking, - !!booking.eventType?.seatsShowAttendees - ); + const showAttendees = userIsEventTypeAdminOrOwner || !!booking.eventType?.seatsShowAttendees; + return this.outputService.getOutputRecurringSeatedBooking(booking, showAttendees); } if (isSeated) { - return this.outputService.getOutputSeatedBooking(booking, !!booking.eventType?.seatsShowAttendees); + const showAttendees = userIsEventTypeAdminOrOwner || !!booking.eventType?.seatsShowAttendees; + return this.outputService.getOutputSeatedBooking(booking, showAttendees); } return this.outputService.getOutputBooking(booking); } @@ -594,10 +615,9 @@ export class BookingsService_2024_08_13 { const ids = recurringBooking.map((booking) => booking.id); const isRecurringSeated = !!recurringBooking[0].eventType?.seatsPerTimeSlot; if (isRecurringSeated) { - return this.outputService.getOutputRecurringSeatedBookings( - ids, - !!recurringBooking[0].eventType?.seatsShowAttendees - ); + const showAttendees = + userIsEventTypeAdminOrOwner || !!recurringBooking[0].eventType?.seatsShowAttendees; + return this.outputService.getOutputRecurringSeatedBookings(ids, showAttendees); } return this.outputService.getOutputRecurringBookings(ids); @@ -663,19 +683,9 @@ export class BookingsService_2024_08_13 { if (isRecurring && !isSeated) { formattedBookings.push(this.outputService.getOutputRecurringBooking(formatted)); } else if (isRecurring && isSeated) { - formattedBookings.push( - this.outputService.getOutputRecurringSeatedBooking( - formatted, - !!formatted.eventType?.seatsShowAttendees - ) - ); + formattedBookings.push(this.outputService.getOutputRecurringSeatedBooking(formatted, true)); } else if (isSeated) { - formattedBookings.push( - await this.outputService.getOutputSeatedBooking( - formatted, - !!formatted.eventType?.seatsShowAttendees - ) - ); + formattedBookings.push(await this.outputService.getOutputSeatedBooking(formatted, true)); } else { formattedBookings.push(await this.outputService.getOutputBooking(formatted)); } @@ -718,7 +728,12 @@ export class BookingsService_2024_08_13 { return queryParamsAttendeeEmail; } - async rescheduleBooking(request: Request, bookingUid: string, body: RescheduleBookingInput) { + async rescheduleBooking( + request: Request, + bookingUid: string, + body: RescheduleBookingInput, + authUser: AuthOptionalUser + ) { try { await this.canRescheduleBooking(bookingUid); const bookingRequest = await this.inputService.createRescheduleBookingRequest( @@ -747,6 +762,10 @@ export class BookingsService_2024_08_13 { throw new Error(`Booking with uid=${booking.uid} was not found in the database`); } + const userIsEventTypeAdminOrOwner = + authUser && databaseBooking.eventType + ? await this.userIsEventTypeAdminOrOwner(authUser, databaseBooking.eventType) + : false; const isRecurring = !!databaseBooking.recurringEventId; const isSeated = !!databaseBooking.eventType?.seatsPerTimeSlot; @@ -756,13 +775,15 @@ export class BookingsService_2024_08_13 { if (isRecurring && isSeated) { return this.outputService.getOutputCreateRecurringSeatedBooking( databaseBooking, - booking?.seatReferenceUid || "" + booking?.seatReferenceUid || "", + userIsEventTypeAdminOrOwner ); } if (isSeated) { return this.outputService.getOutputCreateSeatedBooking( databaseBooking, - booking.seatReferenceUid || "" + booking.seatReferenceUid || "", + userIsEventTypeAdminOrOwner ); } return this.outputService.getOutputBooking(databaseBooking); @@ -790,7 +811,12 @@ export class BookingsService_2024_08_13 { return booking; } - async cancelBooking(request: Request, bookingUid: string, body: CancelBookingInput) { + async cancelBooking( + request: Request, + bookingUid: string, + body: CancelBookingInput, + authUser: AuthOptionalUser + ) { if (this.inputService.isCancelSeatedBody(body)) { const seat = await this.bookingSeatRepository.getByReferenceUid(body.seatUid); @@ -821,13 +847,13 @@ export class BookingsService_2024_08_13 { } if ("cancelSubsequentBookings" in body && body.cancelSubsequentBookings) { - return this.getAllRecurringBookingsByIndividualUid(bookingUid); + return this.getAllRecurringBookingsByIndividualUid(bookingUid, authUser); } - return this.getBooking(bookingUid); + return this.getBooking(bookingUid, authUser); } - private async getAllRecurringBookingsByIndividualUid(bookingUid: string) { + private async getAllRecurringBookingsByIndividualUid(bookingUid: string, authUser: AuthOptionalUser) { const booking = await this.bookingsRepository.getByUid(bookingUid); const recurringBookingUid = booking?.recurringEventId; if (!recurringBookingUid) { @@ -836,7 +862,7 @@ export class BookingsService_2024_08_13 { ); } - return await this.getBooking(recurringBookingUid); + return await this.getBooking(recurringBookingUid, authUser); } async markAbsent(bookingUid: string, bookingOwnerId: number, body: MarkAbsentBookingInput_2024_08_13) { @@ -1003,7 +1029,7 @@ export class BookingsService_2024_08_13 { } } - async confirmBooking(bookingUid: string, requestUser: UserWithProfile) { + async confirmBooking(bookingUid: string, requestUser: ApiAuthGuardUser) { const booking = await this.bookingsRepository.getByUid(bookingUid); if (!booking) { throw new NotFoundException(`Booking with uid=${bookingUid} was not found in the database`); @@ -1032,10 +1058,10 @@ export class BookingsService_2024_08_13 { }, }); - return this.getBooking(bookingUid); + return this.getBooking(bookingUid, requestUser); } - async declineBooking(bookingUid: string, requestUser: UserWithProfile, reason?: string) { + async declineBooking(bookingUid: string, requestUser: ApiAuthGuardUser, reason?: string) { const booking = await this.bookingsRepository.getByUid(bookingUid); if (!booking) { throw new NotFoundException(`Booking with uid=${bookingUid} was not found in the database`); @@ -1065,7 +1091,7 @@ export class BookingsService_2024_08_13 { }, }); - return this.getBooking(bookingUid); + return this.getBooking(bookingUid, requestUser); } async getCalendarLinks(bookingUid: string): Promise { diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts index 0fccb9af77..3b0ad2da0e 100644 --- a/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts +++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/output.service.ts @@ -229,7 +229,8 @@ export class OutputBookingsService_2024_08_13 { status: databaseBooking.status.toLowerCase(), cancellationReason: databaseBooking.status === BookingStatus.CANCELLED ? databaseBooking.cancellationReason : undefined, - cancelledByEmail: databaseBooking.status === BookingStatus.CANCELLED ? databaseBooking.cancelledBy : undefined, + cancelledByEmail: + databaseBooking.status === BookingStatus.CANCELLED ? databaseBooking.cancelledBy : undefined, reschedulingReason: bookingResponses?.rescheduledReason, rescheduledFromUid: databaseBooking.fromReschedule || undefined, start: databaseBooking.startTime, @@ -269,12 +270,11 @@ export class OutputBookingsService_2024_08_13 { async getOutputCreateSeatedBooking( databaseBooking: DatabaseBooking, - seatUid: string + seatUid: string, + userIsEventTypeAdminOrOwner: boolean ): Promise { - const getSeatedBookingOutput = await this.getOutputSeatedBooking( - databaseBooking, - !!databaseBooking.eventType?.seatsShowAttendees - ); + const showAttendees = userIsEventTypeAdminOrOwner || !!databaseBooking.eventType?.seatsShowAttendees; + const getSeatedBookingOutput = await this.getOutputSeatedBooking(databaseBooking, showAttendees); return { ...getSeatedBookingOutput, seatUid }; } @@ -377,7 +377,10 @@ export class OutputBookingsService_2024_08_13 { return transformed.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()); } - async getOutputCreateRecurringSeatedBookings(bookings: { uid: string; seatUid: string }[]) { + async getOutputCreateRecurringSeatedBookings( + bookings: { uid: string; seatUid: string }[], + userIsEventTypeAdminOrOwner: boolean + ) { const transformed = []; for (const booking of bookings) { @@ -386,7 +389,13 @@ export class OutputBookingsService_2024_08_13 { if (!databaseBooking) { throw new Error(`Booking with uid=${booking.uid} was not found in the database`); } - transformed.push(this.getOutputCreateRecurringSeatedBooking(databaseBooking, booking.seatUid)); + transformed.push( + this.getOutputCreateRecurringSeatedBooking( + databaseBooking, + booking.seatUid, + userIsEventTypeAdminOrOwner + ) + ); } return transformed.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()); @@ -394,11 +403,13 @@ export class OutputBookingsService_2024_08_13 { getOutputCreateRecurringSeatedBooking( databaseBooking: DatabaseBooking, - seatUid: string + seatUid: string, + userIsEventTypeAdminOrOwner: boolean ): CreateRecurringSeatedBookingOutput_2024_08_13 { + const showAttendees = userIsEventTypeAdminOrOwner || !!databaseBooking.eventType?.seatsShowAttendees; const getRecurringSeatedBookingOutput = this.getOutputRecurringSeatedBooking( databaseBooking, - !!databaseBooking.eventType?.seatsShowAttendees + showAttendees ); return { ...getRecurringSeatedBookingOutput, seatUid }; } diff --git a/apps/api/v2/swagger/documentation.json b/apps/api/v2/swagger/documentation.json index 3b3c26f84d..862daa8e20 100644 --- a/apps/api/v2/swagger/documentation.json +++ b/apps/api/v2/swagger/documentation.json @@ -28,8 +28,8 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { - "example": 10, "type": "number" } }, @@ -38,8 +38,8 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { - "example": 0, "type": "number" } }, @@ -48,8 +48,8 @@ "required": false, "in": "query", "description": "Filter managed users by email. If you want to filter by multiple emails, separate them with a comma.", + "example": "?emails=email1@example.com,email2@example.com", "schema": { - "example": "?emails=email1@example.com,email2@example.com", "type": "array", "items": { "type": "string" @@ -447,11 +447,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -460,10 +460,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -660,11 +660,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -673,10 +673,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -1173,8 +1173,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -1186,8 +1186,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -1265,8 +1265,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -1278,8 +1278,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -1501,8 +1501,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -1521,8 +1521,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -1531,8 +1531,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -1541,8 +1541,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -1551,8 +1551,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -1561,8 +1561,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -1571,8 +1571,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -1581,8 +1581,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -1591,8 +1591,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1601,8 +1601,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -1611,8 +1611,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1621,8 +1621,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -1631,8 +1631,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1641,8 +1641,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -1651,8 +1651,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -1665,8 +1665,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -1679,8 +1679,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": [ "asc", "desc" @@ -1693,8 +1693,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": [ "asc", "desc" @@ -1707,9 +1707,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -1718,9 +1718,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } }, @@ -1729,8 +1729,8 @@ "required": false, "in": "query", "description": "Filter bookings by ids of users within your organization.", + "example": "?userIds=100,200", "schema": { - "example": "?userIds=100,200", "type": "string" } }, @@ -1949,11 +1949,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -1962,10 +1962,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -2377,8 +2377,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -2577,8 +2577,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -2587,8 +2587,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -2597,8 +2597,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -2607,8 +2607,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -2617,8 +2617,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": [ "range", "time" @@ -2631,8 +2631,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -2641,8 +2641,8 @@ "required": false, "in": "query", "description": "Whether to queue the form response.", + "example": true, "schema": { - "example": true, "type": "boolean" } } @@ -2775,11 +2775,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -2788,10 +2788,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -3220,8 +3220,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -3240,8 +3240,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -3250,8 +3250,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -3260,8 +3260,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the team. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -3270,8 +3270,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the team.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -3280,8 +3280,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -3290,8 +3290,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -3300,8 +3300,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -3314,8 +3314,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -3328,8 +3328,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": [ "asc", "desc" @@ -3342,10 +3342,10 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "minimum": 1, "maximum": 250, - "example": 10, "type": "number" } }, @@ -3354,9 +3354,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "minimum": 0, - "example": 0, "type": "number" } }, @@ -3439,8 +3439,8 @@ "required": false, "in": "query", "description": "Filter booking references by type", + "example": "google_calendar", "schema": { - "example": "google_calendar", "enum": [ "google_calendar", "office365_calendar", @@ -4296,11 +4296,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -4309,10 +4309,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -4673,11 +4673,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -4686,10 +4686,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -5344,8 +5344,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -5354,8 +5354,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -5364,8 +5364,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -5374,8 +5374,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -5384,8 +5384,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": [ "range", "time" @@ -5398,8 +5398,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -5408,8 +5408,8 @@ "required": false, "in": "query", "description": "Whether to queue the form response.", + "example": true, "schema": { - "example": true, "type": "boolean" } } @@ -5550,11 +5550,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -5563,10 +5563,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -5856,11 +5856,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -5869,10 +5869,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -6202,10 +6202,10 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "minimum": 1, "maximum": 1000, - "example": 10, "type": "number" } }, @@ -6214,9 +6214,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "minimum": 0, - "example": 0, "type": "number" } }, @@ -6237,8 +6237,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -6250,9 +6250,9 @@ "required": false, "in": "query", "description": "Query operator used to filter assigned options, AND by default.", + "example": "NONE", "schema": { "default": "AND", - "example": "NONE", "enum": [ "OR", "AND", @@ -6266,8 +6266,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -6543,8 +6543,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -6563,8 +6563,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -6573,8 +6573,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -6583,8 +6583,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -6593,8 +6593,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -6603,8 +6603,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -6613,8 +6613,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -6623,8 +6623,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -6633,8 +6633,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6643,8 +6643,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -6653,8 +6653,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6663,8 +6663,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -6673,8 +6673,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6683,8 +6683,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -6693,8 +6693,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -6707,8 +6707,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -6721,8 +6721,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": [ "asc", "desc" @@ -6735,8 +6735,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": [ "asc", "desc" @@ -6749,9 +6749,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -6760,9 +6760,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } } @@ -6822,11 +6822,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -6835,10 +6835,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -6847,8 +6847,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -6861,8 +6861,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -7103,11 +7103,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -7116,10 +7116,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -7128,8 +7128,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -7142,8 +7142,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -7156,8 +7156,8 @@ "required": false, "in": "query", "description": "Filter ooo entries by the user email address. user must be within your organization.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } } @@ -7545,11 +7545,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -7558,10 +7558,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -7876,7 +7876,7 @@ "post": { "operationId": "BookingsController_2024_08_13_createBooking", "summary": "Create a booking", - "description": "\n POST /v2/bookings is used to create regular bookings, recurring bookings and instant bookings. The request bodies for all 3 are almost the same except:\n If eventTypeId in the request body is id of a regular event, then regular booking is created.\n\n If it is an id of a recurring event type, then recurring booking is created.\n\n Meaning that the request bodies are equal but the outcome depends on what kind of event type it is with the goal of making it as seamless for developers as possible.\n\n For team event types it is possible to create instant meeting. To do that just pass `\"instant\": true` to the request body.\n\n The start needs to be in UTC aka if the timezone is GMT+2 in Rome and meeting should start at 11, then UTC time should have hours 09:00 aka without time zone.\n\n Finally, there are 2 ways to book an event type belonging to an individual user:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `username` and optionally `organizationSlug` if the user with the username is within an organization.\n\n And 2 ways to book and event type belonging to a team:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `teamSlug` and optionally `organizationSlug` if the team with the teamSlug is within an organization.\n ", + "description": "\n POST /v2/bookings is used to create regular bookings, recurring bookings and instant bookings. The request bodies for all 3 are almost the same except:\n If eventTypeId in the request body is id of a regular event, then regular booking is created.\n\n If it is an id of a recurring event type, then recurring booking is created.\n\n Meaning that the request bodies are equal but the outcome depends on what kind of event type it is with the goal of making it as seamless for developers as possible.\n\n For team event types it is possible to create instant meeting. To do that just pass `\"instant\": true` to the request body.\n\n The start needs to be in UTC aka if the timezone is GMT+2 in Rome and meeting should start at 11, then UTC time should have hours 09:00 aka without time zone.\n\n Finally, there are 2 ways to book an event type belonging to an individual user:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `username` and optionally `organizationSlug` if the user with the username is within an organization.\n\n And 2 ways to book and event type belonging to a team:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `teamSlug` and optionally `organizationSlug` if the team with the teamSlug is within an organization.\n\n If you are creating a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -7887,6 +7887,33 @@ "type": "string", "default": "2024-08-13" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { @@ -7945,8 +7972,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -7965,8 +7992,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -7975,8 +8002,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -7985,8 +8012,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -7995,8 +8022,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -8005,8 +8032,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -8015,8 +8042,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -8025,8 +8052,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -8035,8 +8062,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -8045,8 +8072,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -8055,8 +8082,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -8065,8 +8092,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -8075,8 +8102,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -8085,8 +8112,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -8095,8 +8122,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": [ "asc", "desc" @@ -8109,8 +8136,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": [ "asc", "desc" @@ -8123,8 +8150,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": [ "asc", "desc" @@ -8137,8 +8164,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": [ "asc", "desc" @@ -8151,9 +8178,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -8162,9 +8189,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } }, @@ -8199,7 +8226,7 @@ "get": { "operationId": "BookingsController_2024_08_13_getBooking", "summary": "Get a booking", - "description": "`:bookingUid` can be\n\n 1. uid of a normal booking\n\n 2. uid of one of the recurring booking recurrences\n\n 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences).", + "description": "`:bookingUid` can be\n\n 1. uid of a normal booking\n\n 2. uid of one of the recurring booking recurrences\n\n 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences).\n \n If you are fetching a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -8218,6 +8245,33 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { @@ -8344,11 +8398,38 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { "required": true, - "description": "Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2)", + "description": "Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2).\n\n If you are rescheduling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.", "content": { "application/json": { "schema": { @@ -8385,7 +8466,7 @@ "post": { "operationId": "BookingsController_2024_08_13_cancelBooking", "summary": "Cancel a booking", - "description": ":bookingUid can be :bookingUid of an usual booking, individual recurrence or recurring booking to cancel all recurrences.\n \n \nCancelling seated bookings:\n It is possible to cancel specific seat within a booking as an attendee or all of the seats as the host.\n \n1. As an attendee - provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and seatUid in the request body `{\"seatUid\": \"123-123-123\"}` . This will remove this particular attendance from the booking.\n \n2. As the host - host can cancel booking for all attendees aka for every seat. Provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and cancellationReason in the request body `{\"cancellationReason\": \"Will travel\"}` and `Authorization: Bearer token` request header where token is event type owner (host) credential. This will cancel the booking for all attendees.\n \n \nCancelling recurring seated bookings:\n For recurring seated bookings it is not possible to cancel all of them with 1 call\n like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid.", + "description": ":bookingUid can be :bookingUid of an usual booking, individual recurrence or recurring booking to cancel all recurrences.\n \n \nCancelling seated bookings:\n It is possible to cancel specific seat within a booking as an attendee or all of the seats as the host.\n \n1. As an attendee - provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and seatUid in the request body `{\"seatUid\": \"123-123-123\"}` . This will remove this particular attendance from the booking.\n \n2. As the host - host can cancel booking for all attendees aka for every seat. Provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and cancellationReason in the request body `{\"cancellationReason\": \"Will travel\"}` and `Authorization: Bearer token` request header where token is event type owner (host) credential. This will cancel the booking for all attendees.\n \n \nCancelling recurring seated bookings:\n For recurring seated bookings it is not possible to cancel all of them with 1 call\n like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid.\n \n If you are cancelling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -8404,6 +8485,33 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { @@ -8813,8 +8921,8 @@ "required": false, "in": "query", "description": "Filter booking references by type", + "example": "google_calendar", "schema": { - "example": "google_calendar", "enum": [ "google_calendar", "office365_calendar", @@ -9054,8 +9162,8 @@ "required": true, "in": "query", "description": "The timezone of the logged in user represented as a string", + "example": "America/New_York", "schema": { - "example": "America/New_York", "type": "string" } }, @@ -9064,8 +9172,8 @@ "required": false, "in": "query", "description": "The starting date for the busy times query", + "example": "2023-10-01", "schema": { - "example": "2023-10-01", "type": "string" } }, @@ -9074,8 +9182,8 @@ "required": false, "in": "query", "description": "The ending date for the busy times query", + "example": "2023-10-31", "schema": { - "example": "2023-10-31", "type": "string" } }, @@ -10141,11 +10249,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -10154,10 +10262,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -10614,11 +10722,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -10627,10 +10735,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -10638,9 +10746,9 @@ "name": "slug", "required": false, "in": "query", + "example": "organization-slug", "description": "The slug of the managed organization", "schema": { - "example": "organization-slug", "type": "string" } }, @@ -10648,9 +10756,9 @@ "name": "metadataKey", "required": false, "in": "query", + "example": "metadata-key", "description": "The key of the metadata - it is case sensitive so provide exactly as stored. If you provide it then you must also provide metadataValue", "schema": { - "example": "metadata-key", "type": "string" } }, @@ -10658,9 +10766,9 @@ "name": "metadataValue", "required": false, "in": "query", + "example": "metadata-value", "description": "The value of the metadata - it is case sensitive so provide exactly as stored. If you provide it then you must also provide metadataKey", "schema": { - "example": "metadata-value", "type": "string" } } @@ -11322,11 +11430,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -11335,10 +11443,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -11387,11 +11495,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -11400,10 +11508,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -11550,8 +11658,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -11560,8 +11668,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -11570,8 +11678,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -11580,8 +11688,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -11590,8 +11698,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": [ "range", "time" @@ -11604,8 +11712,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -12053,108 +12161,96 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", - "schema": { - "example": "abc123def456" - } + "example": "abc123def456", + "schema": {} }, { "name": "start", "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n\n Must be in UTC timezone as ISO 8601 datestring.\n\n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z.", - "schema": { - "example": "2050-09-05" - } + "example": "2050-09-05", + "schema": {} }, { "name": "end", "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n\n Must be in UTC timezone as ISO 8601 datestring.\n\n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z.", - "schema": { - "example": "2050-09-06" - } + "example": "2050-09-06", + "schema": {} }, { "name": "organizationSlug", "required": false, "in": "query", "description": "The slug of the organization to which user with username belongs or team with teamSlug belongs.", - "schema": { - "example": "org-slug" - } + "example": "org-slug", + "schema": {} }, { "name": "teamSlug", "required": false, "in": "query", "description": "The slug of the team who owns event type with eventTypeSlug - used when slots are checked for team event type.", - "schema": { - "example": "team-slug" - } + "example": "team-slug", + "schema": {} }, { "name": "username", "required": false, "in": "query", "description": "The username of the user who owns event type with eventTypeSlug - used when slots are checked for individual user event type.", - "schema": { - "example": "bob" - } + "example": "bob", + "schema": {} }, { "name": "eventTypeSlug", "required": false, "in": "query", "description": "The slug of the event type for which available slots should be checked. If slug is provided then username or teamSlug must be provided too and if relevant organizationSlug too.", - "schema": { - "example": "event-type-slug" - } + "example": "event-type-slug", + "schema": {} }, { "name": "eventTypeId", "required": false, "in": "query", "description": "The ID of the event type for which available slots should be checked.", - "schema": { - "example": "100" - } + "example": "100", + "schema": {} }, { "name": "usernames", "required": false, "in": "query", "description": "The usernames for which available slots should be checked separated by a comma.\n\n Checking slots by usernames is used mainly for dynamic events where there is no specific event but we just want to know when 2 or more people are available.\n\n Must contain at least 2 usernames.", - "schema": { - "example": "alice,bob" - } + "example": "alice,bob", + "schema": {} }, { "name": "format", "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times. Use 'time' or omit this query parameter to get only start time.", - "schema": { - "example": "range" - } + "example": "range", + "schema": {} }, { "name": "duration", "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", - "schema": { - "example": "60" - } + "example": "60", + "schema": {} }, { "name": "timeZone", "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", - "schema": { - "example": "Europe/Rome" - } + "example": "Europe/Rome", + "schema": {} } ], "responses": { @@ -13124,11 +13220,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13137,10 +13233,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -13339,11 +13435,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13352,10 +13448,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -13583,11 +13679,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13596,10 +13692,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13648,11 +13744,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13661,10 +13757,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13973,11 +14069,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13986,10 +14082,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -14030,11 +14126,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -14043,10 +14139,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -14217,11 +14313,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -14230,10 +14326,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -16412,6 +16508,18 @@ "enableAutomaticRecordingForOrganizer": { "type": "boolean", "description": "If true, enables the automatic recording for the event when organizer joins the call" + }, + "enableAutomaticTranscription": { + "type": "boolean", + "description": "If true, enables the automatic transcription for the event whenever someone joins the call" + }, + "disableTranscriptionForGuests": { + "type": "boolean", + "description": "If true, the guests will not be able to receive transcription of the meeting" + }, + "disableTranscriptionForOrganizer": { + "type": "boolean", + "description": "If true, the organizer will not be able to receive transcription of the meeting" } } }, diff --git a/docs/api-reference/v2/openapi.json b/docs/api-reference/v2/openapi.json index f460ac586a..06c9cfdc91 100644 --- a/docs/api-reference/v2/openapi.json +++ b/docs/api-reference/v2/openapi.json @@ -28,8 +28,8 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { - "example": 10, "type": "number" } }, @@ -38,8 +38,8 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { - "example": 0, "type": "number" } }, @@ -48,8 +48,8 @@ "required": false, "in": "query", "description": "Filter managed users by email. If you want to filter by multiple emails, separate them with a comma.", + "example": "?emails=email1@example.com,email2@example.com", "schema": { - "example": "?emails=email1@example.com,email2@example.com", "type": "array", "items": { "type": "string" @@ -431,11 +431,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -444,10 +444,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -634,11 +634,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -647,10 +647,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -1129,8 +1129,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -1142,8 +1142,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -1219,8 +1219,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -1232,8 +1232,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -1447,8 +1447,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -1461,8 +1461,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -1471,8 +1471,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -1481,8 +1481,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -1491,8 +1491,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -1501,8 +1501,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -1511,8 +1511,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -1521,8 +1521,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -1531,8 +1531,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1541,8 +1541,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -1551,8 +1551,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1561,8 +1561,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -1571,8 +1571,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -1581,8 +1581,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -1591,8 +1591,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -1602,8 +1602,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -1613,8 +1613,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -1624,8 +1624,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -1635,9 +1635,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -1646,9 +1646,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } }, @@ -1657,8 +1657,8 @@ "required": false, "in": "query", "description": "Filter bookings by ids of users within your organization.", + "example": "?userIds=100,200", "schema": { - "example": "?userIds=100,200", "type": "string" } }, @@ -1871,11 +1871,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -1884,10 +1884,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -2283,8 +2283,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -2473,8 +2473,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -2483,8 +2483,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -2493,8 +2493,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -2503,8 +2503,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -2513,8 +2513,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": ["range", "time"], "type": "string" } @@ -2524,8 +2524,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -2534,8 +2534,8 @@ "required": false, "in": "query", "description": "Whether to queue the form response.", + "example": true, "schema": { - "example": true, "type": "boolean" } } @@ -2664,11 +2664,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -2677,10 +2677,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -3095,8 +3095,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -3109,8 +3109,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -3119,8 +3119,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -3129,8 +3129,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the team. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -3139,8 +3139,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the team.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -3149,8 +3149,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -3159,8 +3159,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -3169,8 +3169,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -3180,8 +3180,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -3191,8 +3191,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -3202,10 +3202,10 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "minimum": 1, "maximum": 250, - "example": 10, "type": "number" } }, @@ -3214,9 +3214,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "minimum": 0, - "example": 0, "type": "number" } }, @@ -3297,8 +3297,8 @@ "required": false, "in": "query", "description": "Filter booking references by type", + "example": "google_calendar", "schema": { - "example": "google_calendar", "enum": [ "google_calendar", "office365_calendar", @@ -4107,11 +4107,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -4120,10 +4120,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -4474,11 +4474,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -4487,10 +4487,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -5119,8 +5119,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -5129,8 +5129,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -5139,8 +5139,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -5149,8 +5149,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -5159,8 +5159,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": ["range", "time"], "type": "string" } @@ -5170,8 +5170,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -5180,8 +5180,8 @@ "required": false, "in": "query", "description": "Whether to queue the form response.", + "example": true, "schema": { - "example": true, "type": "boolean" } } @@ -5318,11 +5318,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -5331,10 +5331,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -5614,11 +5614,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -5627,10 +5627,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -5950,10 +5950,10 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "minimum": 1, "maximum": 1000, - "example": 10, "type": "number" } }, @@ -5962,9 +5962,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "minimum": 0, - "example": 0, "type": "number" } }, @@ -5985,8 +5985,8 @@ "required": false, "in": "query", "description": "Filter by assigned attribute option ids. ids must be separated by a comma.", + "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "schema": { - "example": "?assignedOptionIds=aaaaaaaa-bbbb-cccc-dddd-eeeeee1eee,aaaaaaaa-bbbb-cccc-dddd-eeeeee2eee", "type": "array", "items": { "type": "string" @@ -5998,9 +5998,9 @@ "required": false, "in": "query", "description": "Query operator used to filter assigned options, AND by default.", + "example": "NONE", "schema": { "default": "AND", - "example": "NONE", "enum": ["OR", "AND", "NONE"], "type": "string" } @@ -6010,8 +6010,8 @@ "required": false, "in": "query", "description": "Filter by teamIds. Team ids must be separated by a comma.", + "example": "?teamIds=100,200", "schema": { - "example": "?teamIds=100,200", "type": "array", "items": { "type": "number" @@ -6279,8 +6279,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -6293,8 +6293,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -6303,8 +6303,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -6313,8 +6313,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -6323,8 +6323,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -6333,8 +6333,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -6343,8 +6343,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -6353,8 +6353,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -6363,8 +6363,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6373,8 +6373,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -6383,8 +6383,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6393,8 +6393,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -6403,8 +6403,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -6413,8 +6413,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -6423,8 +6423,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6434,8 +6434,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6445,8 +6445,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6456,8 +6456,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6467,9 +6467,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -6478,9 +6478,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } } @@ -6538,11 +6538,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -6551,10 +6551,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -6563,8 +6563,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6574,8 +6574,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6805,11 +6805,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -6818,10 +6818,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -6830,8 +6830,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6841,8 +6841,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -6852,8 +6852,8 @@ "required": false, "in": "query", "description": "Filter ooo entries by the user email address. user must be within your organization.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } } @@ -7229,11 +7229,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -7242,10 +7242,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -7548,7 +7548,7 @@ "post": { "operationId": "BookingsController_2024_08_13_createBooking", "summary": "Create a booking", - "description": "\n POST /v2/bookings is used to create regular bookings, recurring bookings and instant bookings. The request bodies for all 3 are almost the same except:\n If eventTypeId in the request body is id of a regular event, then regular booking is created.\n\n If it is an id of a recurring event type, then recurring booking is created.\n\n Meaning that the request bodies are equal but the outcome depends on what kind of event type it is with the goal of making it as seamless for developers as possible.\n\n For team event types it is possible to create instant meeting. To do that just pass `\"instant\": true` to the request body.\n\n The start needs to be in UTC aka if the timezone is GMT+2 in Rome and meeting should start at 11, then UTC time should have hours 09:00 aka without time zone.\n\n Finally, there are 2 ways to book an event type belonging to an individual user:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `username` and optionally `organizationSlug` if the user with the username is within an organization.\n\n And 2 ways to book and event type belonging to a team:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `teamSlug` and optionally `organizationSlug` if the team with the teamSlug is within an organization.\n ", + "description": "\n POST /v2/bookings is used to create regular bookings, recurring bookings and instant bookings. The request bodies for all 3 are almost the same except:\n If eventTypeId in the request body is id of a regular event, then regular booking is created.\n\n If it is an id of a recurring event type, then recurring booking is created.\n\n Meaning that the request bodies are equal but the outcome depends on what kind of event type it is with the goal of making it as seamless for developers as possible.\n\n For team event types it is possible to create instant meeting. To do that just pass `\"instant\": true` to the request body.\n\n The start needs to be in UTC aka if the timezone is GMT+2 in Rome and meeting should start at 11, then UTC time should have hours 09:00 aka without time zone.\n\n Finally, there are 2 ways to book an event type belonging to an individual user:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `username` and optionally `organizationSlug` if the user with the username is within an organization.\n\n And 2 ways to book and event type belonging to a team:\n 1. Provide `eventTypeId` in the request body.\n 2. Provide `eventTypeSlug` and `teamSlug` and optionally `organizationSlug` if the team with the teamSlug is within an organization.\n\n If you are creating a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -7559,6 +7559,33 @@ "type": "string", "default": "2024-08-13" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { @@ -7615,8 +7642,8 @@ "required": false, "in": "query", "description": "Filter bookings by status. If you want to filter by multiple statuses, separate them with a comma.", + "example": "?status=upcoming,past", "schema": { - "example": "?status=upcoming,past", "type": "array", "items": { "type": "string", @@ -7629,8 +7656,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's email address.", + "example": "example@domain.com", "schema": { - "example": "example@domain.com", "type": "string" } }, @@ -7639,8 +7666,8 @@ "required": false, "in": "query", "description": "Filter bookings by the attendee's name.", + "example": "John Doe", "schema": { - "example": "John Doe", "type": "string" } }, @@ -7649,8 +7676,8 @@ "required": false, "in": "query", "description": "Filter bookings by the booking Uid.", + "example": "2NtaeaVcKfpmSZ4CthFdfk", "schema": { - "example": "2NtaeaVcKfpmSZ4CthFdfk", "type": "string" } }, @@ -7659,8 +7686,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type ids belonging to the user. Event type ids must be separated by a comma.", + "example": "?eventTypeIds=100,200", "schema": { - "example": "?eventTypeIds=100,200", "type": "string" } }, @@ -7669,8 +7696,8 @@ "required": false, "in": "query", "description": "Filter bookings by event type id belonging to the user.", + "example": "?eventTypeId=100", "schema": { - "example": "?eventTypeId=100", "type": "string" } }, @@ -7679,8 +7706,8 @@ "required": false, "in": "query", "description": "Filter bookings by team ids that user is part of. Team ids must be separated by a comma.", + "example": "?teamIds=50,60", "schema": { - "example": "?teamIds=50,60", "type": "string" } }, @@ -7689,8 +7716,8 @@ "required": false, "in": "query", "description": "Filter bookings by team id that user is part of", + "example": "?teamId=50", "schema": { - "example": "?teamId=50", "type": "string" } }, @@ -7699,8 +7726,8 @@ "required": false, "in": "query", "description": "Filter bookings with start after this date string.", + "example": "?afterStart=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterStart=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -7709,8 +7736,8 @@ "required": false, "in": "query", "description": "Filter bookings with end before this date string.", + "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "schema": { - "example": "?beforeEnd=2025-03-07T11:00:00.000Z", "type": "string" } }, @@ -7719,8 +7746,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created after this date string.", + "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterCreatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -7729,8 +7756,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been created before this date string.", + "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeCreatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -7739,8 +7766,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated after this date string.", + "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "schema": { - "example": "?afterUpdatedAt=2025-03-07T10:00:00.000Z", "type": "string" } }, @@ -7749,8 +7776,8 @@ "required": false, "in": "query", "description": "Filter bookings that have been updated before this date string.", + "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "schema": { - "example": "?beforeUpdatedAt=2025-03-14T11:00:00.000Z", "type": "string" } }, @@ -7759,8 +7786,8 @@ "required": false, "in": "query", "description": "Sort results by their start time in ascending or descending order.", + "example": "?sortStart=asc OR ?sortStart=desc", "schema": { - "example": "?sortStart=asc OR ?sortStart=desc", "enum": ["asc", "desc"], "type": "string" } @@ -7770,8 +7797,8 @@ "required": false, "in": "query", "description": "Sort results by their end time in ascending or descending order.", + "example": "?sortEnd=asc OR ?sortEnd=desc", "schema": { - "example": "?sortEnd=asc OR ?sortEnd=desc", "enum": ["asc", "desc"], "type": "string" } @@ -7781,8 +7808,8 @@ "required": false, "in": "query", "description": "Sort results by their creation time (when booking was made) in ascending or descending order.", + "example": "?sortCreated=asc OR ?sortCreated=desc", "schema": { - "example": "?sortCreated=asc OR ?sortCreated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -7792,8 +7819,8 @@ "required": false, "in": "query", "description": "Sort results by their updated time (for example when booking status changes) in ascending or descending order.", + "example": "?sortUpdated=asc OR ?sortUpdated=desc", "schema": { - "example": "?sortUpdated=asc OR ?sortUpdated=desc", "enum": ["asc", "desc"], "type": "string" } @@ -7803,9 +7830,9 @@ "required": false, "in": "query", "description": "The number of items to return", + "example": 10, "schema": { "default": 100, - "example": 10, "type": "number" } }, @@ -7814,9 +7841,9 @@ "required": false, "in": "query", "description": "The number of items to skip", + "example": 0, "schema": { "default": 0, - "example": 0, "type": "number" } }, @@ -7849,7 +7876,7 @@ "get": { "operationId": "BookingsController_2024_08_13_getBooking", "summary": "Get a booking", - "description": "`:bookingUid` can be\n\n 1. uid of a normal booking\n\n 2. uid of one of the recurring booking recurrences\n\n 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences).", + "description": "`:bookingUid` can be\n\n 1. uid of a normal booking\n\n 2. uid of one of the recurring booking recurrences\n\n 3. uid of recurring booking which will return an array of all recurring booking recurrences (stored as recurringBookingUid on one of the individual recurrences).\n \n If you are fetching a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -7868,6 +7895,33 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { @@ -7988,11 +8042,38 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { "required": true, - "description": "Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2)", + "description": "Accepts different types of reschedule booking input: Reschedule Booking (Option 1) or Reschedule Seated Booking (Option 2).\n\n If you are rescheduling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.", "content": { "application/json": { "schema": { @@ -8027,7 +8108,7 @@ "post": { "operationId": "BookingsController_2024_08_13_cancelBooking", "summary": "Cancel a booking", - "description": ":bookingUid can be :bookingUid of an usual booking, individual recurrence or recurring booking to cancel all recurrences.\n \n \nCancelling seated bookings:\n It is possible to cancel specific seat within a booking as an attendee or all of the seats as the host.\n \n1. As an attendee - provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and seatUid in the request body `{\"seatUid\": \"123-123-123\"}` . This will remove this particular attendance from the booking.\n \n2. As the host - host can cancel booking for all attendees aka for every seat. Provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and cancellationReason in the request body `{\"cancellationReason\": \"Will travel\"}` and `Authorization: Bearer token` request header where token is event type owner (host) credential. This will cancel the booking for all attendees.\n \n \nCancelling recurring seated bookings:\n For recurring seated bookings it is not possible to cancel all of them with 1 call\n like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid.", + "description": ":bookingUid can be :bookingUid of an usual booking, individual recurrence or recurring booking to cancel all recurrences.\n \n \nCancelling seated bookings:\n It is possible to cancel specific seat within a booking as an attendee or all of the seats as the host.\n \n1. As an attendee - provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and seatUid in the request body `{\"seatUid\": \"123-123-123\"}` . This will remove this particular attendance from the booking.\n \n2. As the host - host can cancel booking for all attendees aka for every seat. Provide :bookingUid in the request URL `/bookings/:bookingUid/cancel` and cancellationReason in the request body `{\"cancellationReason\": \"Will travel\"}` and `Authorization: Bearer token` request header where token is event type owner (host) credential. This will cancel the booking for all attendees.\n \n \nCancelling recurring seated bookings:\n For recurring seated bookings it is not possible to cancel all of them with 1 call\n like with non-seated recurring bookings by providing recurring bookind uid - you have to cancel each recurrence booking by its bookingUid + seatUid.\n \n If you are cancelling a seated booking for an event type with 'show attendees' disabled, then to retrieve attendees in the response either set 'show attendees' to true on event type level or\n you have to provide an authentication method of event type owner, host, team admin or owner or org admin or owner.\n ", "parameters": [ { "name": "cal-api-version", @@ -8046,6 +8127,33 @@ "schema": { "type": "string" } + }, + { + "name": "Authorization", + "in": "header", + "description": "value must be `Bearer ` where `` is api key prefixed with cal_ or managed user access token", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-secret-key", + "in": "header", + "description": "For platform customers - OAuth client secret key", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "x-cal-client-id", + "in": "header", + "description": "For platform customers - OAuth client ID", + "required": false, + "schema": { + "type": "string" + } } ], "requestBody": { @@ -8441,8 +8549,8 @@ "required": false, "in": "query", "description": "Filter booking references by type", + "example": "google_calendar", "schema": { - "example": "google_calendar", "enum": [ "google_calendar", "office365_calendar", @@ -8668,8 +8776,8 @@ "required": true, "in": "query", "description": "The timezone of the logged in user represented as a string", + "example": "America/New_York", "schema": { - "example": "America/New_York", "type": "string" } }, @@ -8678,8 +8786,8 @@ "required": false, "in": "query", "description": "The starting date for the busy times query", + "example": "2023-10-01", "schema": { - "example": "2023-10-01", "type": "string" } }, @@ -8688,8 +8796,8 @@ "required": false, "in": "query", "description": "The ending date for the busy times query", + "example": "2023-10-31", "schema": { - "example": "2023-10-31", "type": "string" } }, @@ -9680,11 +9788,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -9693,10 +9801,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -10133,11 +10241,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -10146,10 +10254,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -10157,9 +10265,9 @@ "name": "slug", "required": false, "in": "query", + "example": "organization-slug", "description": "The slug of the managed organization", "schema": { - "example": "organization-slug", "type": "string" } }, @@ -10167,9 +10275,9 @@ "name": "metadataKey", "required": false, "in": "query", + "example": "metadata-key", "description": "The key of the metadata - it is case sensitive so provide exactly as stored. If you provide it then you must also provide metadataValue", "schema": { - "example": "metadata-key", "type": "string" } }, @@ -10177,9 +10285,9 @@ "name": "metadataValue", "required": false, "in": "query", + "example": "metadata-value", "description": "The value of the metadata - it is case sensitive so provide exactly as stored. If you provide it then you must also provide metadataKey", "schema": { - "example": "metadata-value", "type": "string" } } @@ -10811,11 +10919,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -10824,10 +10932,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -10874,11 +10982,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -10887,10 +10995,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -11031,8 +11139,8 @@ "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z\n ", + "example": "2050-09-05", "schema": { - "example": "2050-09-05", "type": "string" } }, @@ -11041,8 +11149,8 @@ "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n \n Must be in UTC timezone as ISO 8601 datestring.\n \n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z", + "example": "2050-09-06", "schema": { - "example": "2050-09-06", "type": "string" } }, @@ -11051,8 +11159,8 @@ "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", + "example": "Europe/Rome", "schema": { - "example": "Europe/Rome", "type": "string" } }, @@ -11061,8 +11169,8 @@ "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", + "example": "60", "schema": { - "example": "60", "type": "number" } }, @@ -11071,8 +11179,8 @@ "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times.", + "example": "range", "schema": { - "example": "range", "enum": ["range", "time"], "type": "string" } @@ -11082,8 +11190,8 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", + "example": "abc123def456", "schema": { - "example": "abc123def456", "type": "string" } }, @@ -11513,108 +11621,96 @@ "required": false, "in": "query", "description": "The unique identifier of the booking being rescheduled. When provided will ensure that the original booking time appears within the returned available slots when rescheduling.", - "schema": { - "example": "abc123def456" - } + "example": "abc123def456", + "schema": {} }, { "name": "start", "required": true, "in": "query", "description": "\n Time starting from which available slots should be checked.\n\n Must be in UTC timezone as ISO 8601 datestring.\n\n You can pass date without hours which defaults to start of day or specify hours:\n 2024-08-13 (will have hours 00:00:00 aka at very beginning of the date) or you can specify hours manually like 2024-08-13T09:00:00Z.", - "schema": { - "example": "2050-09-05" - } + "example": "2050-09-05", + "schema": {} }, { "name": "end", "required": true, "in": "query", "description": "\n Time until which available slots should be checked.\n\n Must be in UTC timezone as ISO 8601 datestring.\n\n You can pass date without hours which defaults to end of day or specify hours:\n 2024-08-20 (will have hours 23:59:59 aka at the very end of the date) or you can specify hours manually like 2024-08-20T18:00:00Z.", - "schema": { - "example": "2050-09-06" - } + "example": "2050-09-06", + "schema": {} }, { "name": "organizationSlug", "required": false, "in": "query", "description": "The slug of the organization to which user with username belongs or team with teamSlug belongs.", - "schema": { - "example": "org-slug" - } + "example": "org-slug", + "schema": {} }, { "name": "teamSlug", "required": false, "in": "query", "description": "The slug of the team who owns event type with eventTypeSlug - used when slots are checked for team event type.", - "schema": { - "example": "team-slug" - } + "example": "team-slug", + "schema": {} }, { "name": "username", "required": false, "in": "query", "description": "The username of the user who owns event type with eventTypeSlug - used when slots are checked for individual user event type.", - "schema": { - "example": "bob" - } + "example": "bob", + "schema": {} }, { "name": "eventTypeSlug", "required": false, "in": "query", "description": "The slug of the event type for which available slots should be checked. If slug is provided then username or teamSlug must be provided too and if relevant organizationSlug too.", - "schema": { - "example": "event-type-slug" - } + "example": "event-type-slug", + "schema": {} }, { "name": "eventTypeId", "required": false, "in": "query", "description": "The ID of the event type for which available slots should be checked.", - "schema": { - "example": "100" - } + "example": "100", + "schema": {} }, { "name": "usernames", "required": false, "in": "query", "description": "The usernames for which available slots should be checked separated by a comma.\n\n Checking slots by usernames is used mainly for dynamic events where there is no specific event but we just want to know when 2 or more people are available.\n\n Must contain at least 2 usernames.", - "schema": { - "example": "alice,bob" - } + "example": "alice,bob", + "schema": {} }, { "name": "format", "required": false, "in": "query", "description": "Format of slot times in response. Use 'range' to get start and end times. Use 'time' or omit this query parameter to get only start time.", - "schema": { - "example": "range" - } + "example": "range", + "schema": {} }, { "name": "duration", "required": false, "in": "query", "description": "If event type has multiple possible durations then you can specify the desired duration here. Also, if you are fetching slots for a dynamic event then you can specify the duration her which defaults to 30, meaning that returned slots will be each 30 minutes long.", - "schema": { - "example": "60" - } + "example": "60", + "schema": {} }, { "name": "timeZone", "required": false, "in": "query", "description": "Time zone in which the available slots should be returned. Defaults to UTC.", - "schema": { - "example": "Europe/Rome" - } + "example": "Europe/Rome", + "schema": {} } ], "responses": { @@ -12544,11 +12640,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -12557,10 +12653,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -12751,11 +12847,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -12764,10 +12860,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -12985,11 +13081,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -12998,10 +13094,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13048,11 +13144,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13061,10 +13157,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13359,11 +13455,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13372,10 +13468,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13414,11 +13510,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13427,10 +13523,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } }, @@ -13593,11 +13689,11 @@ "required": false, "in": "query", "description": "Maximum number of items to return", + "example": 25, "schema": { "minimum": 1, "maximum": 250, "default": 250, - "example": 25, "type": "number" } }, @@ -13606,10 +13702,10 @@ "required": false, "in": "query", "description": "Number of items to skip", + "example": 0, "schema": { "minimum": 0, "default": 0, - "example": 0, "type": "number" } } @@ -15474,6 +15570,18 @@ "enableAutomaticRecordingForOrganizer": { "type": "boolean", "description": "If true, enables the automatic recording for the event when organizer joins the call" + }, + "enableAutomaticTranscription": { + "type": "boolean", + "description": "If true, enables the automatic transcription for the event whenever someone joins the call" + }, + "disableTranscriptionForGuests": { + "type": "boolean", + "description": "If true, the guests will not be able to receive transcription of the meeting" + }, + "disableTranscriptionForOrganizer": { + "type": "boolean", + "description": "If true, the organizer will not be able to receive transcription of the meeting" } } },