openapi: 3.1.0
info:
  title: Set Dynamics (Campaign Reach & Frequency)
  version: 2.0.0
  description: |
    On-demand reach and frequency analysis for out-of-home campaigns. A scenario declares a set of Geopath spots, a period (Monday-start, Sunday-end), a cohort (segment × geography), a measurement type (visits / circulation / OTS / LTS), and one or more durations (7, 14, 21, or 28 days). Response is reach percentages at each effective-frequency threshold per duration. 90% CI on reach. Source: https://docs.mworks.com/docs/set-dynamics
            https://docs.mworks.com/docs/set-dynamics-requests
            https://docs.mworks.com/docs/set-dynamics-responses
  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:
    SetDynamicsType:
      type: string
      enum:
        - visits_freq_per_period
        - circ_freq_per_period
        - ots_freq_per_period
        - lts_freq_per_period
      description: |
        Hierarchy: visits → circulation → OTS → LTS, each adding realism. `lts_freq_per_period` is the most customer-facing measure.
    Duration:
      type: integer
      enum:
        - 7
        - 14
        - 21
        - 28
      description: Days. Must be a multiple of 7.
    SetDynamicsPeriod:
      type: object
      required:
        - name
        - start_date
        - end_date
      properties:
        name:
          type: string
        start_date:
          type: string
          format: date
          description: Must be a Monday (server may snap if client sends mid-week).
        end_date:
          type: string
          format: date
          description: Must be a Sunday.
    SetDynamicsCustomer:
      type: object
      required:
        - customer_id
        - customer_name
        - customer_scenario_id
        - customer_scenario_name
      properties:
        customer_id:
          type: integer
        customer_name:
          type: string
        customer_scenario_id:
          type: string
        customer_scenario_name:
          type: string
        customer_scenario_info:
          type: string
          description: Free-form notes / contact info stored as a string.
    SetDynamicsCohort:
      type: object
      required:
        - customer_segment_id
        - customer_base_segment_id
        - geography_ids
        - measuresRelease
      properties:
        customer_segment_id:
          type: integer
        customer_base_segment_id:
          type: integer
        geography_ids:
          type: array
          minItems: 1
          items:
            type: string
          description: |
            `["GLOBAL"]` for national, `["US2020XDMA532"]` for a DMA, or a county-list like `["US2020STCO36061", "US2020STCO34003"]`.
        measuresRelease:
          type: integer
    SetDynamicsRequest:
      type: object
      x-motionworks-status: production
      x-motionworks-source: set-dynamics
      x-motionworks-source-doc: https://docs.mworks.com/docs/set-dynamics-requests
      required:
        - scenarioId
        - name
        - periods
        - customer
        - cohort
        - geopath_spot_list
      properties:
        scenarioId:
          type: string
          description: Server-side scenario identifier.
        name:
          type: string
        description:
          type: string
        periods:
          $ref: '#/components/schemas/SetDynamicsPeriod'
        customer:
          $ref: '#/components/schemas/SetDynamicsCustomer'
        type_list:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/SetDynamicsType'
          default:
            - visits_freq_per_period
        cohort:
          $ref: '#/components/schemas/SetDynamicsCohort'
        effective_freq_list:
          type: array
          minItems: 1
          items:
            type: integer
            minimum: 1
          default:
            - 1
            - 2
            - 3
            - 4
            - 5
            - 6
            - 7
            - 8
            - 9
            - 10
            - 11
            - 20
            - 50
            - 100
        duration_list:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/Duration'
          default:
            - 28
        geopath_spot_list:
          type: array
          minItems: 1
          items:
            type: string
    SetDynamicsFrequencyResult:
      type: object
      required:
        - effective_freq
      properties:
        effective_freq:
          type: string
          description: Frequency threshold (string-encoded per docs).
        lts_reach:
          type: number
          minimum: 0
          maximum: 1
        ots_reach:
          type: number
          minimum: 0
          maximum: 1
        circ_reach:
          type: number
          minimum: 0
          maximum: 1
        visits_reach:
          type: number
          minimum: 0
          maximum: 1
    SetDynamicsDurationResult:
      type: object
      required:
        - duration
        - effective_freq_list
      properties:
        duration:
          type: string
        effective_freq_list:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/SetDynamicsFrequencyResult'
    SetDynamicsResponse:
      type: object
      x-motionworks-status: production
      x-motionworks-source: set-dynamics
      x-motionworks-source-doc: https://docs.mworks.com/docs/set-dynamics-responses
      required:
        - customer
        - cohort
        - effective_reach_per_duration
        - messages
      properties:
        customer:
          $ref: '#/components/schemas/SetDynamicsCustomer'
        cohort:
          $ref: '#/components/schemas/SetDynamicsCohort'
        effective_reach_per_duration:
          type: array
          items:
            $ref: '#/components/schemas/SetDynamicsDurationResult'
        messages:
          type: string
    SetDynamicsScenario:
      type: object
      description: The API's scenario entity. Combines request + status + result.
      properties:
        scenarioId:
          type: string
        name:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
            - queued
            - processing
            - complete
            - failed
        periods:
          $ref: '#/components/schemas/SetDynamicsPeriod'
        customer:
          $ref: '#/components/schemas/SetDynamicsCustomer'
        type_list:
          type: array
          items:
            $ref: '#/components/schemas/SetDynamicsType'
        cohort:
          $ref: '#/components/schemas/SetDynamicsCohort'
        effective_freq_list:
          type: array
          items:
            type: integer
        duration_list:
          type: array
          items:
            $ref: '#/components/schemas/Duration'
        geopath_spot_list:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true
        result:
          oneOf:
            - $ref: '#/components/schemas/SetDynamicsResponse'
            - type: 'null'
        error:
          type: string
          nullable: true
    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
          enum:
            - hourly
            - daily
            - weekly
            - monthly
            - annually
            - on-demand
            - static
        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
            product:
              type: string
            docs_url:
              type: string
