openapi: 3.1.0
info:
  title: ScreamUp Public Aggregate Emotional Intelligence API
  version: 1.0.0
  summary: Privacy-preserving H3 resolution 7 emotional hotspot aggregation API.
  description: |
    Authoritative OpenAPI 3.1 specification for the ScreamUp Public & Corporate Aggregate API (`/v1`).
    - Zero consumer accounts or identity tracking
    - Zero raw audio or transcript storage
    - Zero exact coordinate storage (transient H3 resolution 7 conversion only)
    - Strict k-anonymity (`k >= 5` qualifying completed screams in the active time window)
servers:
  - url: https://screamup-api.shared-backend.workers.dev
    description: Cloudflare Workers Development & Sandbox API
paths:
  /health:
    get:
      operationId: getSystemHealth
      summary: Check API service health and version
      responses:
        '200':
          description: Service is healthy
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HealthResponse'
  /v1/hotspots:
    get:
      operationId: listQualifyingHotspots
      summary: Query qualifying H3 resolution 7 emotional hotspots (k >= 5)
      parameters:
        - name: time_window
          in: query
          schema:
            type: string
            enum: ['1h', '6h', '24h', '7d']
            default: '1h'
        - name: min_lat
          in: query
          schema:
            type: number
        - name: max_lat
          in: query
          schema:
            type: number
        - name: min_lng
          in: query
          schema:
            type: number
        - name: max_lng
          in: query
          schema:
            type: number
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 500
            default: 100
      responses:
        '200':
          description: Qualifying H3 resolution 7 hotspot cells
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotspotListResponse'
        '400':
          description: Invalid time_window or viewport bounds
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
  /v1/geo/hotspots:
    get:
      operationId: listQualifyingGeoHotspotsAlias
      summary: Alias for GET /v1/hotspots
      responses:
        '200':
          description: Qualifying H3 resolution 7 hotspot cells
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HotspotListResponse'
components:
  securitySchemes:
    CorporateApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_live_su_<token>
  schemas:
    HealthResponse:
      type: object
      required: [status, service, version]
      properties:
        status: { type: string, enum: [HEALTHY] }
        service: { type: string, enum: [screamup-api] }
        version: { type: string }
    GeoPoint:
      type: object
      required: [latitude, longitude]
      properties:
        latitude: { type: number }
        longitude: { type: number }
    Hotspot:
      type: object
      required:
        - h3_index
        - center
        - polygon
        - event_count
        - scream_count
        - average_frustration
        - average_intensity
        - average_confidence
        - dominant_category
        - time_window
        - updated_epoch_ms
        - hotspot_score
      properties:
        h3_index: { type: string }
        center: { $ref: '#/components/schemas/GeoPoint' }
        polygon:
          type: array
          items: { $ref: '#/components/schemas/GeoPoint' }
        event_count: { type: integer, minimum: 5 }
        scream_count: { type: integer, minimum: 5 }
        average_frustration: { type: integer, minimum: 0, maximum: 100 }
        average_intensity: { type: integer, minimum: 0, maximum: 100 }
        average_confidence: { type: integer, minimum: 0, maximum: 100 }
        dominant_category: { type: string }
        time_window: { type: string, enum: ['1h', '6h', '24h', '7d'] }
        updated_epoch_ms: { type: integer }
        hotspot_score: { type: [integer, 'null'] }
    HotspotListResponse:
      type: object
      required:
        - time_window
        - time_window_start_ms
        - time_window_end_ms
        - total_qualifying_cells
        - hotspots
      properties:
        time_window: { type: string }
        time_window_start_ms: { type: integer }
        time_window_end_ms: { type: integer }
        total_qualifying_cells: { type: integer }
        hotspots:
          type: array
          items: { $ref: '#/components/schemas/Hotspot' }
    ApiError:
      type: object
      required: [code, message, request_id, error]
      properties:
        code: { type: string }
        message: { type: string }
        request_id: { type: string }
        error:
          type: object
          required: [code, message, request_id]
          properties:
            code: { type: string }
            message: { type: string }
            request_id: { type: string }
