---
title: "Get Speakers For Site"
method: GET
path: "/sites/{site_id}/speakers"
tags: ["speakers"]
---

# Get Speakers For Site

`GET /sites/{site_id}/speakers`

## 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/sites/{site_id}/speakers`
- Auth: HTTP bearer

## Path parameters

- `site_id` string, required

## Response `200`

Successful Response

- GetSpeakersResponse
  - `speakers` SpeakerListItemResponse[], required: Live speakers registered for this site, each with the cameras it covers.
    - `id` string, uuid, required: The speaker record ID.
    - `site_id` string, uuid, required: The site this speaker belongs to.
    - `parent_id` string, uuid, required: The client this speaker belongs to.
    - `label` string, required: Display name.
    - `brand` 'axis', required
    - `model` 'axis_c1310_e' | 'axis_c1210_e' | 'axis_c1310_e_mk2'
    - `host` string, required: IP address of the speaker (IPv4 or IPv6 literal), in canonical form. Hostnames are not supported in v1.
    - `port` string, required: HTTPS port.
    - `username` string, required: Device account username (the password is never returned).
    - `transport` 'direct_https' | 'direct_http' | 'nvr_proxy', required
    - `clip_id` string, nullable: Id of the pre-loaded deterrent clip.
    - `clip_params` object, nullable: Playback parameters.
    - `enabled` boolean, required: Whether delivery and the health poll consider this speaker.
    - `sip_enabled` boolean: Whether the AI voice agent may place a SIP call to this speaker.
    - `sip_account_id` string, nullable: Which of the device's SIP accounts the agent's call is placed from; null means the device default.
    - `mic_enabled` boolean: Whether this unit's microphone is live, which decides whether the agent waits for a reply.
    - `onboarding_checklist` object, nullable: The device-setup checklist: the owner's own attestations under `items`, each stamped server-side. An absent key means not confirmed. The one item the device answers for itself is NOT stored here — read it live from `GET /speakers/{id}/sip-accounts`.
    - `agent_armed_camera_count` integer, nullable: How many of this speaker's camera mappings are ARMED for the AI agent. Zero means nothing will ever announce here, however the device is configured.
    - `last_sip_test` LastSipTest: The headline of the newest SIP test on a speaker. `passed` is the two-signal check — the device reported the call Active AND the voice platform reported the same call live. The full timeline lives on `GET /speakers/{id}/sip-test`; this is what a list row needs to say whether a horn is armed.
      - `at` string, date-time, nullable: When the test was placed.
      - `passed` boolean, required: True only when both signals agreed.
      - `call_id` string, uuid, required: The call record, for the detail view.
      - `summary` string, required: One sentence a person can act on.
    - `map_x` number, nullable: Normalized floor-plan x.
    - `map_y` number, nullable: Normalized floor-plan y.
    - `map_lat` number, nullable: Geographic latitude of the speaker pin.
    - `map_lng` number, nullable: Geographic longitude of the speaker pin.
    - `map_location_label` string, nullable: Operator-facing location prose.
    - `map_heading` number, nullable: Direction a horn faces, degrees clockwise from map-up; null = not aimed (always null for an omnidirectional ceiling unit).
    - `healthy` boolean, nullable: Last health-poll result.
    - `last_healthcheck_at` string, date-time, nullable: When the speaker was last polled.
    - `health_error` string, nullable: Why the last health poll failed: unreachable (no HTTP answer), auth_rejected (the device answered 401 to the stored credentials), not_a_speaker (something answered, but not an Axis device API - e.g. a router page), clip_missing (the configured clip id is not on the device), or error. Null when healthy or never checked.
    - `device_serial` string, nullable: Serial number of the device last seen at this host:port, read without credentials. Compare it across speakers to tell two units behind one IP apart. Last known value; a failed poll keeps it.
    - `device_product` string, nullable: Product name of the device last seen at this host:port (ProdFullName, else ProdNbr). Last known value.
    - `device_firmware` string, nullable: Firmware version of the device last seen at this host:port. Last known value.
    - `device_identity_at` string, date-time, nullable: When the device identity above was last read successfully.
    - `created_at` string, date-time, nullable: When the speaker was registered.
    - `updated_at` string, date-time, nullable: When the speaker was last edited.
    - `cameras` SpeakerCameraMappingResponse[], required: Cameras this speaker covers, in failover order. Empty means the speaker is registered but not mapped to any camera, so nothing can announce on it.
      - `camera_id` string, uuid, required: Mapped camera.
      - `camera_label` string, required: The camera's display name.
      - `priority` integer, required: Failover order for that camera: 0 is the primary.
      - `agent_trigger_enabled` boolean, required: Whether the AI agent is armed to fire this speaker automatically for that camera. False (the default) is human-triggered only: operators can Talk Down, the agent's voice-down fails closed exactly as on an unmapped camera, and the policy ledger reports voice-down as unavailable there.

## 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/35a2a6ebedda?raw)