paths:
  /set-dynamics/scenarios:
    post:
      operationId: createSetDynamicsScenario
      summary: Submit a new Set Dynamics scenario for analysis
      description: |
        Submitting a scenario queues an asynchronous analysis. Typical turnaround is 24–48 hours. Response returns the queued scenario with `status: "queued"`; poll `GET /scenarios/{id}` until `status` is `complete` or `failed`.
      x-credit-cost: 25
      x-motionworks-status: production
      x-motionworks-source-doc: https://docs.mworks.com/docs/set-dynamics-requests
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetDynamicsRequest'
      responses:
        '202':
          description: Scenario accepted and queued for processing.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/SetDynamicsScenario'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '400':
          description: Invalid scenario (bad period dates, durations, geography, etc.)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    get:
      operationId: listSetDynamicsScenarios
      summary: List Set Dynamics scenarios
      x-credit-cost: 1
      x-motionworks-status: production
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum:
              - queued
              - processing
              - complete
              - failed
        - name: customer_scenario_id
          in: query
          schema:
            type: string
        - name: cursor
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
      responses:
        '200':
          description: Paginated scenarios
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/SetDynamicsScenario'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
                  meta:
                    $ref: '#/components/schemas/Meta'
  /set-dynamics/scenarios/{scenario_id}:
    get:
      operationId: getSetDynamicsScenario
      summary: Retrieve a Set Dynamics scenario (polling endpoint)
      x-credit-cost: 1
      x-motionworks-status: production
      x-motionworks-source-doc: https://docs.mworks.com/docs/set-dynamics-responses
      parameters:
        - name: scenario_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Scenario detail, including result when status is complete
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/SetDynamicsScenario'
                  meta:
                    $ref: '#/components/schemas/Meta'
        '404':
          description: Scenario not found
