openapi: 3.1.0
info:
  title: Jet Intelligence Operator Integration API
  version: 1.0.0
  description: Tenant-scoped exchange of assigned charter RFQs and operator responses.
servers:
  - url: https://www.jet-intelligence.com/api/v1/operator
security:
  - operatorBearer: []
paths:
  /rfqs:
    get:
      operationId: listAssignedOperatorRfqs
      summary: List active RFQs assigned to the authenticated operator
      parameters:
        - in: query
          name: limit
          schema: { type: integer, minimum: 1, maximum: 100, default: 25 }
        - in: query
          name: offset
          schema: { type: integer, minimum: 0, maximum: 5000, default: 0 }
      responses:
        "200":
          description: Assigned requests with route and trip requirements; no passenger identity data.
          content:
            application/json:
              schema:
                type: object
                required: [data, pagination]
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/AssignedRfq" } }
                  pagination:
                    type: object
                    properties:
                      limit: { type: integer }
                      offset: { type: integer }
                      next_offset: { type: [integer, "null"] }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
  /rfqs/{rfq_id}/responses:
    post:
      operationId: submitOperatorResponse
      summary: Submit a quote, alternative, question, or decline
      parameters:
        - in: path
          name: rfq_id
          required: true
          schema: { type: string, format: uuid }
        - in: header
          name: Idempotency-Key
          required: true
          schema: { type: string, minLength: 8, maxLength: 128, pattern: "^[A-Za-z0-9._:-]+$" }
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/OperatorResponse" }
      responses:
        "200":
          description: Response accepted; a duplicate identical request replays the original result.
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
components:
  securitySchemes:
    operatorBearer:
      type: http
      scheme: bearer
      bearerFormat: Jet Intelligence operator API key
  responses:
    Error:
      description: API error
      content:
        application/json:
          schema:
            type: object
            required: [error]
            properties:
              error: { type: string }
  schemas:
    AssignedRfq:
      type: object
      required: [recipient_id, rfq_id, response_status, response_deadline, reference, passenger_count, currency, requirements, legs]
      properties:
        recipient_id: { type: string, format: uuid }
        rfq_id: { type: string, format: uuid }
        response_status: { type: string, enum: [queued, sent, opened, question] }
        response_deadline: { type: string, format: date-time }
        reference: { type: string }
        passenger_count: { type: integer }
        currency: { type: string, minLength: 3, maxLength: 3 }
        requirements: { type: object }
        legs: { type: array, items: { type: object } }
    OperatorResponse:
      oneOf:
        - type: object
          required: [kind, aircraftType, priceState, totalAmount, currency, validUntil]
          properties:
            kind: { type: string, enum: [quote, alternative] }
            aircraftType: { type: string }
            registration: { type: string }
            manufactureYear: { type: integer }
            passengerCapacity: { type: integer }
            flightTimeMinutes: { type: integer }
            alternativeOriginIcao: { type: string, pattern: "^[A-Z0-9]{4}$" }
            alternativeDestinationIcao: { type: string, pattern: "^[A-Z0-9]{4}$" }
            alternativeDepartureLocal: { type: string, pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}$" }
            alternativeDepartureTimezone: { type: string, description: "IANA time zone paired with alternativeDepartureLocal." }
            imageUrl: { type: string, format: uri, pattern: "^https://" }
            amenities: { type: array, items: { type: string } }
            included: { type: array, items: { type: string } }
            excluded: { type: array, items: { type: string } }
            cancellationTerms: { type: string }
            priceState: { type: string, enum: [all-in, conditional, indicative] }
            availability: { type: string, enum: [operator_confirmed, confirmation_required, unavailable], default: confirmation_required }
            totalAmount: { type: number, exclusiveMinimum: 0 }
            currency: { type: string, enum: [EUR, GBP, USD] }
            validUntil: { type: string, format: date-time }
            unknownItems: { type: array, items: { type: string } }
            message: { type: string, maxLength: 2000 }
        - type: object
          required: [kind, message]
          properties:
            kind: { type: string, enum: [question, decline] }
            message: { type: string, minLength: 3, maxLength: 2000 }
