diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/booking-guests.controller.ts b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/booking-guests.controller.ts
index 3bb01bc87d..015851bbe7 100644
--- a/apps/api/v2/src/ee/bookings/2024-08-13/controllers/booking-guests.controller.ts
+++ b/apps/api/v2/src/ee/bookings/2024-08-13/controllers/booking-guests.controller.ts
@@ -3,6 +3,7 @@ import { AddGuestsOutput_2024_08_13 } from "@/ee/bookings/2024-08-13/outputs/add
import { BookingGuestsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/booking-guests.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 { Throttle } from "@/lib/endpoint-throttler-decorator";
import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator";
import { Permissions } from "@/modules/auth/decorators/permissions/permissions.decorator";
import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard";
@@ -35,10 +36,19 @@ export class BookingGuestsController_2024_08_13 {
@HttpCode(HttpStatus.OK)
@Permissions([BOOKING_WRITE])
@UseGuards(ApiAuthGuard, BookingUidGuard)
+ @Throttle({
+ limit: 5,
+ ttl: 60000,
+ blockDuration: 60000,
+ name: "booking_guests_add",
+ })
@ApiHeader(API_KEY_OR_ACCESS_TOKEN_HEADER)
@ApiOperation({
summary: "Add guests to an existing booking",
- description: `Add one or more guests to an existing booking.
+ description: `Add one or more guests to an existing booking. Maximum 10 guests per request, with a limit of 30 total guests per booking.
+
+ **Rate Limiting:**
+ This endpoint is rate limited to 5 requests per minute to prevent abuse.
**Email Notifications:**
When guests are added, the following notifications are sent (unless disabled by event type settings):
diff --git a/apps/api/v2/src/ee/bookings/2024-08-13/services/booking-guests.service.ts b/apps/api/v2/src/ee/bookings/2024-08-13/services/booking-guests.service.ts
index 7fca9186c7..c434cfae1b 100644
--- a/apps/api/v2/src/ee/bookings/2024-08-13/services/booking-guests.service.ts
+++ b/apps/api/v2/src/ee/bookings/2024-08-13/services/booking-guests.service.ts
@@ -2,11 +2,13 @@ import { BookingsRepository_2024_08_13 } from "@/ee/bookings/2024-08-13/reposito
import { BookingsService_2024_08_13 } from "@/ee/bookings/2024-08-13/services/bookings.service";
import { PlatformBookingsService } from "@/ee/bookings/shared/platform-bookings.service";
import { ApiAuthGuardUser } from "@/modules/auth/strategies/api-auth/api-auth.strategy";
-import { Injectable, Logger, HttpException, NotFoundException } from "@nestjs/common";
+import { Injectable, Logger, HttpException, NotFoundException, BadRequestException } from "@nestjs/common";
import { addGuestsHandler } from "@calcom/platform-libraries/bookings";
import type { AddGuestsInput_2024_08_13 } from "@calcom/platform-types";
+const MAX_TOTAL_GUESTS_PER_BOOKING = 30;
+
@Injectable()
export class BookingGuestsService_2024_08_13 {
private readonly logger = new Logger("BookingGuestsService_2024_08_13");
@@ -23,6 +25,18 @@ export class BookingGuestsService_2024_08_13 {
throw new NotFoundException(`Booking with uid ${bookingUid} not found`);
}
+ const currentGuestCount = booking.attendees.length;
+ const newGuestCount = input.guests.length;
+ const totalGuestCount = currentGuestCount + newGuestCount;
+
+ if (totalGuestCount > MAX_TOTAL_GUESTS_PER_BOOKING) {
+ const remainingSlots = Math.max(0, MAX_TOTAL_GUESTS_PER_BOOKING - currentGuestCount);
+ throw new BadRequestException(
+ `Cannot add ${newGuestCount} guests. This booking already has ${currentGuestCount} attendees. ` +
+ `Maximum total guests allowed is ${MAX_TOTAL_GUESTS_PER_BOOKING}. You can add up to ${remainingSlots} more guests.`
+ );
+ }
+
const platformClientParams = booking.eventTypeId
? await this.platformBookingsService.getOAuthClientParams(booking.eventTypeId)
: undefined;
diff --git a/docs/api-reference/v2/openapi.json b/docs/api-reference/v2/openapi.json
index 76ce00679b..f731e3cddd 100644
--- a/docs/api-reference/v2/openapi.json
+++ b/docs/api-reference/v2/openapi.json
@@ -10170,7 +10170,7 @@
"post": {
"operationId": "BookingGuestsController_2024_08_13_addGuests",
"summary": "Add guests to an existing booking",
- "description": "Add one or more guests to an existing booking.\n \n **Email Notifications:**\n When guests are added, the following notifications are sent (unless disabled by event type settings):\n \n - **Organizer & Team Members:** Receive an \"Add Guests\" notification email informing them that new guests have been added to the booking.\n \n - **New Guests:** Receive a \"Scheduled Event\" email with full booking details and calendar invite. If they have a phone number, they also receive an SMS notification.\n \n - **Existing Guests:** Receive an \"Add Guests\" notification email informing them that additional guests have been added to the booking.\n \n The cal-api-version header is required for this endpoint. Without it, the request will fail with a 404 error.\n ",
+ "description": "Add one or more guests to an existing booking. Maximum 10 guests per request, with a limit of 30 total guests per booking.\n \n **Rate Limiting:**\n This endpoint is rate limited to 5 requests per minute to prevent abuse.\n \n **Email Notifications:**\n When guests are added, the following notifications are sent (unless disabled by event type settings):\n \n - **Organizer & Team Members:** Receive an \"Add Guests\" notification email informing them that new guests have been added to the booking.\n \n - **New Guests:** Receive a \"Scheduled Event\" email with full booking details and calendar invite. If they have a phone number, they also receive an SMS notification.\n \n - **Existing Guests:** Receive an \"Add Guests\" notification email informing them that additional guests have been added to the booking.\n \n The cal-api-version header is required for this endpoint. Without it, the request will fail with a 404 error.\n ",
"parameters": [
{
"name": "cal-api-version",
@@ -31182,7 +31182,7 @@
"type": "object",
"properties": {
"guests": {
- "description": "Array of guests to add to the booking",
+ "description": "Array of guests to add to the booking. Maximum 10 guests per request.",
"example": [
{
"email": "john.doe@example.com",
@@ -31195,6 +31195,8 @@
}
],
"type": "array",
+ "minItems": 1,
+ "maxItems": 10,
"items": {
"$ref": "#/components/schemas/Guest"
}
diff --git a/packages/platform/types/bookings/2024-08-13/inputs/add-guests.input.ts b/packages/platform/types/bookings/2024-08-13/inputs/add-guests.input.ts
index 34f4e324cd..241240660f 100644
--- a/packages/platform/types/bookings/2024-08-13/inputs/add-guests.input.ts
+++ b/packages/platform/types/bookings/2024-08-13/inputs/add-guests.input.ts
@@ -4,6 +4,7 @@ import {
IsArray,
IsEmail,
ArrayMinSize,
+ ArrayMaxSize,
IsString,
IsOptional,
IsTimeZone,
@@ -67,12 +68,13 @@ class Guest {
export class AddGuestsInput_2024_08_13 {
@ArrayMinSize(1)
+ @ArrayMaxSize(10, { message: "Cannot add more than 10 guests at a time" })
@IsArray()
@ValidateNested({ each: true })
@Type(() => Guest)
@ApiProperty({
type: [Guest],
- description: "Array of guests to add to the booking",
+ description: "Array of guests to add to the booking. Maximum 10 guests per request.",
example: [
{
email: "john.doe@example.com",