openapi: 3.0.0
info:
  title: MOGU Public API
  version: 1.0.0
  description: Public API for managing trips and catalogs in the MOGU platform
  contact:
    name: MOGU Support
    email: support@moguplatform.com
    url: https://moguplatform.com
  license:
    name: Proprietary
    url: https://moguplatform.com/terms
servers:
  - url: https://trips.api.moguplatform.com
    description: Production server
tags:
  - name: trips
    description: Operations for managing trips
  - name: catalogs
    description: Operations for managing catalogs
  - name: status
    description: API health check
security:
  - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: MOGU API Key (format starts with ak_)
  schemas:
    TripConfig:
      type: object
      description: >-
        Complete configuration for a trip including blocks, contact, settings,
        and theme
      required:
        - version
        - blocks
        - contact
        - updatedAt
        - settings
        - moreInfo
        - theme
        - images
      properties:
        version:
          type: string
          description: Semantic version of the config schema
          example: 1.0.0
        blocks:
          type: array
          description: >-
            Array of content blocks (accommodations, activities, transport,
            etc.)
          items:
            $ref: '#/components/schemas/Block'
        contact:
          $ref: '#/components/schemas/TripContact'
        slider:
          type: array
          description: Array of image URLs for the trip slider
          items:
            type: string
            format: uri
          example:
            - https://example.com/image1.jpg
        updatedAt:
          type: string
          format: date-time
          description: Last update timestamp
          example: '2025-01-20T14:45:00.000Z'
        settings:
          $ref: '#/components/schemas/TripSettings'
        moreInfo:
          $ref: '#/components/schemas/FormContent'
        paymentMethodId:
          type: integer
          description: ID of the payment method associated with this trip
          nullable: true
          example: 123
        quotation:
          type: object
          description: Quotation rates for the trip
          example:
            planningRate: 10
            secondRate: 5
          properties:
            planningRate:
              type: number
              description: Planning rate percentage
              example: 10
            secondRate:
              type: number
              description: Second rate percentage
              example: 5
        theme:
          $ref: '#/components/schemas/TripTheme'
        images:
          type: object
          description: Trip image gallery
          example:
            files: []
          properties:
            files:
              type: array
              items:
                $ref: '#/components/schemas/ImageFile'
        cover:
          $ref: '#/components/schemas/TripCover'
    TripConfigUpdate:
      type: object
      description: Schema for updating trip configuration (blocks validation is relaxed)
      required:
        - version
        - blocks
        - contact
        - settings
        - moreInfo
        - theme
        - images
      properties:
        version:
          type: string
          example: 1.0.0
        blocks:
          type: array
          description: Array of blocks with flexible content validation
          items:
            type: object
            required:
              - id
              - type
            properties:
              id:
                type: string
                example: block-123
              type:
                type: string
                description: Block type (accommodation, activity, transport, etc.)
                example: accommodation
              content:
                type: object
                description: Block-specific content (structure varies by type)
                additionalProperties: true
              children:
                type: array
                description: Child blocks
                items:
                  type: object
              parent:
                type: string
                description: Parent block ID
                example: block-parent-456
              hidden:
                type: boolean
                description: Whether the block is hidden
                example: false
        contact:
          $ref: '#/components/schemas/TripContact'
        slider:
          type: array
          items:
            type: string
            example: https://example.com/slider-image.jpg
          example: []
        settings:
          $ref: '#/components/schemas/TripSettings'
        moreInfo:
          $ref: '#/components/schemas/FormContent'
        paymentMethodId:
          type: integer
          nullable: true
          example: 123
        quotation:
          type: object
          example:
            planningRate: 10
            secondRate: 5
          properties:
            planningRate:
              type: number
              example: 10
            secondRate:
              type: number
              example: 5
        theme:
          $ref: '#/components/schemas/TripTheme'
        images:
          type: object
          example:
            files: []
          properties:
            files:
              type: array
              items:
                $ref: '#/components/schemas/ImageFile'
        cover:
          $ref: '#/components/schemas/TripCover'
    Block:
      description: >
        A content block in the trip. Blocks can be of different types with
        specific content structures.


        **Block Types:**

        - **Services**: accomodation, flight, activity, food, cruise, transport,
        train, info

        - **General**: text, title, box, dropdown, group, file, gallery, video,
        map

        - **Pricing**: price, payment

        - **Itinerary**: itinerary, itineraryDay

        - **Special**: servicesSummary, practicalInfo, pageBreak, form


        Each block type has a specific content structure. See examples for
        common block types.
      oneOf:
        - $ref: '#/components/schemas/BlockAccommodation'
        - $ref: '#/components/schemas/BlockActivity'
        - $ref: '#/components/schemas/BlockFlight'
        - $ref: '#/components/schemas/BlockText'
        - $ref: '#/components/schemas/BlockPrice'
        - $ref: '#/components/schemas/BlockPayment'
        - $ref: '#/components/schemas/BlockGeneric'
      discriminator:
        propertyName: type
        mapping:
          accomodation: '#/components/schemas/BlockAccommodation'
          activity: '#/components/schemas/BlockActivity'
          flight: '#/components/schemas/BlockFlight'
          text: '#/components/schemas/BlockText'
          price: '#/components/schemas/BlockPrice'
          payment: '#/components/schemas/BlockPayment'
    BlockGeneric:
      type: object
      description: Generic block structure for other block types
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-123
        type:
          type: string
          enum:
            - group
            - file
            - food
            - transport
            - train
            - cruise
            - info
            - dropdown
            - title
            - box
            - map
            - video
            - gallery
            - servicesSummary
            - practicalInfo
            - pageBreak
            - form
            - itinerary
            - itineraryDay
          example: title
        content:
          type: object
          additionalProperties: true
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockAccommodation:
      type: object
      description: Accommodation block (hotel, hostel, apartment, etc.)
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-hotel-123
        type:
          type: string
          enum:
            - accomodation
          example: accomodation
        content:
          type: object
          required:
            - title
          properties:
            title:
              type: string
              example: Hotel Paris Plaza
            location:
              type: string
              example: 123 Rue de la Paix, 75002 Paris, France
            startDate:
              type: string
              format: date-time
              nullable: true
              example: '2025-07-15T00:00:00Z'
            finishDate:
              type: string
              format: date-time
              nullable: true
              example: '2025-07-22T00:00:00Z'
            nights:
              type: integer
              nullable: true
              example: 7
            roomType:
              type: string
              enum:
                - Single
                - Double
                - Triple
                - Quad
                - Suite
              nullable: true
              example: Double
            stayRegime:
              type: string
              enum:
                - AccommodationOnly
                - BedAndBreakfast
                - HalfPension
                - FullPension
                - AllIncluded
              nullable: true
              example: BedAndBreakfast
            description:
              type: string
              example: 4-star hotel in the heart of Paris
            images:
              type: array
              items:
                type: object
                properties:
                  url:
                    type: string
                    example: https://example.com/hotel.jpg
                  display:
                    type: string
                    enum:
                      - cover
                      - contain
                    example: cover
            rating:
              type: integer
              minimum: 1
              maximum: 5
              example: 4
            googlePlaceId:
              type: string
              example: ChIJD7fiBh9u5kcRYJSMaMOCCwQ
            optional:
              type: boolean
              example: false
            checkout:
              $ref: '#/components/schemas/ServiceCheckout'
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockActivity:
      type: object
      description: Activity block (tour, excursion, experience, etc.)
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-activity-456
        type:
          type: string
          enum:
            - activity
          example: activity
        content:
          type: object
          required:
            - title
          properties:
            title:
              type: string
              example: Eiffel Tower Visit
            location:
              type: string
              example: Champ de Mars, Paris
            startDate:
              type: string
              format: date-time
              nullable: true
              example: '2025-07-16T10:00:00Z'
            startTime:
              type: string
              format: date-time
              nullable: true
              example: '2025-07-16T10:00:00Z'
            description:
              type: string
              example: Skip-the-line ticket to the Eiffel Tower
            images:
              type: array
              items:
                type: object
                properties:
                  url:
                    type: string
                    example: https://example.com/eiffel.jpg
            optional:
              type: boolean
              example: true
            checkout:
              $ref: '#/components/schemas/ServiceCheckout'
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockFlight:
      type: object
      description: Flight block with departure and arrival details
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-flight-789
        type:
          type: string
          enum:
            - flight
          example: flight
        content:
          type: object
          required:
            - flightNumber
            - departureDateTime
            - arrivalDateTime
            - departureAirport
            - arrivalAirport
            - airline
            - elapsedTime
          properties:
            flightNumber:
              type: string
              example: AF123
            departureDateTime:
              type: string
              format: date-time
              example: '2025-07-15T08:00:00Z'
            arrivalDateTime:
              type: string
              format: date-time
              example: '2025-07-15T10:30:00Z'
            departureAirport:
              type: object
              properties:
                iata:
                  type: string
                  example: CDG
                name:
                  type: string
                  example: Charles de Gaulle Airport
                city:
                  type: string
                  example: Paris
                country:
                  type: string
                  example: France
            arrivalAirport:
              type: object
              properties:
                iata:
                  type: string
                  example: JFK
                name:
                  type: string
                  example: John F. Kennedy International Airport
                city:
                  type: string
                  example: New York
                country:
                  type: string
                  example: United States
            airline:
              type: object
              properties:
                iata:
                  type: string
                  example: AF
                name:
                  type: string
                  example: Air France
                logo:
                  type: string
                  example: https://example.com/af-logo.png
            elapsedTime:
              type: integer
              description: Flight duration in minutes
              example: 150
            checkout:
              $ref: '#/components/schemas/ServiceCheckout'
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockText:
      type: object
      description: Rich text content block
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-text-111
        type:
          type: string
          enum:
            - text
          example: text
        content:
          type: object
          required:
            - text
          properties:
            text:
              type: string
              description: HTML or markdown formatted text
              example: <p>Welcome to your Paris adventure!</p>
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockPrice:
      type: object
      description: Price option block
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-price-222
        type:
          type: string
          enum:
            - price
          example: price
        content:
          type: object
          required:
            - title
            - price
            - currency
          properties:
            title:
              type: string
              example: Standard Package
            price:
              type: number
              example: 1500
            currency:
              type: string
              example: EUR
            description:
              type: string
              example: Includes hotel and breakfast
            seats:
              type: integer
              nullable: true
              example: 10
            noSeatLimits:
              type: boolean
              example: false
            default:
              type: boolean
              example: true
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    BlockPayment:
      type: object
      description: Payment/checkout block for trip bookings
      required:
        - id
        - type
        - content
      properties:
        id:
          type: string
          example: block-payment-999
        type:
          type: string
          enum:
            - payment
          example: payment
        content:
          type: object
          required:
            - currency
            - paymentType
            - form
            - sections
            - prices
          properties:
            currency:
              type: string
              example: EUR
            paymentType:
              type: string
              enum:
                - online
                - manual
                - both
              example: online
            paymentRequired:
              type: boolean
              example: true
            description:
              type: string
              example: Secure online payment
            form:
              type: object
              description: Booking form configuration
              example:
                questions: []
              properties:
                questions:
                  type: array
                  example: []
                  items:
                    type: object
            sections:
              type: array
              description: Payment sections with services
              example: []
              items:
                type: object
                properties:
                  id:
                    type: string
                    example: section-123
                  title:
                    type: string
                    example: Main Trip Package
                  services:
                    type: array
                    example: []
                    items:
                      type: object
            prices:
              type: object
              description: Price options for the payment block
              example:
                enabled: true
                prices: []
              properties:
                enabled:
                  type: boolean
                  example: true
                prices:
                  type: array
                  example: []
                  items:
                    $ref: '#/components/schemas/BlockPrice'
        children:
          type: array
          items:
            type: object
          example: []
        parent:
          type: string
          example: parent-block-id
        hidden:
          type: boolean
          example: false
    ServiceCheckout:
      type: object
      description: Checkout configuration for a service block
      properties:
        amount:
          type: number
          example: 150
        currency:
          type: string
          example: EUR
        seats:
          type: integer
          nullable: true
          example: 20
        minSeatsPerBooking:
          type: integer
          nullable: true
          example: 1
        maxSeatsPerBooking:
          type: integer
          nullable: true
          example: 4
    TripContact:
      type: object
      description: Contact information displayed on the trip
      properties:
        address:
          type: string
          maxLength: 255
          example: 123 Main Street, Paris, France
        agencyName:
          type: string
          maxLength: 128
          example: Travel Dreams Agency
        agentName:
          type: string
          maxLength: 128
          example: John Doe
        description:
          type: string
          maxLength: 5000
          example: Expert travel agent specializing in European tours
        email:
          type: string
          format: email
          example: contact@travelagency.com
        phoneNumber:
          type: string
          maxLength: 50
          example: +33 1 23 45 67 89
        pictureUrl:
          type: string
          format: uri
          example: https://example.com/agent-photo.jpg
        type:
          type: string
          description: Type of contact
          enum:
            - agency
            - agent
          example: agency
        visible:
          type: boolean
          description: Whether contact info is visible on the trip
          example: true
        web:
          type: string
          format: uri
          example: https://travelagency.com
    TripSettings:
      type: object
      description: Trip settings and preferences
      required:
        - canDownloadPdf
        - canCreateCopy
        - hasExpiration
        - language
        - startOfTheWeek
        - timeFormat
        - dateFormat
        - timezone
        - currencySymbolPosition
        - decimalSeparator
        - currency
      properties:
        description:
          type: string
          maxLength: 500
          example: A wonderful 7-day trip to Paris
        canDownloadPdf:
          type: boolean
          description: Allow travelers to download trip as PDF
          example: true
        canCreateCopy:
          type: boolean
          description: Allow travelers to create a copy of the trip
          example: false
        hasExpiration:
          type: boolean
          description: Whether the trip has an expiration date
          example: false
        shareOnWhatsapp:
          type: object
          description: WhatsApp sharing configuration
          example:
            enabled: true
            phoneNumber: '+33123456789'
          properties:
            enabled:
              type: boolean
              example: true
            phoneNumber:
              type: string
              example: '+33123456789'
        language:
          type: string
          description: Trip language code
          example: en
        startOfTheWeek:
          type: string
          description: First day of the week
          enum:
            - monday
            - sunday
          example: monday
        timeFormat:
          type: string
          description: Time format preference
          enum:
            - 12h
            - 24h
          example: 24h
        dateFormat:
          type: string
          description: Date format pattern
          example: DD/MM/YYYY
        timezone:
          type: string
          maxLength: 50
          description: IANA timezone identifier
          example: Europe/Paris
        currencySymbolPosition:
          type: string
          description: Where to display currency symbol
          enum:
            - start
            - end
          example: end
        decimalSeparator:
          type: string
          description: Decimal separator character
          enum:
            - ','
            - .
          example: ','
        currency:
          type: string
          minLength: 3
          maxLength: 3
          description: ISO 4217 currency code
          example: EUR
    TripTheme:
      type: object
      description: Visual theme and branding for the trip
      properties:
        headerImage:
          type: object
          description: Header image configuration
          example:
            config: cover
          properties:
            config:
              type: string
              description: Header image display mode
              enum:
                - cover
                - contain
                - none
              example: cover
        navigation:
          type: string
          description: Navigation layout style
          enum:
            - verticalRight
            - verticalLeft
            - horizontal
            - none
          nullable: true
          example: verticalRight
        logo:
          type: string
          format: uri
          description: URL of the agency/brand logo
          example: https://example.com/logo.png
        color:
          type: string
          description: Primary brand color (hex code)
          pattern: ^#[0-9A-Fa-f]{6}$
          example: '#195bf5'
        font:
          type: string
          description: Font family for the trip
          nullable: true
          example: Roboto
        pdfContactPosition:
          type: string
          description: Where to display contact info in PDF
          enum:
            - firstPage
            - lastPage
          nullable: true
          example: lastPage
    FormContent:
      type: object
      description: Additional information form configuration
      required:
        - enabled
        - fields
      properties:
        enabled:
          type: boolean
          description: Whether the additional info form is enabled
          example: false
        fields:
          type: array
          description: Form field definitions
          example: []
          items:
            type: object
            example:
              id: field-123
              type: text
              label: Dietary restrictions
              required: false
            properties:
              id:
                type: string
                example: field-123
              type:
                type: string
                enum:
                  - text
                  - email
                  - phone
                  - textarea
                  - select
                  - checkbox
                example: text
              label:
                type: string
                example: Dietary restrictions
              required:
                type: boolean
                example: false
    ImageFile:
      type: object
      description: Image file in the trip gallery
      required:
        - url
      properties:
        url:
          type: string
          format: uri
          description: URL of the image
          example: https://example.com/trip-image.jpg
        display:
          type: string
          description: Image display mode
          enum:
            - cover
            - contain
          example: cover
        index:
          type: integer
          description: Display order index
          example: 0
    TripCover:
      type: object
      description: Trip cover image configuration
      properties:
        enabled:
          type: boolean
          description: Whether cover is enabled
          example: true
        files:
          type: array
          description: Cover image files
          example: []
          items:
            $ref: '#/components/schemas/ImageFile'
