openapi: 3.0.3 info: version: v1.0.3 title: LE-KO Bookings API license: name: private url: https://le-ko.deggex.com contact: email: denis@deggex.awsapps.com description: LE-KO Bookings API servers: - url: https://booking-{env}.le-ko.deggex.com/{basePath} description: Bookings APIs. variables: basePath: default: v1 env: default: dev security: - bearerHttpAuthentication: [] tags: - name: Bookings description: Bookings APIs paths: /bookings/notify: post: summary: Send booking notifications operationId: notifyBookings description: | ✨ Sends booking notifications according to the defined notification rules. This endpoint is intended to be called periodically (cron-like) to trigger the sending of notifications as part of the booking flow. tags: - Bookings parameters: - $ref: '#/components/parameters/TraceparentHeader' responses: '204': description: Notifications sent successfully '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' '500': description: Internal server error /bookings/{bookingId}/completed: patch: summary: Mark a booking as completed operationId: markBookingAsCompleted description: ✨ Mark a specific booking as completed. The booking must have already happened. tags: - Bookings parameters: - name: bookingId in: path required: true description: The booking ID schema: $ref: '#/components/schemas/Id' - $ref: '#/components/parameters/TraceparentHeader' requestBody: required: true content: application/json: schema: type: object properties: completed: type: boolean required: - completed responses: '200': description: Booking marked as completed content: application/json: schema: $ref: '#/components/schemas/Booking' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' '404': description: Booking not found content: application/json: schema: $ref: '#/components/schemas/Error' /bookings/{bookingId}/note: patch: summary: Add a note to a booking operationId: addBookingNote description: ✨ Add a note to a specific booking that has already happened. tags: - Bookings parameters: - name: bookingId in: path required: true description: The booking ID schema: $ref: '#/components/schemas/Id' - $ref: '#/components/parameters/TraceparentHeader' requestBody: required: true content: application/json: schema: type: object properties: note: type: string required: - note responses: '200': description: Note added to booking content: application/json: schema: $ref: '#/components/schemas/Booking' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' '404': description: Booking not found content: application/json: schema: $ref: '#/components/schemas/Error' /bookings/{bookingId}/dismiss: post: summary: Dismiss a canceled booking operationId: dismissBooking description: | ✨ Dismiss a canceled booking from the user's calendar view. Only the booking owner can dismiss their own bookings, and only canceled bookings can be dismissed. This action is permanent and helps keep the calendar UI clean. tags: - Bookings parameters: - name: bookingId in: path required: true description: The booking ID to dismiss schema: $ref: '#/components/schemas/Id' - name: userId in: query required: true description: The user ID (must match the booking owner) schema: $ref: '#/components/schemas/Id' - $ref: '#/components/parameters/TraceparentHeader' responses: '204': description: Booking dismissed successfully '400': description: Bad Request - booking is not canceled content: application/json: schema: $ref: '#/components/schemas/Errors' '403': description: Forbidden - user does not own this booking content: application/json: schema: $ref: '#/components/schemas/Errors' '404': description: Booking not found content: application/json: schema: $ref: '#/components/schemas/Error' /bookings/orders: get: summary: Get all booking orders for a user operationId: getUserBookingOrders description: ✨ Get all booking orders of a specific user. tags: - Bookings parameters: - name: userId in: query required: true description: The user ID schema: $ref: '#/components/schemas/UserId' - name: startAt in: query required: false description: The start date time to filter schema: type: string format: date-time - name: endAt in: query required: false description: The end date time to filter schema: type: string format: date-time - $ref: '#/components/parameters/TraceparentHeader' responses: '200': description: List of booking orders content: application/json: schema: type: array items: $ref: '#/components/schemas/BookingOrder' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' /bookings/{bookingId}: get: summary: Get a specific booking operationId: getBookingById description: ✨ Get details of a specific booking by its ID. tags: - Bookings parameters: - name: bookingId in: path required: true description: The booking ID schema: $ref: '#/components/schemas/Id' - $ref: '#/components/parameters/TraceparentHeader' responses: '200': description: Booking details content: application/json: schema: $ref: '#/components/schemas/Booking' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' '404': description: Booking not found content: application/json: schema: $ref: '#/components/schemas/Error' /bookings: get: summary: Get all bookings for a user or event operationId: getBookings description: ✨ Get all bookings of a specific user or event. The user must provide either `eventId` or `userId`. If `userId` is provided, `startAt` and `endAt` can be used to filter the results. tags: - Bookings parameters: - name: userId in: query required: false description: The user ID. Either `userId` or `eventId` must be provided. schema: $ref: '#/components/schemas/UserId' - name: eventId in: query required: false description: The event ID. Either `userId` or `eventId` must be provided. schema: $ref: '#/components/schemas/Id' - name: startAt in: query required: false description: The start date time to filter. Only applicable when `userId` is provided. schema: type: string format: date-time - name: endAt in: query required: false description: The end date time to filter. Only applicable when `userId` is provided. schema: type: string format: date-time - $ref: '#/components/parameters/TraceparentHeader' responses: '200': description: List of bookings content: application/json: schema: type: array items: $ref: '#/components/schemas/Booking' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/Errors' post: summary: Create an order for booking events operationId: bookEvents description: ✨ Create an order for booking events. tags: - Bookings parameters: - $ref: '#/components/parameters/TraceparentHeader' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BookEventRequest' responses: '201': description: Booking created content: application/json: schema: $ref: '#/components/schemas/BookingOrder' '400': description: Bad Request content: application/json: schema: $ref: '#/components/schemas/BookEventErrorResponse' /users: delete: tags: - Bookings summary: Delete user data from bookings description: | ✨ Deletes all user-related data from the bookings system including: - User's booking history (as athlete or coach) - User's booking orders and payment records - User's booking notes and interactions - User's dispute records If userId parameter is provided, deletes the specified user (admin only). If userId is not provided, deletes the current user (from x-current-user-id header). operationId: deleteUserFromBookings parameters: - $ref: '#/components/parameters/CurrentUserId' - $ref: '#/components/parameters/UserId' responses: '204': description: User data successfully deleted '400': $ref: '#/components/responses/400' '403': $ref: '#/components/responses/403' '404': $ref: '#/components/responses/404' security: - bearerHttpAuthentication: [] components: securitySchemes: bearerHttpAuthentication: description: Bearer token using a JWT type: http scheme: bearer bearerFormat: JWT parameters: TraceparentHeader: name: traceparent in: header required: false description: W3C Trace Context traceparent header for request tracing schema: type: string pattern: ^[0-9a-f]{2}-[0-9a-f]{32}-[0-9a-f]{16}-[0-9a-f]{2}$ example: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 CurrentUserId: name: x-current-user-id in: header required: true description: Current user ID for authentication and authorization schema: type: string format: uuid example: 4b72d209-debd-45e1-93cc-7640bf7d39bf UserId: name: userId in: query required: false description: | User ID to delete. If not provided, deletes the current user (from x-current-user-id header). Only admins can delete other users. schema: type: string format: uuid example: 4b72d209-debd-45e1-93cc-7640bf7d39bf x-go-name: UserIdParam schemas: Error: type: object required: - code - message - endpoint - requestId properties: code: type: string description: Error unique code enum: - validation - internal - oops - unexpected - tooManyRequests - notFound - unauthorized - forbidden message: type: string description: Error message endpoint: type: string requestId: type: string Errors: type: object required: - errors properties: errors: type: array items: $ref: '#/components/schemas/Error' Id: type: string example: 4b72d209-debd-45e1-93cc-7640bf7d39bf description: Database entity primary key uuid format: uuid maxLength: 36 minLength: 36 pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ UserId: type: string example: 00000000-0000-1000-9000-55f01dda9dd0 description: User ID format: uuid CoachEventId: type: string example: 4b72d209-debd-45e1-93cc-7640bf7d39bf description: Event UUID format: uuid maxLength: 36 minLength: 36 pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ BookingStatus: type: string enum: - Accepted - Rejected - Pending - Canceled - InDispute - DisputeDone BookingCanceledByRole: type: string description: Who canceled the booking enum: - Athlete - Coach - System BookingCancellationReasonCode: type: string description: Reason code for booking cancellation enum: - NotFeelingWell - NoTime - Other TimeSlotId: type: string example: 4b72d209-debd-45e1-93cc-7640bf7d39bf description: Time Slot UUID format: uuid maxLength: 36 minLength: 36 pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ Time: type: string format: time description: time in RFC-3339 example: 12:09:53+00:00 Currency: type: string enum: - RUB AddressId: type: string example: 4b72d209-debd-45e1-93cc-7640bf7d39bf description: Address UUID format: uuid maxLength: 36 minLength: 36 pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ TimeSlot: type: object required: - timeSlotId - startTime - endTime - numberOfParticipants - slotType - ageFrom - ageTo - duration - price - priceCurrency - paymentMethod properties: timeSlotId: $ref: '#/components/schemas/TimeSlotId' startTime: $ref: '#/components/schemas/Time' endTime: $ref: '#/components/schemas/Time' numberOfParticipants: type: integer minimum: 1 slotType: type: string enum: - Online - Offline ageFrom: type: integer minimum: 18 maximum: 99 ageTo: type: integer minimum: 18 maximum: 99 duration: type: integer minimum: 15 price: type: integer priceCurrency: $ref: '#/components/schemas/Currency' paymentMethod: type: string enum: - Cash addressId: $ref: '#/components/schemas/AddressId' public: type: boolean level: type: string enum: - Any - Beginner - Medium - Pro eligibility: type: string enum: - All - Men - Women Booking: type: object properties: bookingId: $ref: '#/components/schemas/Id' orderId: type: string format: uuid userId: $ref: '#/components/schemas/UserId' coachId: type: string format: uuid eventId: $ref: '#/components/schemas/CoachEventId' startAt: type: string format: date-time endAt: type: string format: date-time bookingStatus: $ref: '#/components/schemas/BookingStatus' eventStatus: type: string nullable: true completed: type: boolean note: type: string nullable: true canceledAt: type: string format: date-time nullable: true canceledByRole: allOf: - $ref: '#/components/schemas/BookingCanceledByRole' type: string nullable: true cancellationReasonCode: allOf: - $ref: '#/components/schemas/BookingCancellationReasonCode' type: string nullable: true cancellationReasonText: type: string nullable: true sportId: $ref: '#/components/schemas/Id' serviceCardinality: type: integer nullable: true description: The cardinality of the service (1st, 2nd, 3rd service) for this coach, or null if unavailable timeslot: $ref: '#/components/schemas/TimeSlot' required: - bookingId - orderId - userId - coachId - eventId - startAt - endAt - bookingStatus - eventStatus - completed - note - timeslot BookingOrderPaymentStatus: type: string enum: - Pending - Paid - Failed - Cash BookingOrder: type: object properties: orderId: $ref: '#/components/schemas/Id' userId: $ref: '#/components/schemas/UserId' paymentStatus: $ref: '#/components/schemas/BookingOrderPaymentStatus' createdAt: type: string format: date-time bookings: type: array items: $ref: '#/components/schemas/Booking' required: - orderId - userId - status - paymentStatus - createdAt - bookings PaymentMethodId: type: string example: 4b72d209-debd-45e1-93cc-7640bf7d39bf description: Payment Method uuid format: uuid maxLength: 36 minLength: 36 pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ BookEventPaymentMethod: type: object description: | Specifies the payment method for booking one or more events. For the project's MVP, only `Cash` will be accepted. Once `Card` payments are enabled, the `methodId` field must be provided when the payment type is `Card`. properties: type: type: string enum: - Cash - Card methodId: $ref: '#/components/schemas/PaymentMethodId' required: - type BookEventRequest: type: object properties: userId: $ref: '#/components/schemas/UserId' eventIds: type: array items: $ref: '#/components/schemas/Id' paymentMethod: $ref: '#/components/schemas/BookEventPaymentMethod' required: - userId - eventIds - paymentMethod BookEventError: type: object required: - eventId - bookingError properties: eventId: $ref: '#/components/schemas/Id' bookingError: type: string description: | Indicates the type of booking error encountered. The `overbooked` error occurs when one or more requested events exceed capacity. The `conflictingUserSchedules` error occurs when there are scheduling conflicts for one or more requested events. The `selfBookAttempt` occurs when a user tries to book one of their own events. The `pastEventBookAttempt` occurs when a user tries to book an event that has already occurred. The `tooCloseToEventStart` occurs when a user tries to book an event within 30 minutes of its start time. enum: - overbooked - conflictingUserSchedules - selfBookAttempt - pastEventBookAttempt - tooCloseToEventStart BookEventErrorResponse: allOf: - $ref: '#/components/schemas/Error' - type: object properties: errors: type: array items: $ref: '#/components/schemas/BookEventError' responses: '400': description: Bad Request, the request is not valid content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: - code: 400 message: The request is not valid '403': description: Forbidden, you are not allowed to perform this action content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: - code: 403 message: You are not allowed to perform this action '404': description: Not found, the resource you are looking for does not exist content: application/json: schema: $ref: '#/components/schemas/Errors' example: errors: - code: 404 message: Resource not found