openapi: 3.1.0
info:
  title: Popcast Ambient API
  version: 0.1.0
  description: |
    Ambient layer of The Conscience Stack. Current-moment per-FIPS
    environmental context: weather (NOAA), air quality (PurpleAir),
    daylight, mobility (Motionworks digital-twin — currently stubbed),
    calendar context. Refreshed hourly.
  contact:
    name: Motionworks AI
    url: https://docs.mworks.com
servers:
  - url: https://api.mworks.com
tags:
  - name: ambient
    description: Block group ambient signal endpoints
paths: {}
components:
  parameters:
    FipsParam:
      name: fips
      in: path
      required: true
      schema:
        type: string
        pattern: ^\d{12}$
  schemas:
    WeatherForecastDay:
      type: object
      properties:
        date:
          type: string
        high_f:
          type: number
        low_f:
          type: number
        condition:
          type: string
          enum:
            - clear
            - partly-cloudy
            - cloudy
            - rain
            - thunderstorm
            - snow
            - fog
            - windy
            - haze
            - unknown
        precipitation_chance_pct:
          type: number
    WeatherSnapshot:
      type: object
      properties:
        current_temp_f:
          type: number
        condition:
          type: string
        humidity_pct:
          type: number
        wind_mph:
          type: number
        forecast:
          type: array
          items:
            $ref: '#/components/schemas/WeatherForecastDay'
        source:
          type: string
    AirQualitySnapshot:
      type: object
      properties:
        aqi:
          type: integer
        category:
          type: string
          enum:
            - good
            - moderate
            - unhealthy-sensitive
            - unhealthy
            - very-unhealthy
            - hazardous
        pm25_ugm3:
          type: number
          nullable: true
        pm10_ugm3:
          type: number
          nullable: true
        dominant_pollutant:
          type: string
          nullable: true
        source:
          type: string
    DaylightSnapshot:
      type: object
      properties:
        date:
          type: string
        sunrise_local:
          type: string
        sunset_local:
          type: string
        solar_noon_local:
          type: string
        daylight_minutes:
          type: integer
        timezone:
          type: string
    MobilitySnapshot:
      type: object
      description: |
        Motionworks digital-twin snapshot. Indexes are 0-500 where 100
        equals the block group's own historical mean. `source` prefixes
        `motionworks-digital-twin-stub` until the real adapter lands.
      properties:
        pedestrian_index:
          type: number
        vehicular_index:
          type: number
        dwell_index:
          type: number
        inbound_flow_index:
          type: number
        outbound_flow_index:
          type: number
        sample_size:
          type: integer
        source:
          type: string
    CalendarContext:
      type: object
      properties:
        is_federal_holiday:
          type: boolean
        federal_holiday_name:
          type: string
          nullable: true
        is_school_day:
          type: boolean
        school_district_name:
          type: string
          nullable: true
        is_weekend:
          type: boolean
        day_of_week:
          type: string
          enum:
            - mon
            - tue
            - wed
            - thu
            - fri
            - sat
            - sun
    AmbientPayload:
      type: object
      properties:
        weather:
          $ref: '#/components/schemas/WeatherSnapshot'
        air_quality:
          $ref: '#/components/schemas/AirQualitySnapshot'
        daylight:
          $ref: '#/components/schemas/DaylightSnapshot'
        mobility:
          $ref: '#/components/schemas/MobilitySnapshot'
        calendar:
          $ref: '#/components/schemas/CalendarContext'
    AmbientSignal:
      type: object
      required:
        - fips
        - signal_layer
        - period_end
        - refreshed_at
        - payload
      properties:
        fips:
          type: string
        signal_layer:
          type: string
          enum:
            - ambient
        period_end:
          type: string
        refreshed_at:
          type: string
          format: date-time
        data_quality:
          type: string
          enum:
            - high
            - medium
            - low
        source_breakdown:
          type: object
          additionalProperties:
            type: integer
        payload:
          $ref: '#/components/schemas/AmbientPayload'
    Meta:
      type: object
      properties:
        request_id:
          type: string
        credits_used:
          type: integer
        product:
          type: string
        version:
          type: string
    AmbientSignalResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/AmbientSignal'
        meta:
          $ref: '#/components/schemas/Meta'
    AmbientHistorySnapshot:
      type: object
      properties:
        fips:
          type: string
        period_start:
          type: string
        period_end:
          type: string
        window_days:
          type: integer
        avg_temp_f:
          type: number
        avg_aqi:
          type: integer
        rainy_days:
          type: integer
        avg_pedestrian_index:
          type: number
        avg_vehicular_index:
          type: number
        data_quality:
          type: string
    AmbientHistoryResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AmbientHistorySnapshot'
        pagination:
          type: object
          properties:
            cursor:
              type: string
              nullable: true
            has_more:
              type: boolean
            total:
              type: integer
        meta:
          $ref: '#/components/schemas/Meta'
    AmbientBatchRequest:
      type: object
      required:
        - fips_codes
      properties:
        fips_codes:
          type: array
          maxItems: 100
          items:
            type: string
            pattern: ^\d{12}$
    AmbientBatchResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/AmbientSignal'
        meta:
          $ref: '#/components/schemas/Meta'
    ApiError:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            status:
              type: integer
            request_id:
              type: string
  responses:
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    ValidationError:
      description: Validation error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
