---
title: "Get Incident Counts"
method: GET
path: "/analytics/incidents"
tags: ["analytics"]
---

# Get Incident Counts

`GET /analytics/incidents`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/analytics/incidents`
- Auth: HTTP bearer

AI detections grouped by incident_type over a window (default rolling
24h; start/end win when both given), rolled up per site and per camera —
the Analytics → Incident Data tab. site_id/camera_id repeat for
multi-select: UUID-typed so malformed ids 422 at the edge instead of
500ing in Postgres, and length-capped to bound the authorization and
analytics IN clauses. Same tenant scoping as /analytics/summary.

## Query parameters

- `hours` integer, nullable
- `start` string, date-time, nullable
- `end` string, date-time, nullable
- `parent_id` string, uuid, nullable
- `site_id` string[], nullable
- `camera_id` string[], nullable

## Response `200`

Successful Response

- GetIncidentCountsResponse
  - `window_start` string, date-time, required: Start of the counted window (UTC).
  - `window_end` string, date-time, required: End of the counted window (UTC).
  - `total` integer, required: All AI detections in the window across the selected scope.
  - `totals` IncidentTypeCount[], required: Per-incident-type totals, largest first.
    - `incident_type` string, required: IncidentType value. Treated as an open string by clients so enum additions never break the UI.
    - `count` integer, required: AI detections of this type in the window.
  - `sites` SiteIncidentCounts[], required: Per-site rollups (only sites with detections appear).
    - `site_id` string, required: Site UUID.
    - `count` integer, required: Total AI detections at this site in the window.
    - `by_type` object, required: Per-incident-type counts at this site.
  - `cameras` CameraIncidentCounts[], required: Per-camera rollups (only cameras with detections appear).
    - `camera_id` string, required: Camera row UUID (not the hardware camera_id).
    - `site_id` string, required: Site UUID the camera belongs to.
    - `count` integer, required: Total AI detections on this camera in the window.
    - `by_type` object, required: Per-incident-type counts on this camera.
  - `gate_rejections` GateRejections, required: DeepAlert Phase B (round-0b design §7.3/OQ-7): terminal_stage == 'object_gate' rows, segmented out of the primary AI incident counts above so a gate-negative never silently counts as an ordinary AI NORMAL classification. Zero for every scope until a camera is flipped to detection_mode='ii_gated' and incident-intelligence's own Phase B pipeline ships — both independent of this PR.
    - `total` integer, required: Total object_gate rows in the window across the selected scope.
    - `by_reason` GateRejectionReasonCount[], required: Per-reason breakdown, largest first.
      - `reason` string, required: gate_outcome.reason value (open string — ii may add new reasons; 'unknown' when the JSONB key is missing/null).
      - `count` integer, required: Gate-negative rows with this reason in the window.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/verdun/apis/verdun-api.md) - [All operations](https://skmtc.dev/verdun/apis/verdun-api/llms.txt) - [OpenAPI document](https://skmtc.dev/verdun/apis/verdun-api/revisions/00252d8227c1?raw)
