Sources
Connect RTSP or ingest test frames
A Source is a durable video input with desired state and observable runtime state. List/get responses never return passwords or unredacted RTSP URLs.
Allow the camera destination first
RTSP is default-deny. Before creating a Source, add an exact IP, host:port, or CIDR to deploy/api/.env, then recreate only the API service. Wildcards are not supported.
SENTINEL_RTSP_ALLOWED_HOSTS=192.168.10.25:554
SENTINEL_RTSP_ALLOWED_CIDRS=192.168.10.0/24
docker compose config --quiet
docker compose up -d --no-deps --force-recreate apiCreate an RTSP Source
curl -X POST http://localhost:8000/v1/sources \
-H "Authorization: Bearer $SENTINEL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: site-a-loading-dock" \
-d '{
"name": "Loading dock",
"input": {
"type": "rtsp",
"url": "rtsp://user:password@camera.local/stream2"
}
}'Submit input.url only when creating or rotating credentials. Responses expose credentials_configured and sanitized connection information, never the URL/password. Prefer a dedicated read-only camera account and low-resolution substream.
Create an image Source without a camera
POST /v1/sources
{
"name": "Integration test",
"input": {"type": "frame"}
}Test and frame ingest
POST /v1/sources/{source_id}/test
POST /v1/sources/{source_id}/frames
Content-Type: image/jpeg
Idempotency-Key: frame-20260829-001
<raw JPEG bytes>frames is a bounded test/custom-ingest path, not a video-storage API. The server checks Content-Type, byte size, JPEG decoding, and image dimensions before inference.
Retrieve the current image
GET /v1/sources/{source_id}/image?view=preview
GET /v1/sources/{source_id}/image?view=inferenceBoth return binary image/jpeg, require the same Source authorization, and use Cache-Control: no-store. A Source with no current frame returns 503. Do not treat current images as immutable Event evidence.
Bounded live preview
GET /v1/sources/{source_id}/stream?max_fps=15&max_height=720
Authorization: Bearer $SENTINEL_API_KEY
Content-Type: multipart/x-mixed-replace; boundary=frameThis endpoint returns a bounded MJPEG preview, not a recording or Event-evidence download. It requires sources:read; max_fps defaults to 15 and accepts 1–30, while max_height defaults to 0 (keep source size) and accepts 0–2160. The stream is not stored and uses Cache-Control: no-store.
Runtime states
pending | connecting | online | degraded | offline | stoppedThe API reports runtime_state, last_frame_at, and sanitized status_code/status_message so integrations can distinguish connecting, offline, and stream-error conditions. Disabling/re-enabling does not change the src_* ID.