---
title: "Start/stop always-on alert rules for an incoming camera event"
method: POST
path: "/api/v1/realtime/always-on"
tags: ["realtime"]
---

# Start/stop always-on alert rules for an incoming camera event

`POST /api/v1/realtime/always-on`

Starts or stops always-on alert rules in response to a camera lifecycle event.

**Behavior by `event.change`:**

- `camera_streaming` — starts one rule per entry in the always-on rules config. Idempotent per `camera_id`: repeats return reason `STREAM_ADD_ALREADY_ACTIVE`.
- `camera_remove` — stops every rule previously started for that `camera_id`.

Responses carry a `reason` code (`STREAM_ADD_SUCCESS`, `STREAM_ADD_PARTIAL_SUCCESS`, `STREAM_ADD_ALREADY_ACTIVE`, `STREAM_ADD_FAILED`, or `ALWAYS_ON_DISABLED`) and a `details` array with one entry per rule.

## Request body

- object — Request body for ``POST /api/v1/realtime/always-on``. Only the canonical VST shape is accepted: ```json { "source": "vst", "alert_type": "camera_status_change", "created_at": "2026-04-22T17:38:38Z", "event": { "camera_id": "c0413489-6ca1-422e-a09c-08224169ff6a", "camera_name": "warehouse", "camera_url": "rtsp://localhost:8554/live/<id>", "camera_vod_url": "rtsp://localhost:8554/vod/<id>", "change": "camera_streaming", "metadata": {"codec": "H264"} } } ``` Producer-only fields on the outer envelope (``source``, ``alert_type``, ``created_at``) and inside ``event`` (``metadata``, ``camera_vod_url``) pass through unused; extra unknown fields are tolerated (``extra="allow"``) so upstream changes don't break the endpoint.
  - `source` string, nullable — Upstream producer tag (informational; e.g. 'vst')
  - `alert_type` string, nullable — Producer-assigned event type, e.g. 'camera_status_change'. Not to be confused with the always-on rule's `alert_type` in the YAML config — this one is informational and passes through unused.
  - `created_at` string, nullable — Producer-assigned creation timestamp (informational)
  - `event` object, required — Inner ``event`` object of a VST-style camera lifecycle event. The shape mirrors what the real producer emits; extra fields are tolerated so producers can add metadata without breaking us.
    - `camera_id` string, required — Unique camera identifier
    - `camera_name` string, nullable — Human-readable camera label. Required on `camera_streaming` (enforced by the handler); ignored on `camera_remove`.
    - `camera_url` string, nullable — RTSP URL for the live stream. Required on `camera_streaming` (enforced by the handler); ignored on `camera_remove`.
    - `camera_vod_url` string, nullable — Optional VOD RTSP URL (not used by always-on)
    - `change` 'camera_streaming' | 'camera_remove', required — Lifecycle signal: `camera_streaming` starts the configured always-on rules for this camera; `camera_remove` tears them down.
    - `metadata` object, nullable — Producer-specific metadata (informational; not used by always-on)

## Response `200`

Rules started/stopped successfully

- object
  - `reason` string, required
  - `status` string, required
  - `details` object[]

## Other responses

- `422` — Invalid payload
- `502` — All rules failed to start on RTVI VLM
- `503` — Always-on feature disabled or rules config missing

---

[API](https://skmtc.dev/nvidia/apis/alert-agent-api.md) · [All operations](https://skmtc.dev/nvidia/apis/alert-agent-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/nvidia/alert-agent-api/revisions/e754ab3efedd/schema)
