📄 OpenAPI Specification

Lucky Rentals AI Agent API v1.0.0
openapi: 3.0.3
info:
  title: Lucky Rentals AI Agent API
  description: |
    API for AI agents to discover vehicle availability and pricing for the Lucky Rentals booking system.
    
    ## Workflow
    
    1. **Discover Depots**: GET `/api/agent/depots` to get available pickup/dropoff locations
    2. **Check Availability**: GET `/api/agent/vehicles/availability` with dates and locations to get available vehicles
    3. **Discover Options**: For a chosen vehicle, get accessories and insurance options:
       - GET `/api/agent/vehicles/{vehicleId}/accessories`
       - GET `/api/agent/vehicles/{vehicleId}/insurance-types`
    4. **Get Quote**: GET `/api/agent/quotes` with vehicle and selected options for final pricing
  version: 1.0.0
  contact:
    name: Lucky Rentals API Support

servers:
  - url: https://www.luckyrentals.co.nz
    description: Lucky Rentals AI Agent API

paths:
  /api/agent/depots:
    get:
      summary: Get all available depot locations
      description: Returns a list of all active depot locations with their operating hours
      tags:
        - Discovery
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Depot'
              example:
                - id: 1
                  name: "Auckland Airport"
                  pickup_times: 
                    - { "time": "09:00", "day": "weekday" }
                    - { "time": "10:00", "day": "weekend" }
                  drop_off_times:
                    - { "time": "17:00", "day": "weekday" }
                    - { "time": "16:00", "day": "weekend" }
                  opening_hours_description: "Weekdays 9am-5pm, Weekends 10am-4pm"
                - id: 2
                  name: "Auckland City"
                  pickup_times:
                    - { "time": "08:00", "day": "weekday" }
                    - { "time": "09:00", "day": "weekend" }
                  drop_off_times:
                    - { "time": "18:00", "day": "weekday" }
                    - { "time": "17:00", "day": "weekend" }
                  opening_hours_description: "Weekdays 8am-6pm, Weekends 9am-5pm"
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'

  /api/agent/vehicles/availability:
    get:
      summary: Get available vehicles for given criteria
      description: Returns a list of vehicles available for the specified dates and locations
      tags:
        - Discovery
      parameters:
        - name: pick_up_depot_id
          in: query
          required: true
          schema:
            type: integer
          description: ID of the pickup depot
          example: 1
        - name: drop_off_depot_id
          in: query
          required: true
          schema:
            type: integer
          description: ID of the drop-off depot
          example: 2
        - name: pick_up_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: Pickup date (YYYY-MM-DD)
          example: "2024-01-15"
        - name: drop_off_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: Drop-off date (YYYY-MM-DD)
          example: "2024-01-22"
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Vehicle'
              example:
                - vehicleId: 4
                  name: "Lucky Rover Beta"
                  rentalDailyRate: 45.00
                  imageUrl: "https://api.example.com/vehicle-type/4/image"
                - vehicleId: 7
                  name: "Adventure Camper Plus"
                  rentalDailyRate: 65.00
                  imageUrl: "https://api.example.com/vehicle-type/7/image"
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'

  /api/agent/vehicles/{vehicleId}/accessories:
    get:
      summary: Get accessories available for a specific vehicle
      description: Returns a list of accessories that can be added to the specified vehicle
      tags:
        - Options Discovery
      parameters:
        - name: vehicleId
          in: path
          required: true
          schema:
            type: integer
          description: ID of the vehicle
          example: 4
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Accessory'
              example:
                - id: 1
                  name: "Bedding Pack (for 2 people)"
                  price: 10.00
                - id: 2
                  name: "Camping Chairs (set of 2)"
                  price: 10.00
                - id: 15
                  name: "Portable BBQ"
                  price: 25.00
                - id: 23
                  name: "Outdoor Table"
                  price: 15.00
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'

  /api/agent/vehicles/{vehicleId}/insurance-types:
    get:
      summary: Get insurance options available for a specific vehicle
      description: Returns a list of insurance plans that can be selected for the specified vehicle
      tags:
        - Options Discovery
      parameters:
        - name: vehicleId
          in: path
          required: true
          schema:
            type: integer
          description: ID of the vehicle
          example: 4
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Insurance'
              example:
                - id: 1
                  name: "Basic Insurance (No excess reduction)"
                  price: 0.00
                - id: 15
                  name: "\"On the Fence\" Insurance ($1500 Excess)"
                  price: 15.00
                - id: 3
                  name: "Premium Insurance ($500 Excess)"
                  price: 35.00
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'

  /api/agent/quotes:
    get:
      summary: Get detailed price quote for vehicle configuration
      description: Returns a comprehensive price breakdown for the specified vehicle and options
      tags:
        - Quoting
      parameters:
        - name: pick_up_depot_id
          in: query
          required: true
          schema:
            type: integer
          description: ID of the pickup depot
          example: 1
        - name: drop_off_depot_id
          in: query
          required: true
          schema:
            type: integer
          description: ID of the drop-off depot
          example: 1
        - name: pick_up_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: Pickup date (YYYY-MM-DD)
          example: "2025-09-17"
        - name: drop_off_date
          in: query
          required: true
          schema:
            type: string
            format: date
          description: Drop-off date (YYYY-MM-DD)
          example: "2025-09-24"
        - name: vehicle_class_id
          in: query
          required: true
          schema:
            type: integer
          description: ID of the selected vehicle
          example: 4
        - name: accessories
          in: query
          required: false
          schema:
            type: string
          description: Comma-separated list of accessory IDs (e.g., "1,5,7")
          example: "1,2"
        - name: insurance_type
          in: query
          required: false
          schema:
            type: integer
          description: ID of the selected insurance plan
          example: 15
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
              example:
                quoteId: "1757992557279-4"
                expiresAt: "2025-09-16T03:45:57.279Z"
                currency: "NZD"
                priceBreakdown:
                  rentalFee: 360.00
                  routeFee: 0.00
                  accessoriesFee: 20.00
                  insuranceFee: 120.00
                  accessories:
                    - id: 1
                      name: "Bedding Pack (for 2 people)"
                      cost: 10.00
                      quantity: 1
                    - id: 2
                      name: "Camping Chairs (set of 2)"
                      cost: 10.00
                      quantity: 1
                  insurance:
                    id: 15
                    name: "\"On the Fence\" Insurance ($1500 Excess)"
                    cost: 120.00
                totalAmount: 500.00
                note: "All amounts are in NZD dollars. Original external API returns values in cents which are automatically converted for AI consumption."
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'

