openapi: '3.1.0'
info:
  title: Motionworks API - Places Library
  version: 2.0.0
  description: >
    Canonical place-metadata reference shared across all Motionworks products.
    Every place_id referenced by Viewcast, Placecast, or Pathcast resolves to
    a Place record here.
  contact:
    name: Motionworks AI
    url: https://mworks.com
    email: api@mworks.com

servers:
  - url: https://api.mworks.com/v2
    description: Production

security:
  - apiKey: []

components:
  securitySchemes:
    apiKey:
      type: apiKey
      name: X-API-Key
      in: header

  schemas:
    Place:
      type: object
      x-motionworks-status: production
      x-motionworks-source: places-library
      x-motionworks-source-doc: https://docs.mworks.com/docs/places
      properties:
        place_id:
          type: integer
        name:
          type: string
        short_name:
          type: string
          nullable: true
        place_type_id:
          type: integer
        place_type:
          type: string
        is_focused:
          type: boolean
          description: >
            When true, the place has direct measurements. When false, metrics
            are estimated from peer-group places (the "unfocused" methodology).
        parent_place_id:
          type: integer
          nullable: true
        audit_status_id:
          type: integer
          enum: [1, 2, 3, 4, 5, 7, 9, 12, 67]
        audit_status:
          type: string
          enum:
            - Requested
            - Started
            - Requires Review
            - Reviewed
            - Certified
            - Closed
            - Approximate
            - Published - Third Party
            - Geofence Only
        co_geoid:
          type: string
          description: County GEOID
        co_name:
          type: string
        st_usps:
          type: string
          minLength: 2
          maxLength: 2
          description: Two-letter state postal code
        st_name:
          type: string
        cbsa_geoid:
          type: string
        cbsa_name:
          type: string
        cbsa_type:
          type: string
          enum: [cbsa_metro, cbsa_micro]
        dma_geoid:
          type: string
        dma_name:
          type: string
        su:
          type: string
          description: Sunday hours (HHMM-HHMM) or empty if closed
        mo:
          type: string
        tu:
          type: string
        we:
          type: string
        th:
          type: string
        fr:
          type: string
        sa:
          type: string
        su_hours:
          type: number
        mo_hours:
          type: number
        tu_hours:
          type: number
        we_hours:
          type: number
        th_hours:
          type: number
        fr_hours:
          type: number
        sa_hours:
          type: number
        no_entrances:
          type: integer
          nullable: true
        no_floors:
          type: integer
          nullable: true
        no_concourses:
          type: integer
          nullable: true
          description: Transit-station-specific
        no_platforms:
          type: integer
          nullable: true
          description: Transit-station-specific
        no_gates:
          type: integer
          nullable: true
          description: Airport-specific
        collection_sqft:
          type: number
          nullable: true
        building_sqft:
          type: number
          nullable: true
        timezone:
          type: string
          description: IANA time zone (e.g. America/New_York)
        lat:
          type: number
          format: double
        lon:
          type: number
          format: double
        geography:
          type: string
          description: Place polygon as WKT
        modified:
          type: string
          description: ISO-ish timestamp when the place metadata was last modified

    Pagination:
      type: object
      properties:
        cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
        total:
          type: integer

    Provenance:
      type: object
      description: Response-level provenance (see TF-93).
      properties:
        source:
          type: string
        source_doc:
          type: string
          format: uri
        methodology_version:
          type: string
        data_vintage:
          type: string
          format: date
        data_freshness:
          type: string
          enum: [hourly, daily, weekly, monthly, annually, on-demand]
        data_latency_days:
          type: integer
        data_maturity:
          type: string
          enum: [production, research-preview, synthetic-only, roadmap]
        is_focused:
          type: boolean

    Meta:
      type: object
      properties:
        request_id:
          type: string
        credits_used:
          type: integer
        credits_remaining:
          type: integer
        product:
          type: string
        version:
          type: string
        provenance:
          $ref: '#/components/schemas/Provenance'

    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            status:
              type: integer
            request_id:
              type: string
            product:
              type: string
            docs_url:
              type: string

paths:
  /places/{place_id}:
    get:
      operationId: getPlace
      summary: Get a single place by ID
      x-credit-cost: 1
      x-motionworks-status: production
      x-motionworks-source-doc: https://docs.mworks.com/docs/places
      parameters:
        - name: place_id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Place record
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Place'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Place not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded

  /places:
    get:
      operationId: searchPlaces
      summary: Search places by type / geography / parent / focus status
      x-credit-cost: 5
      x-motionworks-status: production
      x-motionworks-source-doc: https://docs.mworks.com/docs/places
      parameters:
        - name: search
          in: query
          description: Free-text search on name
          schema:
            type: string
        - name: place_type
          in: query
          schema:
            type: string
          description: e.g. "Shopping Mall", "Coffee Shop", "Transit Station"
        - name: place_type_id
          in: query
          schema:
            type: integer
        - name: city
          in: query
          schema:
            type: string
        - name: state
          in: query
          schema:
            type: string
            minLength: 2
            maxLength: 2
        - name: dma_geoid
          in: query
          schema:
            type: string
        - name: cbsa_geoid
          in: query
          schema:
            type: string
        - name: parent_place_id
          in: query
          schema:
            type: integer
        - name: is_focused
          in: query
          schema:
            type: boolean
        - name: audit_status_id
          in: query
          schema:
            type: integer
            enum: [1, 2, 3, 4, 5, 7, 9, 12, 67]
        - name: bbox
          in: query
          schema:
            type: string
          description: 'sw_lat,sw_lng,ne_lat,ne_lng'
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
      responses:
        '200':
          description: Paginated place records
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Place'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
