openapi: 3.1.0
info:
  title: Viewcast (Inventory Profiles)
  version: 2.0.0
  description: |
    Face-level and spot-level OOH measurement data including circulation, opportunity-to-see (OTS), likelihood-to-see (LTS), and audience reach at effective-frequency thresholds.
    Key corrections from the v2 scaffold:
      - media_type is size-based (Display/Panel/Junior Poster/Poster/Bulletin/Murals)
      - classification_type is 2-value (Roadside | Place-Based)
      - Reach is 4 variants: total/market x eff1/eff3 — not a single reach_pct
      - Both face-level and spot-level measurements exposed
      - viewcast_score removed (roadmap TF-90)

    Invariant: LTS <= OTS <= Circulation <= Traffic (at both face and spot level)
  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:
    ViewcastMarket:
      type: object
      properties:
        co_geoid:
          type: string
        co_name:
          type: string
        st_name:
          type: string
        cbsa_geoid:
          type: string
        cbsa_name:
          type: string
        cbsa_type:
          type: string
        dma_geoid:
          type: string
        dma_name:
          type: string
        postal_code:
          type: string
    FaceMeasurements:
      type: object
      x-motionworks-status: production
      description: |
        Aggregated across all spots on the face. LTS <= OTS <= face_circ <= traffic.
      properties:
        traffic:
          type: integer
          description: Weekly average vehicles + pedestrians in the viewshed.
        face_circ:
          type: integer
          description: Weekly average circulation (persons) to the face.
        face_ots:
          type: integer
          description: Weekly average OTS impressions for the face.
        face_lts:
          type: integer
          description: Weekly average LTS impressions (OTS x Geopath VAI).
        face_share_of_voice:
          type: number
          minimum: 0
          maximum: 1
        dwell:
          type: number
          description: Circulation-weighted dwell in minutes within the viewshed.
    SpotMeasurements:
      type: object
      x-motionworks-status: production
      description: |
        Weighted by share_of_voice and spot_length for digital displays. For static (SoV=1.0), equals face measurements. spot_lts <= spot_ots <= spot_circ.
      properties:
        spot_circ:
          type: integer
        spot_ots:
          type: integer
        spot_lts:
          type: integer
        share_of_voice:
          type: number
          minimum: 0
          maximum: 1
          description: Fraction of time this spot is visible on the face.
        spot_length:
          type: integer
          description: Spot duration in seconds (digital only).
    ViewcastReach:
      type: object
      x-motionworks-status: production
      description: |
        4 reach variants: total-US and DMA-market populations, each at effective frequency 1+ and 3+.
      properties:
        total_population:
          type: integer
        market_population:
          type: integer
        total_reach_eff1:
          type: integer
          description: Total US population reached at least once.
        market_reach_eff1:
          type: integer
        total_reach_eff3:
          type: integer
          description: Total US population reached at least 3 times.
        market_reach_eff3:
          type: integer
    ViewcastProfile:
      type: object
      x-motionworks-status: production
      x-motionworks-source: viewcast-profiles
      x-motionworks-source-doc: https://docs.mworks.com/docs/viewcast-profiles
      properties:
        place_id:
          type: integer
        spot_id:
          type: integer
        geopath_spot_id:
          type: integer
        geopath_frame_id:
          type: integer
        location:
          type: string
          description: WKT POINT of the face.
        market:
          $ref: '#/components/schemas/ViewcastMarket'
        construction_type:
          type: string
          enum:
            - Freestanding
            - Interior Wall
            - Furniture
            - Exterior Wall
            - Bus Exterior
            - Exterior Vehicle
            - Ceiling
            - Floor
            - Column
            - Elevator
            - Stairs
            - Furniture - Top
            - Interior Vehicle
            - Tablet
            - Rooftop
        classification_type:
          type: string
          enum:
            - Roadside
            - Place-Based
          description: Replaces the invented 4-value media_class from the v2 scaffold.
        media_type:
          type: string
          enum:
            - Display
            - Panel
            - Junior Poster
            - Poster
            - Bulletin
            - Murals
          description: Size-based display classification. Replaces the scaffold's 4-value enum.
        digital:
          type: boolean
        face_orientation:
          type: number
          description: Display orientation in degrees (0=N, 180=S).
        face_height:
          type: number
          description: Display height in inches.
        face_width:
          type: number
          description: Display width in inches.
        viewable_distance:
          type: number
          description: Maximum viewable distance in feet.
        face_audit_status:
          type: integer
        period_start:
          type: string
          format: date
        period_end:
          type: string
          format: date
        period_days:
          type: integer
        face:
          $ref: '#/components/schemas/FaceMeasurements'
        spot:
          $ref: '#/components/schemas/SpotMeasurements'
        reach:
          $ref: '#/components/schemas/ViewcastReach'
        assignment_status:
          type: string
          enum:
            - Industry Assigned
            - System Assigned
            - Motionworks Assigned
            - Unverified Assignments
    Pagination:
      type: object
      properties:
        cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
        total:
          type: integer
    Provenance:
      type: object
      properties:
        source:
          type: string
        source_doc:
          type: string
          format: uri
        methodology_version:
          type: string
        data_vintage:
          type: string
          format: date
        data_freshness:
          type: string
        data_latency_days:
          type: integer
        data_maturity:
          type: string
          enum:
            - production
            - research-preview
            - synthetic-only
            - roadmap
    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
            docs_url:
              type: string
paths:
  /profiles/{place_id}:
    get:
      operationId: getViewcastProfile
      summary: Get a single Viewcast profile (face + spot measurements)
      x-credit-cost: 300
      x-motionworks-status: production
      x-motionworks-source-doc: https://docs.mworks.com/docs/viewcast-profiles
      parameters:
        - name: place_id
          in: path
          required: true
          schema:
            type: integer
        - name: fields
          in: query
          schema:
            type: string
          description: Comma-separated field names to project.
        - name: include
          in: query
          schema:
            type: string
          description: 'Additional data: geopath, demographics, history'
      responses:
        '200':
          description: ViewcastProfile
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ViewcastProfile'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '404':
          description: Profile not found
