openapi: 3.1.0
info:
  title: Tango Locations Outbound API
  version: "2.0"
  description: |
    Async **delta** REST API: client GETs Property / Building / Floor /
    Location-Store records that were updated in Tango since the last
    integration run. Single endpoint returns all four entity types; an
    optional query param scopes the response.

    Records created via "conversion" are excluded. Updates to `building_id`,
    `floor_id`, and `lease_number` do NOT trigger an export — only updates
    to other fields do.

    For STORE and BUILDING records, `associated_property` carries the linked
    property information.

    Direction NOTE: source header says `Source: CLIENT SYSTEM / Destination:
    TANGO` but description is "outbound Building/Floor data from Tango to
    client's system". Treated as outbound (Tango → Client).

    Field schema NOTE: the source data-mapping table didn't extract into the
    text dump; the schema below is a thin permissive scaffold pending a
    fuller field list.
  x-direction: outbound
  x-source: Tango
  x-destination: Client System
servers:
  - url: https://api.tangoanalytics.com
    description: Production
  - url: https://testapi.tangoanalytics.com
    description: Test (SIT/UAT)
tags:
  - name: Locations (Delta)
  - name: Status
paths:
  /v1/spacemgmt/delta/buildings:
    get:
      summary: Initiate delta location export (async)
      operationId: getLocationsDelta
      tags: [Locations (Delta)]
      parameters:
        - $ref: "#/components/parameters/XClient"
        - $ref: "#/components/parameters/XApiKey"
        - in: query
          name: "Entity Type"
          required: false
          schema:
            type: string
            enum: [Buildings, Floors, Stores, Properties]
          description: |
            Optional. NOTE: source documents this param with a literal
            space — `Entity Type` — rather than snake/camel case.
            Preserved verbatim; confirm wire format (most likely a
            doc-formatting artifact, real param is probably `entity_type`).
            If omitted, all entity types with updates are returned.
      responses:
        "200":
          description: Async ack with gu_id.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AcceptedResponse"
  /v1/batch/status:
    get:
      summary: Retrieve paginated location records by gu_id
      operationId: getLocationsByGuId
      tags: [Status]
      parameters:
        - $ref: "#/components/parameters/XClient"
        - $ref: "#/components/parameters/XApiKey"
        - in: query
          name: gu_id
          required: true
          schema: { type: string, format: uuid }
        - in: query
          name: page_no
          required: false
          schema: { type: integer, minimum: 1 }
      responses:
        "200":
          description: Paginated location records.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LocationPage"
components:
  securitySchemes:
    xClientHeader: { type: apiKey, in: header, name: x-client }
    xApiKeyHeader: { type: apiKey, in: header, name: x-api-key }
  parameters:
    XClient:
      name: x-client
      in: header
      required: true
      schema: { type: string }
    XApiKey:
      name: x-api-key
      in: header
      required: true
      schema: { type: string }
  schemas:
    AcceptedResponse:
      type: object
      required: [status]
      properties:
        status: { type: string, enum: [OK, Error] }
        status_message: { type: string }
        gu_id: { type: string, format: uuid }
    LocationPage:
      type: object
      required: [status, records]
      properties:
        status: { type: string, enum: [PROCESSING, COMPLETED, ERROR] }
        total_records: { type: integer }
        total_pages: { type: integer }
        page_size: { type: integer, default: 5000 }
        page_no: { type: integer }
        records:
          type: array
          items:
            $ref: "#/components/schemas/LocationRecord"
    LocationRecord:
      type: object
      description: |
        Permissive schema — the source data-mapping table didn't surface
        in the text extraction. Records can be Buildings, Floors,
        Properties, or Stores; entity-type-specific fields (building_id,
        floor_id, store_number, property_number, etc.) are accepted via
        additionalProperties pending a fuller schema.
      additionalProperties: true
      properties:
        building_id: { type: number }
        floor_id: { type: number }
        store_number: { type: string }
        property_number: { type: string }
        associated_property:
          type: object
          description: |
            Linked property information for STORE and BUILDING records.
          additionalProperties: true
        lease_number: { type: string }
        store_size: { type: number }
        last_updated_date: { type: string, description: "TIMESTAMP." }
security:
  - xClientHeader: []
    xApiKeyHeader: []
