openapi: 3.0.3
info:
  title: DisasterAWARE V2 API
  description: |
    The DisasterAWARE V2 API provides access to real-time and historical hazard
    data, alert geographies, hazard metadata, and associated products from the
    DisasterAWARE Enterprise platform.

    ## Authentication

    All endpoints except `/authorize` require a JWT Bearer token. Obtain a token
    by calling `POST /authorize` with valid credentials. Access tokens expire
    after **15 minutes**. Use the returned `refreshToken` to obtain a new access
    token when needed.
  version: "2.0"
  contact:
    name: DisasterAWARE Enterprise
    url: https://disasteraware.com

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

security:
  - bearerAuth: []

tags:
  - name: Authentication
    description: Obtain and manage JWT access tokens.
  - name: Active Hazards
    description: Query currently active hazard events.
  - name: OSINT Hazards
    description: |
      Query active hazard events detected from open-source intelligence. Access
      requires a specific role on your credentials.
  - name: Historical Hazards
    description: Query historical hazard records and counts.
  - name: Hazard Metadata
    description: Reference data for hazard types, severities, categories, and alert geography.
  - name: Products
    description: Documents, maps, and other products associated with hazards.

paths:
  /authorize:
    post:
      operationId: authorize
      tags:
        - Authentication
      summary: Obtain a JWT access token
      description: |
        Authenticate with username and password to receive a short-lived JWT
        access token (15-minute expiry) and a refresh token.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - username
                - password
              properties:
                username:
                  type: string
                  example: "user@example.com"
                password:
                  type: string
                  format: password
                  example: "s3cret"
      responses:
        "200":
          description: Authentication successful.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthResponse"
        "401":
          description: Invalid credentials.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AuthError"

  /active-hazards-query:
    get:
      operationId: getActiveHazards
      tags:
        - Active Hazards
      summary: Query active hazard events
      description: |
        Returns a **302 redirect** to a pre-signed S3 URL. The resource at that
        URL contains **gzipped NDJSON** (newline-delimited JSON) with one hazard
        object per line.

        This redirect behaviour applies to both filtered and unfiltered
        requests. Clients must follow the redirect and decompress the gzipped
        response body to read hazard records.

        All query parameters are optional. When none are provided the full set
        of active hazards is returned.
      parameters:
        - name: name
          in: query
          description: Filter by hazard name (partial match).
          schema:
            type: string
        - name: comment
          in: query
          description: Filter by comment text (partial match).
          schema:
            type: string
        - name: type
          in: query
          description: Filter by hazard type. Comma-separated list for multiple values.
          schema:
            type: string
          example: "EARTHQUAKE,FLOOD"
        - name: severity
          in: query
          description: Filter by severity level. Comma-separated list for multiple values.
          schema:
            type: string
          example: "WARNING,WATCH"
        - name: category
          in: query
          description: Filter by hazard category. Comma-separated list for multiple values.
          schema:
            type: string
          example: "EVENT,NATURAL"
        - name: country
          in: query
          description: Filter by country. The full country name is required (e.g. `United States`, not `USA`). Comma-separated list for multiple values.
          schema:
            type: string
          example: "United States,Japan"
        - name: started_at
          in: query
          description: Filter hazards started at or after this timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
          example: "2024-01-01 00:00:00"
        - name: ended_at
          in: query
          description: Filter hazards ended at or before this timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
          example: "2024-12-31 23:59:59"
        - name: created_at
          in: query
          description: Filter by creation timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
        - name: updated_at
          in: query
          description: Filter by last-update timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
        - name: latitude
          in: query
          description: Filter by latitude range as `min,max`.
          schema:
            type: string
          example: "-10.0,10.0"
        - name: longitude
          in: query
          description: Filter by longitude range as `min,max`.
          schema:
            type: string
          example: "100.0,150.0"
        - name: uuid
          in: query
          description: Filter by hazard UUID(s). Comma-separated list for multiple values.
          schema:
            type: string
      responses:
        "302":
          description: |
            Redirect to a pre-signed S3 URL. Follow the `Location` header to
            retrieve gzipped NDJSON hazard data. Each line in the decompressed
            body is a JSON object matching the `ActiveHazard` schema.
            The pre-signed URL expires after 5 minutes.
          headers:
            Location:
              description: Pre-signed S3 URL containing the gzipped NDJSON response.
              schema:
                type: string
                format: uri
          content:
            application/x-ndjson:
              schema:
                description: |
                  Each line of the gzipped response body is one ActiveHazard JSON object.
                $ref: "#/components/schemas/ActiveHazard"
        "400":
          description: Query validation failed.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ActiveHazardQueryError"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /osint-hazards-query:
    get:
      operationId: getOsintHazards
      tags:
        - OSINT Hazards
      summary: Query active OSINT hazard events
      description: |
        Returns a **302 redirect** to a pre-signed S3 URL. The resource at that
        URL contains **gzipped NDJSON** (newline-delimited JSON) with one hazard
        object per line.

        OSINT hazards are detected through proprietary processing of open-source
        intelligence -- news articles, social network feeds, and other
        authoritative sources -- rather than reported by a single authoritative
        agency. The response shape mirrors `/active-hazards-query`, with an
        additional `n2h` block carrying the contributing sources and
        event-specific detail.

        **This endpoint requires a specific role on your credentials.** It is not
        enabled by default. If you receive a `403`, confirm with your sales
        contact or `support@disasteraware.com` that your credentials carry the
        required role.

        This redirect behaviour applies to both filtered and unfiltered
        requests. Clients must follow the redirect and decompress the gzipped
        response body to read hazard records.

        All query parameters are optional. When none are provided the full set
        of active OSINT hazards is returned.
      parameters:
        - name: name
          in: query
          description: Filter by hazard name (partial match).
          schema:
            type: string
        - name: type
          in: query
          description: |
            Filter by hazard type. Comma-separated list for multiple values.
            One or more of `CIVILUNREST`, `FLOOD`, `COMBAT`, `TERRORISM`,
            `ACTIVESHOOTER`, `INCIDENT`.
          schema:
            type: string
          example: "COMBAT,TERRORISM"
        - name: sub_type
          in: query
          description: |
            Filter by hazard sub-type (`hazard_sub_type`). Comma-separated list
            for multiple values, and pairs naturally with `type`. Every type
            except `FLOOD` carries a sub-type; `FLOOD` has no sub-type system and
            is always an empty string, so filtering `FLOOD` by `sub_type` returns
            nothing.

            Valid values by type:

            * `CIVILUNREST` -- `PROTEST`, `STRIKE`, `RIOT`
            * `COMBAT` -- `AIRSTRIKE`, `MISSILESTRIKE`, `DRONESTRIKE`, `BOMBING`,
              `ARTILLERY`, `GROUNDCOMBAT`, `INVASION`, `NAVAL`, `IED`, `AMBUSH`
            * `TERRORISM` -- `BOMBING`, `SUICIDE_BOMBING`, `IED`,
              `VEHICLE_RAMMING`, `MASS_SHOOTING`, `KNIFE_ATTACK`, `HOSTAGE`,
              `ASSASSINATION`, `ARSON`, `OTHER`
            * `ACTIVESHOOTER` -- `MASS_SHOOTING`, `DRIVEBY`, `STANDOFF`, `SNIPER`,
              `SHOOTING`, `OTHER`
            * `INCIDENT` -- `ROAD_CLOSURE`, `BRIDGE`, `RAIL`, `PIPELINE`, `POWER`,
              `INDUSTRIAL`, `WATER`, `OTHER`

            Note there is no `PORT` or `AIRPORT` sub-type. To find disruptions at
            ports and airports, use the `supply_chain` parameter -- the affected
            infrastructure is carried by `SupplyChainInfrastructure`, not by the
            sub-type.
          schema:
            type: string
          example: "RAIL,ROAD_CLOSURE"
        - name: severity
          in: query
          description: |
            Filter by severity level. Comma-separated list for multiple values.
            OSINT hazards represent observed events and are published as
            `WARNING`.
          schema:
            type: string
          example: "WARNING"
        - name: category
          in: query
          description: |
            Filter by hazard category. Comma-separated list for multiple values.
            OSINT hazards are published as `EVENT`.
          schema:
            type: string
          example: "EVENT"
        - name: country
          in: query
          description: |
            Filter by country. Comma-separated list for multiple values. This
            endpoint accepts three interchangeable forms, selected by the length
            of the value:

            * **2 characters** -- exact match on the ISO 3166-1 alpha-2 code
              (e.g. `US`).
            * **3 characters** -- exact match on the ISO 3166-1 alpha-3 code
              (e.g. `USA`).
            * **4 or more characters** -- substring match against the full
              country name, so `United States` matches
              `United States of America`.

            This is more permissive than the `country` parameter on
            `/active-hazards-query`, which requires the full country name.
          schema:
            type: string
          example: "US,JPN,United States"
        - name: started_at
          in: query
          description: Filter hazards started at or after this timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
          example: "2026-07-01 00:00:00"
        - name: ended_at
          in: query
          description: Filter hazards ended at or before this timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
          example: "2026-07-31 23:59:59"
        - name: created_at
          in: query
          description: Filter by creation timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
        - name: updated_at
          in: query
          description: Filter by last-update timestamp (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
        - name: since
          in: query
          description: |
            Return only hazards whose `updatedAt` is at or after this timestamp.
            Intended as a watermark for incremental polling: store the highest
            `updatedAt` you have seen and pass it back on the next request
            (format `YYYY-MM-DD HH:MM:SS`).
          schema:
            type: string
          example: "2026-07-13 06:00:00"
        - name: latitude
          in: query
          description: Filter by latitude range as `min,max`.
          schema:
            type: string
          example: "-10.0,10.0"
        - name: longitude
          in: query
          description: Filter by longitude range as `min,max`.
          schema:
            type: string
          example: "100.0,150.0"
        - name: bbox
          in: query
          description: |
            Filter to hazards whose centroid falls inside a bounding box, given
            as `minLon,minLat,maxLon,maxLat` (WGS84).
          schema:
            type: string
          example: "100.0,-10.0,150.0,10.0"
        - name: min_precision
          in: query
          description: |
            Filter on the geographic precision of the hazard's location
            (`n2h.location_level`). One of `point`, `city`, `county`, `corridor`,
            `river_corridor`, `chokepoint`, or `region` -- `point` is the most
            precise and `region` the least. Hazards are never published at
            country-level precision or coarser.
          schema:
            type: string
          example: "city"
        - name: supply_chain
          in: query
          description: |
            When `true`, return only hazards that disrupt transport or shipping
            infrastructure (`incident.properties.SupplyChainImpact`), such as
            port strikes, canal closures, rail suspensions, and airport
            shutdowns.
          schema:
            type: boolean
          example: true
        - name: uuid
          in: query
          description: Filter by hazard UUID(s). Comma-separated list for multiple values.
          schema:
            type: string
      responses:
        "302":
          description: |
            Redirect to a pre-signed S3 URL. Follow the `Location` header to
            retrieve gzipped NDJSON hazard data. Each line in the decompressed
            body is a JSON object matching the `OsintHazard` schema.
            The pre-signed URL expires after 5 minutes.
          headers:
            Location:
              description: Pre-signed S3 URL containing the gzipped NDJSON response.
              schema:
                type: string
                format: uri
          content:
            application/x-ndjson:
              schema:
                description: |
                  Each line of the gzipped response body is one OsintHazard JSON object.
                $ref: "#/components/schemas/OsintHazard"
        "400":
          description: Query validation failed.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ActiveHazardQueryError"
        "403":
          description: |
            Forbidden -- the token is invalid or expired, **or** the credentials
            do not carry the role required for OSINT hazards. If your token works
            against other endpoints, contact your sales contact or
            `support@disasteraware.com` to have the required role added.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /historical_hazards:
    get:
      operationId: getHistoricalHazards
      tags:
        - Historical Hazards
      summary: Search historical hazard records
      description: |
        Query the historical hazard database using a SQL-style `where` clause.
        Returns an array of matching hazard records.
      parameters:
        - name: where
          in: query
          required: true
          description: |
            SQL-style filter expression. Example:
            `type_ID='EARTHQUAKE' AND severity_ID='WARNING'`
          schema:
            type: string
          example: "type_ID='EARTHQUAKE'"
      responses:
        "200":
          description: Array of matching historical hazard records.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HistoricalHazard"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards_count:
    get:
      operationId: getHazardsCount
      tags:
        - Historical Hazards
      summary: Count historical hazard records
      description: |
        Returns the count of historical hazard records matching the given
        `where` clause. Uses the same query syntax as `/historical_hazards`.
      parameters:
        - name: where
          in: query
          required: true
          description: |
            SQL-style filter expression, same syntax as `/historical_hazards`.
          schema:
            type: string
          example: "type_ID='FLOOD'"
      responses:
        "200":
          description: Count result.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HazardsCountResponse"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards/{hazard-id}/alert-geography:
    get:
      operationId: getAlertGeography
      tags:
        - Hazard Metadata
      summary: Get alert geography for a hazard
      description: |
        Returns the alert geography (affected area polygon) for a specific
        hazard, including the geometry as WKT and binary representations.
      parameters:
        - name: hazard-id
          in: path
          required: true
          description: Unique hazard identifier (UUID or numeric ID).
          schema:
            type: string
      responses:
        "200":
          description: Alert geography for the requested hazard.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AlertGeography"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards/types:
    get:
      operationId: getHazardTypes
      tags:
        - Hazard Metadata
      summary: List all hazard types
      description: Returns the full set of hazard type reference values (e.g. EARTHQUAKE, FLOOD).
      responses:
        "200":
          description: Array of hazard types.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HazardType"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards/severities:
    get:
      operationId: getHazardSeverities
      tags:
        - Hazard Metadata
      summary: List all hazard severity levels
      description: Returns the full set of hazard severity reference values (e.g. WARNING, WATCH, TERMINATION).
      responses:
        "200":
          description: Array of severity levels.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HazardSeverity"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards/categories:
    get:
      operationId: getHazardCategories
      tags:
        - Hazard Metadata
      summary: List all hazard categories
      description: Returns the full set of hazard category reference values (e.g. EVENT, NATURAL).
      responses:
        "200":
          description: Array of hazard categories.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/HazardCategory"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /hazards/{hazard-id}/products:
    get:
      operationId: getHazardProducts
      tags:
        - Products
      summary: List products for a hazard
      description: Returns all products (documents, maps, folders) associated with a specific hazard.
      parameters:
        - name: hazard-id
          in: path
          required: true
          description: Unique hazard identifier (UUID or numeric ID).
          schema:
            type: string
      responses:
        "200":
          description: Array of products for the hazard.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Product"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /products/types:
    get:
      operationId: getProductTypes
      tags:
        - Products
      summary: List all product types
      description: Returns the full set of product type reference values.
      responses:
        "200":
          description: Array of product types.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ProductType"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

  /products/{product-id}:
    get:
      operationId: getProduct
      tags:
        - Products
      summary: Get a single product by ID
      description: |
        Returns an array containing a single product object matching the given
        product ID.
      parameters:
        - name: product-id
          in: path
          required: true
          description: Unique product identifier (UUID or numeric ID).
          schema:
            type: string
      responses:
        "200":
          description: Array containing the requested product.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Product"
        "403":
          description: Forbidden -- invalid or expired token.
          content:
            text/plain:
              schema:
                type: string
                example: "Forbidden"

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT access token obtained from `POST /authorize`. Tokens expire after
        15 minutes.

  schemas:
    # ── Authentication ──────────────────────────────────────────────────

    AuthResponse:
      type: object
      properties:
        accessToken:
          type: string
          description: Short-lived JWT access token (15-minute expiry).
          example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        refreshToken:
          type: string
          description: Long-lived token used to obtain a new access token.
          example: "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."

    AuthError:
      type: object
      properties:
        status:
          type: string
          example: "UNAUTHORIZED"
        message:
          type: string
          example: "Authentication failed."

    # ── Active Hazards ──────────────────────────────────────────────────

    LocaleObject:
      type: object
      description: A localised text value.
      properties:
        locale:
          type: string
          description: Locale of the value, formatted according to RFC 5646.
          example: "en"
        value:
          type: string
          example: "M 5.2 Earthquake - Southern Peru"

    PopulationBreakdown:
      type: object
      description: Population estimates broken down by demographic group.
      properties:
        total:
          type: number
          description: Total estimated population.
          example: 712000.0
        total0_14:
          type: number
          description: Estimated population aged 0-14.
          example: 125312.0
        total15_64:
          type: number
          description: Estimated population aged 15-64.
          example: 462515.2
        total65_Plus:
          type: number
          description: Estimated population aged 65 and over.
          example: 124101.6
        households:
          type: number
          description: Estimated number of households.
          example: 285943.7751
        vulnerable:
          type: number
          description: Estimated vulnerable population.
          example: 85400.0

    CapitalBreakdown:
      type: object
      description: Capital exposure and critical infrastructure counts.
      properties:
        total:
          type: number
          description: Total estimated capital/infrastructure value at risk (USD).
          example: 76826932300.0
        school:
          type: integer
          description: Number of schools exposed.
          example: 418
        hospital:
          type: integer
          description: Number of hospitals exposed.
          example: 25

    RegionBreakdown:
      type: object
      description: Exposure breakdown for a specific country or administrative region.
      properties:
        population:
          $ref: "#/components/schemas/PopulationBreakdown"
        country:
          type: string
          description: ISO 3166-1 alpha-3 country code.
          example: "PHL"
        capital:
          $ref: "#/components/schemas/CapitalBreakdown"
        admin0:
          type: string
          description: Country-level administrative name.
          example: "Philippines"
        admin1:
          type: string
          nullable: true
          description: First-level administrative division (e.g., province/state), or null if not applicable.
          example: "Calabarzon"
        admin2:
          type: string
          nullable: true
          description: Second-level administrative division (e.g., municipality/district), or null if not applicable.
          example: "Batangas"
        foodNeedsUnit:
          type: string
          description: Unit for foodNeeds value.
          example: "MRE"
        foodNeeds:
          type: number
          description: Estimated food needs for this region.
        waterNeedsUnit:
          type: string
          description: Unit for waterNeeds value.
          example: "gal"
        waterNeeds:
          type: number
          description: Estimated water needs for this region.
        wasteNeedsUnit:
          type: string
          description: Unit for wasteNeeds value.
          example: "25 gal"
        wasteNeeds:
          type: number
          description: Estimated waste-management needs for this region.
        shelterNeedsUnit:
          type: string
          description: Unit for shelterNeeds value.
          example: "sq feet"
        shelterNeeds:
          type: number
          description: Estimated shelter needs for this region.

    ExposureAssessment:
      type: object
      description: Exposure and humanitarian-needs assessment for a hazard.
      properties:
        population:
          $ref: "#/components/schemas/PopulationBreakdown"
        capital:
          $ref: "#/components/schemas/CapitalBreakdown"
        foodNeeds:
          type: number
          description: Estimated food needs.
        waterNeeds:
          type: number
          description: Estimated water needs.
        wasteNeeds:
          type: number
          description: Estimated waste-management needs.
        shelterNeeds:
          type: number
          description: Estimated shelter needs.
        foodNeedsUnit:
          type: string
          description: Unit for foodNeeds value.
          example: "MRE"
        waterNeedsUnit:
          type: string
          description: Unit for waterNeeds value.
          example: "gal"
        wasteNeedsUnit:
          type: string
          description: Unit for wasteNeeds value.
          example: "25 gal"
        shelterNeedsUnit:
          type: string
          description: Unit for shelterNeeds value.
          example: "sq feet"
        totalByCountry:
          type: array
          description: Exposure totals broken down by country.
          items:
            $ref: "#/components/schemas/RegionBreakdown"
        totalByAdmin:
          type: array
          description: Exposure totals broken down by administrative region.
          items:
            $ref: "#/components/schemas/RegionBreakdown"
        exposureLevels:
          type: array
          description: Breakdown of exposure by severity level.
          items:
            type: object
            properties:
              level:
                type: string
                description: Exposure severity level ("1", "2", or "3").
                example: "1"
              exposureDescription:
                type: string
                description: Human-readable description of this exposure zone.
              data:
                type: object
                description: Exposure data for this level.
                properties:
                  population:
                    $ref: "#/components/schemas/PopulationBreakdown"
                  capital:
                    $ref: "#/components/schemas/CapitalBreakdown"
                  foodNeeds:
                    type: number
                  waterNeeds:
                    type: number
                  wasteNeeds:
                    type: number
                  shelterNeeds:
                    type: number
                  foodNeedsUnit:
                    type: string
                  waterNeedsUnit:
                    type: string
                  wasteNeedsUnit:
                    type: string
                  shelterNeedsUnit:
                    type: string
                  totalByCountry:
                    type: array
                    description: Exposure totals for this level broken down by country.
                    items:
                      $ref: "#/components/schemas/RegionBreakdown"
                  totalByAdmin:
                    type: array
                    description: Exposure totals for this level broken down by administrative region.
                    items:
                      $ref: "#/components/schemas/RegionBreakdown"
        exposureDescription:
          type: string
          description: Human-readable exposure summary.
        timestamp:
          type: integer
          description: Unix timestamp of the assessment.
        hazardUuid:
          type: string
          description: UUID of the assessed hazard.
        hazardType:
          type: string
          description: Type of the assessed hazard.
        version:
          type: integer

    IncidentObject:
      type: object
      description: Source incident details.
      properties:
        uuid:
          type: string
        type:
          type: string
        sourceId:
          type: string
        sourceRecordId:
          type: string
        properties:
          type: object

    SourceObject:
      type: object
      nullable: true
      description: Data source for the hazard.
      properties:
        id:
          type: string
        name:
          type: string
        longName:
          type: string
        description:
          type: string

    GeoJSONFeatureCollection:
      type: object
      description: GeoJSON FeatureCollection.
      properties:
        type:
          type: string
          enum:
            - FeatureCollection
        features:
          type: array
          items:
            type: object

    ActiveHazard:
      type: object
      description: |
        A single active hazard record. Returned as newline-delimited JSON
        (one object per line) in the gzipped body at the pre-signed S3 URL.
      properties:
        name:
          type: array
          description: Localised hazard name.
          items:
            $ref: "#/components/schemas/LocaleObject"
        description:
          type: array
          description: Localised hazard description.
          items:
            $ref: "#/components/schemas/LocaleObject"
        severity:
          type: string
          description: Severity level identifier.
          example: "WARNING"
        category:
          type: string
          description: Category identifier.
          example: "NATURAL"
        type:
          type: string
          description: Hazard type identifier.
          example: "EARTHQUAKE"
        uuid:
          type: string
          description: Unique identifier for the hazard.
          example: "abc12345-6789-def0-1234-56789abcdef0"
        comment:
          type: string
          nullable: true
          description: Optional editorial comment.
        createdAt:
          type: integer
          description: Creation time as Unix timestamp (seconds).
          example: 1697222149
        updatedAt:
          type: integer
          description: Last update time as Unix timestamp (seconds).
          example: 1697222149
        startedAt:
          type: integer
          description: Hazard start time as Unix timestamp (seconds).
        endedAt:
          type: integer
          description: Hazard end time as Unix timestamp (seconds).
        latitude:
          type: number
          format: float
          description: Latitude of the hazard centroid.
          example: -16.25
        longitude:
          type: number
          format: float
          description: Longitude of the hazard centroid.
          example: -71.58
        version:
          type: integer
          description: Record version number.
        creator:
          type: string
          description: Creator or system that produced the record.
          example: "DisasterAWARE (Automated)"
        relatedHazards:
          type: array
          description: UUIDs or references to related hazard events.
          items:
            type: object
        incident:
          $ref: "#/components/schemas/IncidentObject"
        source:
          $ref: "#/components/schemas/SourceObject"
        alertGeometry:
          $ref: "#/components/schemas/GeoJSONFeatureCollection"
        features:
          description: Additional GeoJSON features, or null if none.
          type: object
          nullable: true
          properties:
            type:
              type: string
              example: FeatureCollection
            features:
              type: array
              items:
                type: object
        exposureAreas:
          $ref: "#/components/schemas/GeoJSONFeatureCollection"
        exposureAssessment:
          $ref: "#/components/schemas/ExposureAssessment"

    ActiveHazardQueryError:
      type: object
      properties:
        error:
          type: string
          example: "Query validation failed"
        details:
          type: array
          items:
            type: object
            properties:
              parameter:
                type: string
                example: "severity"
              value:
                type: string
                example: "INVALID_VALUE"
              error:
                type: string
                example: "Invalid severity value"
              expected_format:
                type: string
                example: "Comma-separated list of valid severity IDs"
              allowed_parameters:
                type: array
                items:
                  type: string

    # ── OSINT Hazards ───────────────────────────────────────────────────

    OsintLocaleObject:
      type: object
      description: A localised hazard name.
      properties:
        locale:
          type: string
          description: Locale of the value, formatted according to RFC 5646.
          example: "en"
        value:
          type: string
          example: "Russian Missile and Drone Strike on Power Grid — Ukraine"

    OsintDescriptionObject:
      type: object
      description: A localised hazard description.
      properties:
        locale:
          type: string
          description: Locale of the value, formatted according to RFC 5646.
          example: "en"
        value:
          type: string
          example: |
            A Combat incident was reported in Podilskyi district, Ukraine on 2026-07-03.
            Preliminary reports indicate 10 total victims comprised of 10 fatalities.

            Event Summary*:
            • Combat has been reported in Podilskyi district, Ukraine.
            • Affected areas include: Podilskyi district, Ukraine.

            Based on 247 article(s) from: Ukrainska Pravda English, South China Morning Post, ...

    SourceArticle:
      type: object
      description: A news article that contributed to the detection of the hazard.
      properties:
        name:
          type: string
          description: Publisher name.
          example: "Ukrainska Pravda English"
        title:
          type: string
          description: Article headline.
        url:
          type: string
          format: uri
          description: Link to the source article.
        type:
          type: string
          description: Feed type the article arrived on.
          example: "rss"
        published_at:
          type: string
          nullable: true
          description: Publication time reported by the source (ISO 8601), when available.
        body:
          type: string
          description: Article text extract.

    N2HBlock:
      type: object
      description: |
        OSINT-specific detail accompanying the hazard. This block is an extension
        to the core hazard shape and is present only on OSINT hazards.
      properties:
        hazard_id:
          type: string
          description: Human-readable identifier for the detected event.
          example: "COMBAT-UKR-KYIV-2026-07"
        hazard_sub_type:
          type: string
          description: Sub-classification of the hazard type. Mirrors the top-level field.
          example: "MISSILESTRIKE"
        summary:
          type: string
          description: Short summary of the event synthesised from the contributing articles.
        is_ongoing:
          type: boolean
          description: |
            Whether the underlying real-world event is still unfolding. Distinct
            from the record's lifecycle: a hazard can remain active in the feed
            after the event itself has concluded.
        start_date_iso:
          type: string
          description: Date the event began (ISO 8601 date).
          example: "2026-07-03"
        end_date_iso:
          type: string
          nullable: true
          description: Date the event concluded, or null if it is still ongoing.
        location_level:
          type: string
          description: |
            Geographic precision of the resolved location. One of `point`, `city`,
            `county`, `corridor`, `river_corridor`, `chokepoint`, or `region` --
            `point` is the most precise and `region` the least. Hazards are never
            published at country-level precision or coarser.
          example: "point"
        location_specific:
          type: string
          description: The most specific place name resolved for the event.
          example: "Podilskyi district"
        country:
          type: string
          description: Country the event occurred in, as reported by the pipeline.
        article_count:
          type: integer
          description: |
            Number of articles that contributed to this hazard. A higher count
            indicates broader corroboration.
          example: 247
        quantitative:
          type: object
          description: |
            Counters extracted from the reporting. Keys vary by hazard type --
            for example `participants` and `arrests` for CIVILUNREST,
            `missiles_fired` and `drones_intercepted` for COMBAT, or
            `flood_depth_ft` and `homes_flooded` for FLOOD. Treat this as an
            open map and read only the keys you need.
          additionalProperties: true
        sources:
          type: array
          description: The contributing articles.
          items:
            $ref: "#/components/schemas/SourceArticle"
        extra:
          type: object
          description: |
            Internal pipeline diagnostics. Reserved for internal use -- the
            contents are not part of the public contract and may change without
            notice.

    OsintHazard:
      type: object
      description: |
        A single active OSINT hazard record. Returned as newline-delimited JSON
        (one object per line) in the gzipped body at the pre-signed S3 URL.

        The shape mirrors `ActiveHazard`, with three differences: an added `n2h`
        block, an added `locationDetails` block, and `exposureAreas` /
        `exposureAssessment` which are not computed for OSINT hazards and are
        always null.
      properties:
        name:
          type: array
          description: Localised hazard name.
          items:
            $ref: "#/components/schemas/OsintLocaleObject"
        description:
          type: array
          description: |
            Localised hazard description, summarising the event and the
            publications it was drawn from.
          items:
            $ref: "#/components/schemas/OsintDescriptionObject"
        severity:
          type: string
          description: Severity level identifier. OSINT hazards are published as `WARNING`.
          example: "WARNING"
        category:
          type: string
          description: Category identifier. OSINT hazards are published as `EVENT`.
          example: "EVENT"
        type:
          type: string
          description: |
            Hazard type identifier: `CIVILUNREST`, `FLOOD`, `COMBAT`,
            `TERRORISM`, `ACTIVESHOOTER`, or `INCIDENT`.
          example: "COMBAT"
        hazard_sub_type:
          type: string
          description: |
            Sub-classification of the hazard type. Guaranteed non-empty for every
            type except `FLOOD`, which has no sub-type system and is always an
            empty string. Each type defines a default that is used when reporting
            does not identify a more specific sub-type.
          example: "MISSILESTRIKE"
        uuid:
          type: string
          description: Unique identifier for the hazard, stable across updates.
          example: "a6a4b817-8e6f-4f27-8974-c755db09f918"
        comment:
          type: string
          nullable: true
          description: Optional editorial comment.
        createdAt:
          type: integer
          description: Creation time as Unix timestamp (seconds).
          example: 1783392752
        updatedAt:
          type: integer
          description: Last update time as Unix timestamp (seconds).
          example: 1783981527
        startedAt:
          type: integer
          description: Event start time as Unix timestamp (seconds).
          example: 1783036800
        endedAt:
          type: integer
          description: |
            Unix timestamp (seconds) of the **detected end** of the event. It is
            never padded: a hazard remains in the active feed for a short linger
            period after `endedAt`, but the timestamp itself always reports when
            the event actually concluded. Judge relevance from this value rather
            than from the hazard's presence in the feed.
          example: 1783641600
        latitude:
          type: number
          format: float
          description: Latitude of the event location.
          example: 50.4895076
        longitude:
          type: number
          format: float
          description: Longitude of the event location.
          example: 30.4287653
        version:
          type: integer
          description: Record version number, incremented as the event is updated.
          example: 2
        creator:
          type: string
          description: System that produced the record.
          example: "News2Hazards (Automated)"
        relatedHazards:
          type: array
          description: Reserved for future use. Currently an empty array.
          items:
            type: object
        incident:
          $ref: "#/components/schemas/IncidentObject"
        source:
          $ref: "#/components/schemas/SourceObject"
        locationDetails:
          type: object
          description: |
            Administrative hierarchy resolved from the event coordinates.
            Includes `country`, `country_code` (ISO-2), `country_code_3`
            (ISO-3), `state_province`, `state_code`, `county`, `continent`,
            `subregion`, and `location_type`.
        n2h:
          $ref: "#/components/schemas/N2HBlock"
        alertGeometry:
          $ref: "#/components/schemas/GeoJSONFeatureCollection"
        features:
          description: |
            GeoJSON FeatureCollection containing an `INCIDENT` point at the event
            location and a `SMART_ALERT` polygon defining the alert boundary.
          type: object
          nullable: true
          properties:
            type:
              type: string
              example: FeatureCollection
            features:
              type: array
              items:
                type: object
        exposureAreas:
          type: object
          nullable: true
          description: Not computed for OSINT hazards. Always null.
        exposureAssessment:
          type: object
          nullable: true
          description: Not computed for OSINT hazards. Always null.

    # ── Historical Hazards ──────────────────────────────────────────────

    HistoricalHazard:
      type: object
      description: A historical hazard record.
      properties:
        app_ID:
          type: integer
          description: Application ID.
          example: 1
        app_IDs:
          type: string
          description: Comma-separated application IDs.
        autoexpire:
          type: string
          description: Auto-expiration flag.
        category_ID:
          type: string
          description: Category identifier.
          example: "NATURAL"
        charter_Uri:
          type: string
          description: International Charter URI, if applicable.
        comment_Text:
          type: string
          description: Editorial comment.
        create_Date:
          type: string
          description: Creation timestamp in epoch milliseconds.
          example: "1697157024387"
        creator:
          type: string
          description: Record creator.
          example: "DisasterAWARE (Automated)"
        end_Date:
          type: string
          description: End timestamp in epoch milliseconds.
        glide_Uri:
          type: string
          description: GLIDE number URI.
        hazard_ID:
          type: integer
          description: Numeric hazard identifier.
          example: 203575
        hazard_Name:
          type: string
          description: Human-readable hazard name.
          example: "M 5.2 Earthquake - Southern Peru"
        last_Update:
          type: string
          description: Last update timestamp in epoch milliseconds.
        latitude:
          type: number
          description: Latitude of the hazard centroid.
          example: -16.25
        longitude:
          type: number
          description: Longitude of the hazard centroid.
          example: -71.58
        master_Incident_ID:
          type: string
          description: Master incident identifier.
        message_ID:
          type: string
          description: Associated message identifier.
        org_ID:
          type: integer
          description: Organisation ID.
        severity_ID:
          type: string
          description: Severity identifier.
          example: "WARNING"
        snc_url:
          type: string
          description: Situational awareness URL.
        start_Date:
          type: string
          description: Start timestamp in epoch milliseconds.
          example: "1697157024387"
        status:
          type: string
          description: Hazard status (e.g. active, expired).
        type_ID:
          type: string
          description: Hazard type identifier.
          example: "EARTHQUAKE"
        update_Date:
          type: string
          description: Update timestamp in epoch milliseconds.
        update_User:
          type: string
          description: User who last updated the record.
        product_total:
          type: string
          description: Total number of associated products.
        uuid:
          type: string
          description: Unique identifier.
        in_Dashboard:
          type: string
          description: Whether the hazard appears in the dashboard.
        areabrief_url:
          type: string
          nullable: true
          description: URL to the area brief, if available.
        description:
          type: string
          description: Hazard description text.
        roles:
          type: array
          description: Roles associated with the hazard.
          items:
            type: string

    HazardsCountResponse:
      type: object
      description: |
        Count of hazards matching the query. The `code` and `description`
        fields contain the numeric count; `value` is a status indicator.
      properties:
        code:
          type: integer
          description: Number of matching records.
          example: 165
        value:
          type: string
          description: Status indicator.
          example: "PASS"
        description:
          type: string
          description: Human-readable count (same number as `code`).
          example: "165"

    # ── Alert Geography ─────────────────────────────────────────────────

    AlertGeography:
      type: object
      description: Alert geography (affected-area polygon) for a hazard.
      properties:
        magId:
          type: integer
          description: Internal geometry record ID.
          example: 570048
        uuid:
          type: string
          description: UUID of the alert geography.
        title:
          type: string
          description: Title of the alert area.
        createDate:
          type: integer
          description: Creation timestamp in epoch milliseconds.
          example: 1697222149887
        magType:
          type: string
          description: Geometry derivation type.
          example: "calculated"
        creator:
          type: string
          description: Creator of the geometry.
        isActive:
          type: boolean
          description: Whether this geometry is currently active.
          example: true
        updateDate:
          type: integer
          description: Last update timestamp in epoch milliseconds.
          example: 1697222149887
        wkt:
          type: object
          description: Well-Known Text representation of the geometry.
          properties:
            text:
              type: string
              description: WKT geometry string.
              example: "MULTIPOLYGON (((-71.0 -16.0, ...)))"
            binary:
              type: string
              description: Base64-encoded binary geometry.

    # ── Hazard Metadata ─────────────────────────────────────────────────

    HazardType:
      type: object
      properties:
        type_id:
          type: string
          description: Unique type identifier.
          example: "EARTHQUAKE"
        type_name:
          type: string
          description: Human-readable type name.
          example: "Earthquake"
        type_icon:
          type: string
          description: Icon filename for UI rendering.
          example: "earthquake.png"

    HazardSeverity:
      type: object
      properties:
        severity_id:
          type: string
          description: Unique severity identifier.
          example: "WARNING"
        severity_name:
          type: string
          description: Human-readable severity name.
          example: "Warning"
        severity_icon:
          type: string
          description: Icon filename for UI rendering.
          example: "warning.png"

    HazardCategory:
      type: object
      properties:
        category_id:
          type: string
          description: Unique category identifier.
          example: "EVENT"
        category_name:
          type: string
          description: Human-readable category name.
          example: "Event"

    # ── Products ────────────────────────────────────────────────────────

    Product:
      type: object
      description: A document, map, report, or folder associated with a hazard.
      properties:
        app_IDs:
          type: string
          nullable: true
          description: Associated application IDs.
        comment_Text:
          type: string
          description: Comment on the product.
        data:
          type: string
          nullable: true
          description: Inline data payload, if any.
        filename:
          type: string
          nullable: true
          description: Original filename, if applicable.
        hazard_ID:
          type: integer
          description: Associated hazard ID.
          example: 203575
        is_Hidden:
          type: string
          description: Whether the product is hidden (`Y` or `N`).
          example: "N"
        org_ID:
          type: integer
          description: Organisation ID.
        org_IDs:
          type: string
          description: Comma-separated organisation IDs.
        organization_acronym:
          type: string
          nullable: true
          description: Acronym of the producing organisation.
        parent_ID:
          type: integer
          description: Parent product ID (for folder hierarchy).
          example: 1756465
        product_ID:
          type: integer
          description: Unique product identifier.
          example: 1756466
        product_Type:
          type: string
          description: Product type code.
          example: "FOLDER_PRODUCT"
        security_Flag:
          type: string
          description: Security classification flag.
          example: "A"
        title:
          type: string
          description: Product title.
          example: "PDC (SA)"
        uuid:
          type: string
          description: Unique identifier.
        user_ID:
          type: string
          description: User or system that created the product.
          example: "DisasterAWARE (Automated)"
        product_url:
          type: string
          nullable: true
          description: URL to download or view the product.
        suffix:
          type: string
          description: File suffix or type indicator.
          example: "folder"
        create_Date:
          type: string
          description: Creation timestamp in epoch milliseconds.
          example: "1697157024387"
        update_Date:
          type: string
          description: Last update timestamp in epoch milliseconds.
          example: "1697222488323"
        timeline_Date:
          type: string
          description: Timeline display timestamp in epoch milliseconds.
          example: "1697222488323"
        update_User:
          type: string
          description: User who last updated the product.
          example: "ddp"
        geo_Locations:
          type: string
          description: Geographic location metadata.

    ProductType:
      type: object
      properties:
        type:
          type: string
          description: Product type code.
          example: "FOLDER_PRODUCT"
        description:
          type: string
          description: Human-readable description of the product type.
