openapi: 3.1.0
info:
  title: Pricing Distribution Service API
  version: 0.1.0
  summary: First-pass partner onboarding contract for Pricing Distribution Service.
  description: |
    Pricing Distribution Service (PDS) is a facade over the Novasol partner API.

    This first-pass OpenAPI document focuses on the HTTP contract exposed by PDS:
    paths, methods, headers, query parameters, form bodies, status codes, and
    representative XML or JSON payload examples.

    Notes:
    - Several endpoints proxy or forward partner-specific query parameters to the upstream Novasol API.
      Where PDS does not validate those parameters locally, this document lists the common fields used for onboarding
      and calls out passthrough behavior in descriptions.
    - The batch products payload downloaded from GET /api/batches/{batchID} is defined by the XML schema in
      internal/batch/test/batchfile.xsd. OpenAPI documents the transport; the XSD remains the authoritative schema
      for the batch XML file structure.
servers:
  - url: https://pds-api.pricing.awaze.com
    description: Production
  - url: https://pds-api.ppe.pricing.awaze.com
    description: PPE
tags:
  - name: Availability
  - name: Batches
  - name: Bookings
security:
  - ApiKeyHeader: []
paths:
  /api/available/{propertyID}:
    get:
      tags:
        - Availability
      summary: Fetch uplifted availability for a property
      description: |
        Retrieves availability from the upstream partner API, applies the configured OTA uplift,
        and returns XML.

        PDS forwards the raw query string upstream. This document lists only the commonly used
        parameters for onboarding. Additional upstream-supported query parameters may also be accepted.
      parameters:
        - name: propertyID
          in: path
          required: true
          schema:
            type: string
        - name: agency
          in: query
          required: false
          schema:
            type: string
          description: Agency identifier forwarded upstream.
        - name: arrival
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: departure
          in: query
          required: false
          schema:
            type: string
            format: date
        - name: adults
          in: query
          required: false
          schema:
            type: integer
        - name: children
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Availability XML with uplifted prices.
          headers:
            X-Response-Time:
              schema:
                type: string
            X-Response-Time-Ms:
              schema:
                type: string
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
              example: |
                <?xml version="1.0" encoding="UTF-8"?>
                <available>
                  <property>
                    <propertyid>A12345</propertyid>
                    <arrival>2026-07-12</arrival>
                    <departure>2026-07-19</departure>
                    <available>true</available>
                    <price>1450</price>
                    <bookingprice>1450</bookingprice>
                    <currency>EUR</currency>
                  </property>
                </available>
        '400':
          description: Missing property ID, missing key header, or uplift not enabled.
          content:
            text/plain:
              schema:
                type: string
        '500':
          description: Internal error.
          content:
            text/plain:
              schema:
                type: string

  /api/batches:
    post:
      tags:
        - Batches
      summary: Request a batch export
      description: |
        Creates a full or delta batch export request. The request body is form URL encoded.

        Notes:
        - replyTo is required.
        - lastchange is optional. When supplied, the request is treated as a delta batch.
        - PDS also accepts replyto and Replyto for compatibility, but replyTo should be used for new integrations.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - replyTo
              properties:
                replyTo:
                  type: string
                  format: uri
                  description: Callback URL for batch-ready notifications.
                lastchange:
                  type: string
                  format: date-time
                  description: Optional timestamp for delta batches.
            examples:
              full:
                value:
                  replyTo: https://partner.example.com/pds/batch-ready
              delta:
                value:
                  replyTo: https://partner.example.com/pds/batch-ready
                  lastchange: '2026-03-18T23:00:00Z'
      responses:
        '200':
          description: Batch request accepted.
          headers:
            X-Response-Time:
              schema:
                type: string
            X-Response-Time-Ms:
              schema:
                type: string
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
              example: |
                <?xml version="1.0" encoding="UTF-8"?>
                <response>
                  <batchId>123456789</batchId>
                </response>
        '400':
          description: Invalid request body, missing key header, or uplift not enabled.
        '500':
          description: Internal error.

  /api/batches/{batchID}:
    get:
      tags:
        - Batches
      summary: Download an uplifted batch file
      description: |
        Returns the processed batch payload stored by PDS.

        The transport is documented here; the XML structure inside the batch file is defined by
        internal/batch/test/batchfile.xsd.
      security: []
      parameters:
        - name: batchID
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Zipped batch file or an XML error payload when the batch cannot be located.
          headers:
            X-Response-Time:
              schema:
                type: string
            X-Response-Time-Ms:
              schema:
                type: string
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
              example: |
                <?xml version="1.0"?>
                <error>Zipped batch file couldn't be located!</error>
      x-batch-file-schema-path: internal/batch/test/batchfile.xsd
      x-batch-file-example-path: batch-example.xml

  /api/bookings:
    post:
      tags:
        - Bookings
      summary: Create a booking
      description: |
        Creates a booking via the upstream partner API.

        The body is form URL encoded. PDS validates a subset of fields locally and then applies
        uplift logic before forwarding upstream.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              additionalProperties:
                type: string
              required:
                - propertyid
                - arrival
                - departure
                - price
              properties:
                propertyid:
                  type: string
                arrival:
                  type: string
                  format: date
                departure:
                  type: string
                  format: date
                price:
                  type: integer
                agency:
                  type: integer
                company:
                  type: string
                salesmarket:
                  type: integer
                adults:
                  type: integer
                children:
                  type: integer
                firstname:
                  type: string
                lastname:
                  type: string
                email:
                  type: string
                  format: email
                phone:
                  type: string
                test:
                  type: boolean
            example:
              propertyid: A12345
              arrival: '2026-07-12'
              departure: '2026-07-19'
              price: 1450
              agency: 1234
              company: AWAZE
              salesmarket: 44
              adults: 2
              children: 1
              firstname: Jane
              lastname: Doe
              email: jane@example.com
              phone: '+441234567890'
      responses:
        '200':
          description: Booking created successfully.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
              example: |
                <?xml version="1.0" encoding="UTF-8"?>
                <response>
                  <bookingNumber>987654321</bookingNumber>
                </response>
        '400':
          description: Invalid request payload.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
              example: |
                <?xml version="1.0" encoding="UTF-8"?><error code="400">Error</error>
        '401':
          description: API key missing or partner not enabled for uplift.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
        '500':
          description: Internal error.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'

  /api/bookings/{bookingID}:
    put:
      tags:
        - Bookings
      summary: Acknowledge an existing booking
      description: Forwards the request to the upstream partner API and streams the XML response back unchanged.
      parameters:
        - name: bookingID
          in: path
          required: true
          schema:
            type: string
        - name: action
          in: query
          required: true
          schema:
            type: string
            enum:
              - acknowledge
      responses:
        '200':
          description: Upstream acknowledgement response.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
        '400':
          description: Missing booking ID or invalid request.
        '500':
          description: Internal error.

    delete:
      tags:
        - Bookings
      summary: Delete an existing booking
      description: Forwards the request to the upstream partner API and streams the XML response back unchanged.
      parameters:
        - name: bookingID
          in: path
          required: true
          schema:
            type: string
        - name: company
          in: query
          required: false
          schema:
            type: string
        - name: salesmarket
          in: query
          required: false
          schema:
            type: integer
        - name: agency
          in: query
          required: false
          schema:
            type: integer
        - name: propertyid
          in: query
          required: false
          schema:
            type: string
        - name: user
          in: query
          required: false
          schema:
            type: string
        - name: test
          in: query
          required: false
          schema:
            type: boolean
      responses:
        '200':
          description: Upstream delete response.
          content:
            application/xml:
              schema:
                $ref: '#/components/schemas/XmlString'
        '400':
          description: Invalid request.
        '500':
          description: Internal error.

components:
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: key
      description: API key header required by partner-facing PDS endpoints.
  schemas:
    HealthResponse:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          example: ok
    XmlString:
      type: string
      description: Raw XML payload.
    StatusResponse:
      type: object
      required:
        - status
      properties:
        status:
          type: string
          example: ok
    UpliftRequest:
      type: object
      required:
        - otaId
        - upliftPercentage
        - inUse
      properties:
        otaId:
          type: string
        upliftPercentage:
          type: number
          format: float
        inUse:
          type: string
          enum:
            - pending
            - active
    UpliftResponse:
      type: object
      required:
        - otaId
        - upliftPercentage
      properties:
        otaId:
          type: string
        upliftPercentage:
          type: number
          format: float