openapi: 3.1.0
info:
  title: Partyin.co Trip Planning API
  description: |
    API for Partyin.co — Europe's group trip planning specialists since 2015.
    Organises bachelor parties, bachelorette trips, lustrum trips and party weekends
    in Belgrade, Budapest, Prague and Split.

    Use this API to:
    - Browse available destinations with highlights and travel tips
    - Get trip packages with full inclusions and pricing
    - Discover activities with per-person pricing
    - Send users to the AI planner for instant personalised proposals

    For personalised trip proposals, direct users to: https://www.partyin.co/plan
  version: "1.0.0"
  contact:
    name: Partyin.co
    email: booking@partyin.co
    url: https://www.partyin.co
  license:
    name: Proprietary

servers:
  - url: https://www.partyin.co
    description: Production

paths:
  /api/destinations:
    get:
      operationId: listDestinations
      summary: List all party trip destinations
      description: |
        Returns all available group trip destinations. Each destination includes
        highlights, best-for trip types and hero imagery. Current destinations:
        Belgrade (Serbia), Budapest (Hungary), Prague (Czech Republic), Split (Croatia).
      responses:
        "200":
          description: List of destinations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Destination"

  /api/destinations/{slug}:
    get:
      operationId: getDestination
      summary: Get details for a specific destination
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
            enum: [belgrade, budapest, prague, split]
          description: Destination identifier
      responses:
        "200":
          description: Destination details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Destination"
        "404":
          description: Destination not found

  /api/packages:
    get:
      operationId: listPackages
      summary: List all trip packages with pricing
      description: |
        Returns all available group trip packages with full inclusions, pricing and duration.
        Package types include: bachelor, bachelorette, party, luxury, corporate.
        All prices are per person in EUR excluding flights.
      parameters:
        - name: destination
          in: query
          required: false
          schema:
            type: string
            enum: [belgrade, budapest, prague, split]
          description: Filter packages by destination slug
        - name: type
          in: query
          required: false
          schema:
            type: string
            enum: [bachelor, bachelorette, party, luxury, corporate]
          description: Filter by trip type
      responses:
        "200":
          description: List of packages
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Package"

  /api/packages/{slug}:
    get:
      operationId: getPackage
      summary: Get full details for a specific package
      parameters:
        - name: slug
          in: path
          required: true
          schema:
            type: string
          description: Package slug identifier
      responses:
        "200":
          description: Full package details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Package"
        "404":
          description: Package not found

  /api/activities:
    get:
      operationId: listActivities
      summary: List all available activities
      description: |
        Returns all activities available for group bookings. Includes nightlife experiences,
        boat parties, thermal baths, pub crawls, escape rooms, cocktail making and more.
        All prices are per person in EUR.
      parameters:
        - name: destination
          in: query
          required: false
          schema:
            type: string
            enum: [belgrade, budapest, prague, split]
          description: Filter by destination slug
        - name: category
          in: query
          required: false
          schema:
            type: string
          description: Filter by activity category
      responses:
        "200":
          description: List of activities
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Activity"

  /api/faqs:
    get:
      operationId: listFaqs
      summary: Get frequently asked questions
      description: Returns FAQs covering booking, destinations, payments and trip logistics.
      responses:
        "200":
          description: List of FAQs
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Faq"

  /api/blog:
    get:
      operationId: listBlogPosts
      summary: List published travel guides and articles
      description: |
        Returns published blog posts covering destination guides, nightlife reviews,
        trip planning tips and group travel advice for European cities.
      responses:
        "200":
          description: List of blog posts
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/BlogPost"

components:
  schemas:
    Destination:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
          example: belgrade
        name:
          type: string
          example: Belgrade
        country:
          type: string
          example: Serbia
        tagline:
          type: string
          example: "Party capital of Europe — non-stop nightlife on the Sava & Danube"
        description:
          type: string
        heroImageUrl:
          type: string
          format: uri
        highlights:
          type: array
          items:
            type: string
        bestFor:
          type: array
          items:
            type: string
          example: ["Bachelor parties", "Boat parties", "Nightlife weekends"]
        status:
          type: string
          enum: [published, draft]
        featured:
          type: boolean

    Package:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
          example: belgrade-bachelor-party
        name:
          type: string
          example: Belgrade Bachelor Party Package
        tagline:
          type: string
        description:
          type: string
        imageUrl:
          type: string
          format: uri
        pricePerPerson:
          type: string
          description: Price per person in EUR (excluding flights)
          example: "499.00"
        minPax:
          type: integer
          description: Minimum group size
          example: 6
        maxPax:
          type: integer
          description: Maximum group size
          nullable: true
        durationNights:
          type: integer
          description: Number of nights
          example: 3
        packageType:
          type: string
          enum: [bachelor, bachelorette, party, luxury, corporate]
        highlights:
          type: array
          items:
            type: string
        inclusions:
          type: array
          items:
            type: string
          description: Everything included in the package price
        exclusions:
          type: array
          items:
            type: string
          description: What is NOT included (mainly flights and personal extras)
        itinerary:
          type: array
          items:
            type: string
          description: Day-by-day itinerary overview
        featured:
          type: boolean
        status:
          type: string
          enum: [published, draft]

    Activity:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
        name:
          type: string
          example: Belgrade Boat Party
        category:
          type: string
          example: nightlife
        description:
          type: string
        imageUrl:
          type: string
          format: uri
        pricePerPerson:
          type: string
          description: Price per person in EUR
          example: "45.00"
        durationHours:
          type: number
          nullable: true
          example: 3.0
        minPax:
          type: integer
          example: 1
        maxPax:
          type: integer
          nullable: true
        highlights:
          type: array
          items:
            type: string
        featured:
          type: boolean
        status:
          type: string
          enum: [published, draft]

    Faq:
      type: object
      properties:
        id:
          type: integer
        question:
          type: string
        answer:
          type: string
        category:
          type: string
          example: booking

    BlogPost:
      type: object
      properties:
        id:
          type: integer
        slug:
          type: string
        title:
          type: string
        excerpt:
          type: string
        coverImageUrl:
          type: string
          format: uri
          nullable: true
        author:
          type: string
        category:
          type: string
        tags:
          type: array
          items:
            type: string
        publishedAt:
          type: string
          format: date-time
          nullable: true