paths:
  /trips:
    get:
      operationId: listTrips
      summary: Get trips
      description: Retrieve a paginated list of trips with optional filtering and sorting
      tags:
        - trips
      parameters:
        - name: page
          in: query
          required: false
          description: Page number (starts at 1)
          schema:
            type: integer
            example: 1
        - name: pageSize
          in: query
          required: false
          description: Number of items per page
          schema:
            type: integer
            example: 20
        - name: filters
          in: query
          required: false
          description: >-
            JSON array of filters, e.g.
            [{"field":"duration","operator":"gte","value":5}]
          style: form
          explode: false
          schema:
            type: string
            example: '[{"field":"duration","operator":"gte","value":5}]'
        - name: orderBy
          in: query
          required: false
          description: >-
            JSON object for sorting, e.g.
            {"field":"createdAt","direction":"desc"}
          style: form
          explode: false
          schema:
            type: string
            example: '{"field":"createdAt","direction":"desc"}'
        - name: search
          in: query
          required: false
          description: JSON object for searching, e.g. {"fields":["title"],"term":"Paris"}
          style: form
          explode: false
          schema:
            type: string
            example: '{"fields":["title"],"term":"Paris"}'
      responses:
        '200':
          description: Successful response with paginated trips
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                  page:
                    type: integer
                    example: 1
                  pageSize:
                    type: integer
                    example: 20
                  totalCount:
                    type: integer
                    example: 150
                  totalPages:
                    type: integer
                    example: 8
        '400':
          description: Invalid request parameters
    post:
      operationId: createTrip
      summary: Create trip
      description: Create a new trip with the specified details
      tags:
        - trips
      responses:
        '201':
          description: Trip created successfully
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Invalid request body
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
              properties:
                title:
                  type: string
                  example: Paris Summer Vacation
                duration:
                  type: integer
                  example: 7
                dateStart:
                  type: string
                  format: date-time
                  example: '2025-07-15T00:00:00.000Z'
                dateFinish:
                  type: string
                  format: date-time
                  example: '2025-07-22T00:00:00.000Z'
                countries:
                  type: array
                  items:
                    type: string
                  example:
                    - FRA
    delete:
      operationId: deleteTripsInBulk
      summary: Delete trips in bulk
      description: Delete multiple trips at once
      tags:
        - trips
      responses:
        '200':
          description: Trips deleted successfully
        '400':
          description: Invalid request body
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - tripId
              properties:
                tripId:
                  type: array
                  items:
                    type: integer
                    example: 12345
                  example:
                    - 12345
                    - 12346
                    - 12347
  /trips/{tripId}:
    get:
      operationId: getTripById
      summary: Get trip
      description: Retrieve detailed information about a specific trip
      tags:
        - trips
      responses:
        '200':
          description: Trip details retrieved successfully
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Trip not found
    patch:
      operationId: updateTrip
      summary: Update trip
      description: Update an existing trip's details
      tags:
        - trips
      responses:
        '200':
          description: Trip updated successfully
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Invalid request
        '404':
          description: Trip not found
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  example: Paris Summer Vacation
                duration:
                  type: integer
                  example: 7
                dateStart:
                  type: string
                  format: date-time
                  example: '2025-07-15T00:00:00.000Z'
                dateFinish:
                  type: string
                  format: date-time
                  example: '2025-07-22T00:00:00.000Z'
    delete:
      operationId: deleteTrip
      summary: Delete trip
      description: Delete a specific trip by ID
      tags:
        - trips
      responses:
        '200':
          description: Trip deleted successfully
        '404':
          description: Trip not found
    parameters:
      - name: tripId
        in: path
        required: true
        description: Unique identifier of the trip
        schema:
          type: integer
          example: 12345
  /trips/{tripId}/config:
    get:
      operationId: getTripConfig
      summary: Get trip configuration
      description: >-
        Retrieve the complete configuration for a trip, including blocks,
        contact info, settings, and theme
      tags:
        - trips
      responses:
        '200':
          description: Trip configuration retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TripConfig'
        '400':
          description: Invalid trip ID
        '404':
          description: Trip config not found
    put:
      operationId: updateTripConfig
      summary: Update trip configuration
      description: Update the complete configuration for a trip (replaces existing config)
      tags:
        - trips
      responses:
        '200':
          description: Configuration updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Config updated
        '400':
          description: Invalid request body or dangerous update attempt
        '404':
          description: Trip not found
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TripConfigUpdate'
    parameters:
      - name: tripId
        in: path
        required: true
        description: Unique identifier of the trip
        schema:
          type: integer
          example: 12345
  /catalogs:
    get:
      operationId: listCatalogs
      summary: Get catalogs
      description: Retrieve a paginated list of catalogs
      tags:
        - catalogs
      parameters:
        - name: page
          in: query
          required: false
          description: Page number
          schema:
            type: integer
            example: 1
        - name: pageSize
          in: query
          required: false
          description: Items per page
          schema:
            type: integer
            example: 20
        - name: filters
          in: query
          required: false
          description: JSON array of filters
          schema:
            type: string
            example: '[]'
        - name: orderBy
          in: query
          required: false
          description: JSON object for sorting
          schema:
            type: string
            example: '{"field":"title","direction":"asc"}'
        - name: search
          in: query
          required: false
          description: JSON object for searching
          schema:
            type: string
            example: '{"fields":["title"],"term":"Europe"}'
      responses:
        '200':
          description: Successful response with paginated catalogs
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Invalid request parameters
    post:
      operationId: createCatalog
      summary: Create catalog
      description: Create a new catalog with the specified details
      tags:
        - catalogs
      responses:
        '201':
          description: Catalog created successfully
        '400':
          description: Invalid request body
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - title
              properties:
                title:
                  type: string
                  example: European Tours
                description:
                  type: string
                  example: Collection of our best European tours
                filters:
                  type: object
                  properties:
                    country:
                      type: boolean
                      example: true
                logoUrl:
                  type: string
                  format: uri
                  example: https://example.com/catalog-logo.png
                tripIds:
                  type: array
                  items:
                    type: integer
                    example: 12345
                  example:
                    - 12345
                    - 12346
    delete:
      operationId: deleteCatalogsInBulk
      summary: Delete catalogs in bulk
      description: Delete multiple catalogs at once
      tags:
        - catalogs
      responses:
        '200':
          description: Catalogs deleted successfully
        '400':
          description: Invalid request body
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - catalogIds
              properties:
                catalogIds:
                  type: array
                  items:
                    type: integer
                    example: 101
                  example:
                    - 101
                    - 102
                    - 103
  /catalogs/{id}:
    get:
      operationId: getCatalogById
      summary: Get catalog
      description: Retrieve detailed information about a specific catalog
      tags:
        - catalogs
      responses:
        '200':
          description: Catalog details
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Catalog not found
    patch:
      operationId: updateCatalog
      summary: Update catalog
      description: Update catalog details and associated trips
      tags:
        - catalogs
      responses:
        '200':
          description: Catalog updated successfully
        '400':
          description: Invalid request body
        '404':
          description: Catalog not found
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                  example: Updated European Tours
                description:
                  type: string
                  example: Updated collection description
                tripIds:
                  type: array
                  items:
                    type: integer
                    example: 12345
                  example:
                    - 12345
                    - 12346
                    - 12347
    delete:
      operationId: deleteCatalog
      summary: Delete catalog
      description: Delete a specific catalog by ID
      tags:
        - catalogs
      responses:
        '200':
          description: Catalog deleted successfully
        '404':
          description: Catalog not found
    parameters:
      - name: id
        in: path
        required: true
        description: Unique identifier of the catalog
        schema:
          type: integer
          example: 101
  /catalogs/{id}/trips:
    get:
      operationId: getCatalogTrips
      summary: Get trips in catalog
      description: Retrieve all trips associated with a specific catalog
      tags:
        - catalogs
      parameters:
        - name: filters
          in: query
          required: false
          description: JSON array of filters
          schema:
            type: string
            example: '[]'
      responses:
        '200':
          description: List of trips in the catalog
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Catalog not found
    parameters:
      - name: id
        in: path
        required: true
        description: Unique identifier of the catalog
        schema:
          type: integer
          example: 101
  /catalogs/public/{id}:
    get:
      operationId: getPublicCatalog
      summary: Get public catalog
      description: Retrieve a publicly accessible catalog by ID
      tags:
        - catalogs
      security: []
      parameters:
        - name: filters
          in: query
          required: false
          description: JSON array of filters
          schema:
            type: string
            example: '[]'
      responses:
        '200':
          description: Public catalog details
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Catalog not found
    parameters:
      - name: id
        in: path
        required: true
        description: Unique identifier of the catalog
        schema:
          type: integer
          example: 101
  /status:
    get:
      operationId: getStatus
      summary: Health check status
      description: Check if the API is running
      tags:
        - status
      security: []
      responses:
        '200':
          description: API is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok
        '503':
          description: Service unavailable