components:
  schemas:
    Depot:
      type: object
      properties:
        id:
          type: integer
          description: Unique identifier for the depot
        name:
          type: string
          description: Display name of the depot
        pickup_times:
          type: array
          items:
            type: object
          description: Available pickup times
        drop_off_times:
          type: array
          items:
            type: object
          description: Available drop-off times
        opening_hours_description:
          type: string
          description: Human-readable description of opening hours

    Vehicle:
      type: object
      properties:
        vehicleId:
          type: integer
          description: Unique identifier for the vehicle
        name:
          type: string
          description: Display name of the vehicle
        rentalDailyRate:
          type: number
          format: float
          description: Base daily rental rate
        imageUrl:
          type: string
          format: uri
          description: URL to vehicle image

    Accessory:
      type: object
      properties:
        id:
          type: integer
          description: Unique identifier for the accessory
        name:
          type: string
          description: Display name of the accessory
        price:
          type: number
          format: float
          description: Price of the accessory

    Insurance:
      type: object
      properties:
        id:
          type: integer
          description: Unique identifier for the insurance plan
        name:
          type: string
          description: Display name of the insurance plan
        price:
          type: number
          format: float
          description: Price of the insurance plan

    Quote:
      type: object
      properties:
        quoteId:
          type: string
          description: Unique identifier for this quote
        expiresAt:
          type: string
          format: date-time
          description: When this quote expires
        priceBreakdown:
          type: object
          properties:
            rentalFee:
              type: number
              format: float
              description: Base vehicle rental cost
            accessoriesFee:
              type: number
              format: float
              description: Total cost of selected accessories
            insuranceFee:
              type: number
              format: float
              description: Cost of selected insurance
            accessories:
              type: array
              items:
                type: object
                properties:
                  name:
                    type: string
                  cost:
                    type: number
                    format: float
            insurance:
              type: object
              nullable: true
              properties:
                name:
                  type: string
                cost:
                  type: number
                  format: float
        totalAmount:
          type: number
          format: float
          description: Final total cost

    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message

  responses:
    BadRequest:
      description: Bad request - invalid parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: "Missing required query parameter: pick_up_depot_id"
    
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: "Vehicle not available for the selected criteria."
    
    RateLimited:
      description: Too many requests
      content:
        text/plain:
          schema:
            type: string
            example: "Too Many Requests"
      headers:
        X-RateLimit-Limit:
          schema:
            type: integer
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: string
    
    ServiceUnavailable:
      description: Service temporarily unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'

tags:
  - name: Discovery
    description: Endpoints for discovering available options
  - name: Options Discovery
    description: Endpoints for discovering vehicle-specific options
  - name: Quoting
    description: Endpoints for generating price quotes