en un clic
vios
// Query VIOS REST APIs: sensor list, recording timelines, video clip extraction, snapshot capture, add/delete sensors and streams
// Query VIOS REST APIs: sensor list, recording timelines, video clip extraction, snapshot capture, add/delete sensors and streams
| name | vios |
| description | Query VIOS REST APIs: sensor list, recording timelines, video clip extraction, snapshot capture, add/delete sensors and streams |
| license | Apache-2.0 |
| metadata | {"version":"3.1.0","github-url":"https://github.com/NVIDIA-AI-Blueprints/video-search-and-summarization","tags":"nvidia blueprint operational"} |
You are a VIOS API assistant. Interact with the VIOS microservice to manage cameras/sensors, RTSP streams, recordings, snapshots, and storage. Use when asked to: add a camera, add an RTSP stream, list sensors, show configured sensors/cameras/streams, check stream status, get a snapshot, download a clip, upload a video file, or manage video storage. Always query the VIOS API directly using curl — do not navigate the UI.
This skill requires any VSS profile that brings up VIOS / VST — base (recommended), or any of lvs / search / alerts. Before any request:
Probe VIOS:
curl -sf --max-time 5 "http://${HOST_IP}:30888/vst/api/v1/sensor/list" >/dev/null
If the probe fails, ask the user:
"No VSS profile appears to be running on
$HOST_IP(VIOS unreachable). Shall I deploybaseusing the/deployskill? If you'd like a different profile, say which."
/deploy -p base (or the profile the user names). Return here once it succeeds.(If your caller has granted explicit pre-authorization to deploy
autonomously — e.g. the request says "pre-authorized to deploy
prerequisites", or you are running in a non-interactive evaluation
harness with that permission — skip the confirmation and invoke
/deploy -p base directly. Prefer base unless the request names
another profile.)
If the probe passes, proceed.
The following VIOS API paths can return HTTP 502 Bad Gateway or stale results when the host has leftover containers from an earlier deploy:
GET /vst/api/v1/sensor/listGET /vst/api/v1/sensor/<sensorId>/streamsRoot cause: the alerts compose profile (bp_developer_alerts_2d_cv /
bp_developer_alerts_2d_vlm) brings up the *-smc set of VST
microservices alongside the *-dev set, both with network_mode: host
binding the same host ports (30000 for sensor-ms, 30888 for
vst-ingress). When a subsequent base/lvs/search deploy runs, those
*-smc containers can survive past the /deploy skill's Step 0
teardown if the teardown grep doesn't catch them — and one
sensor-ms loses the port-bind race, returning 502 to anything that
proxies through vst-ingress. See
issue #151.
The /deploy skill's Step 0 teardown grep was extended to cover the
full set (sensor-ms-*, vst-ingress-*, centralizedb-*,
storage-ms-*, sdr-*, envoy-*, rtspserver-ms-*, etc.), so
fresh deploys via /deploy should not hit this. If you inherit a
host without re-deploying and see 502s, re-run /deploy to clean.
Other VIOS paths (storage/file/* upload, replay/stream/*/picture/url
snapshot, storage/file/*/url clip extraction) are unaffected.
Base URL: http://<VST_ENDPOINT>/vst/api/v1
Endpoint Resolution:
Availability Check:
curl -sf --connect-timeout 5 http://<VST_ENDPOINT>/vst/api/v1/sensor/version
Fallback:
Run all curl commands yourself — never instruct the user to run commands manually.
Auth: Optional. Most deployments run without auth. If a 401 is returned, retry with -H "Authorization: Bearer <token>" and ask the user for the token.
Start/end time handling: Any API that requires startTime/endTime:
Resolving sensorId / streamId: If the user has not provided a sensorId or streamId, look it up automatically using one of:
GET /sensor/list — lists all sensors with their sensorIdGET /sensor/{sensorId}/streams — lists streams for a specific sensor with their streamIdGET /sensor/streams — lists all streams across all sensorsGET /live/streams — lists all active live streamsGET /replay/streams — lists all available replay streamsIf a sensor has only one stream, sensorId and streamId are equal and can be used interchangeably.
| Capability | URL prefix |
|---|---|
| Version / health check | /vst/api/v1/sensor/version |
| Sensor list / info / status / add / delete | /vst/api/v1/sensor/ |
| Sensor streams | /vst/api/v1/sensor/streams, /vst/api/v1/sensor/{id}/streams |
| Network scan | /vst/api/v1/sensor/scan |
| Recording timelines | /vst/api/v1/storage/ |
| Video clip download / URL | /vst/api/v1/storage/ |
| File upload / delete | /vst/api/v1/storage/ |
| Live streams / snapshot (picture) | /vst/api/v1/live/ |
| Replay streams / historical snapshot | /vst/api/v1/replay/ |
Full API reference for the eight VIOS REST operations (version/health, sensor list, timelines, clip extraction, snapshot/picture, add sensor/stream, delete sensor, file upload/delete) lives in references/api-reference.md. Read that file when invoking any operation.
curl -s "http://<VST_ENDPOINT>/vst/api/v1/storage/file//url?startTime=&endTime=&container=mp4&disableAudio=true&expiryMinutes=" | jq .
Response: `{absolutePath, videoUrl, startTime, startTimeEpochMs, expiryISO, expiryMinutes, streamId, type: "replay"}`.
Note: `startTime` in the response reflects the actual segment boundary, which may differ slightly from the requested `startTime`.
**Query parameters for clip download/URL:**
| Parameter | Required | Description |
|---|---|---|
| `startTime` | Yes | ISO 8601 UTC. Use user-provided value, or fetch timelines first to get a valid range. |
| `endTime` | Yes | ISO 8601 UTC. Must fall within the same recorded segment as `startTime`. |
| `container` | No | `mp4` (default: `mp2t`/TS) |
| `disableAudio` | No | Always pass `true` — VIOS does not support audio for files with B-frames; disabled by default to avoid failures |
| `transcode` | No | `none` (default, fastest) or `full` (re-encode) |
| `fullLength` | No | boolean; if true, snaps to full segment boundaries |
| `expiryMinutes` | No (URL only) | minutes until URL expires, default 10080 (7 days) |
---
### 5. Snapshot / Picture
#### Live snapshot (most recent frame from sensor)
```bash
# width and height are optional; omit to use native sensor resolution (max 8000x4000)
curl -s "http://<VST_ENDPOINT>/vst/api/v1/live/stream/<streamId>/picture?width=<width>&height=<height>" \
-H "streamId: <streamId>" \
-o snapshot.jpg
Get temporary URL for live snapshot (no download, returns URL):
curl -s "http://<VST_ENDPOINT>/vst/api/v1/live/stream/<streamId>/picture/url" \
-H "streamId: <streamId>" | jq .
Response: {absolutePath, imageUrl, expiryISO, expiryMinutes, streamId, type: "live"}.
startTime: Use the value provided by the user. If not provided, first fetch timelines to find a valid range:
curl -s "http://<VST_ENDPOINT>/vst/api/v1/storage/<streamId>/timelines" | jq .Pick any timestamp within a returned
{startTime, endTime}range.
# startTime is ISO 8601 UTC — the frame closest to this timestamp is returned
curl -s "http://<VST_ENDPOINT>/vst/api/v1/replay/stream/<streamId>/picture?startTime=<startTime>" \
-H "streamId: <streamId>" \
-o snapshot_recorded.jpg
Optional: width, height query parameters (string format, e.g. width=<width>).
Get temporary URL for historical snapshot:
curl -s "http://<VST_ENDPOINT>/vst/api/v1/replay/stream/<streamId>/picture/url?startTime=<startTime>" \
-H "streamId: <streamId>" | jq .
Note:
streamIdmust be passed as both path parameter andstreamIdheader (pattern:^[a-zA-Z0-9_-]+$, max 100 chars).
Add sensor by IP (ONVIF):
# sensorIp: camera IP address; name/location are optional labels
curl -s -X POST "http://<VST_ENDPOINT>/vst/api/v1/sensor/add" \
-H "Content-Type: application/json" \
-d '{
"sensorIp": "<sensorIp>",
"username": "<username>",
"password": "<password>",
"name": "<name>",
"location": "<location>"
}' | jq .
Response: {"sensorId": "<uuid>"}.
Add sensor by RTSP URL:
# sensorUrl: full RTSP URL with credentials embedded, e.g. rtsp://<username>:<password>@<ip>:<port>/<path>
# username/password are part of the URL — do not include them separately in the body
# name: use the last segment of the RTSP URL path as the default (e.g. for rtsp://.../live/cam1, use "cam1")
curl -s -X POST "http://<VST_ENDPOINT>/vst/api/v1/sensor/add" \
-H "Content-Type: application/json" \
-d '{
"sensorUrl": "<sensorUrl>",
"name": "<name>"
}' | jq .
Optional fields for both: hardware, manufacturer, serialNumber, firmwareVersion, hardwareId, tags.
Trigger network scan for sensors:
curl -s -X POST "http://<VST_ENDPOINT>/vst/api/v1/sensor/scan" | jq .
Use this to delete sensors that are not uploaded files (e.g. RTSP streams added to VIOS):
# Returns true on success
curl -s -X DELETE "http://<VST_ENDPOINT>/vst/api/v1/sensor/<sensorId>" | jq .
This removes the sensor from all VIOS APIs but does not delete recordings from disk.
RTSP full cleanup: Calling only
DELETE /sensor/<sensorId>leaves orphaned recordings on disk. See the delete guidance in Section 8 for the complete two-step RTSP removal flow.
There are two PUT upload APIs. Use the new API (v2) for most cases.
PUT /storage/file/{filename}Filename in path, timestamp and sensorId as query params.
# filename: must not contain whitespace
# timestamp: ISO 8601 UTC, e.g. 2025-01-01T00:00:00.000Z — default when user has not specified: 2025-01-01T00:00:00.000Z
# sensorId: optional — if omitted, server generates a UUID; if provided and already exists, file is added as a sub-stream of that sensor
curl -s -X PUT "http://<VST_ENDPOINT>/vst/api/v1/storage/file/<filename>?timestamp=<timestamp>&sensorId=<sensorId>" \
-H "Content-Type: application/octet-stream" \
-H "Content-Length: <file_size_in_bytes>" \
--upload-file /path/to/video.mp4 | jq .
Key behavior:
sensorId query param: if provided, used as the sensorId (allows grouping under an existing sensor as a sub-stream); if omitted, a new random UUID is generatedContent-Length header is requiredPUT /storage/file/{filename}/{timestamp}Both filename and timestamp in the path. No query params.
# filename: must not contain whitespace
# timestamp: ISO 8601 UTC, e.g. 2025-01-01T00:00:00.000Z — default when user has not specified: 2025-01-01T00:00:00.000Z
curl -s -X PUT "http://<VST_ENDPOINT>/vst/api/v1/storage/file/<filename>/<timestamp>" \
-H "Content-Type: application/octet-stream" \
-H "Content-Length: <file_size_in_bytes>" \
--upload-file /path/to/video.mp4 | jq .
Key behavior:
sensorId query param is ignored even if passedResponse (both APIs): {id, filename, bytes, sensorId, streamId, filePath, timestamp, created_at}.
id — unique file identifiersensorId / streamId — assigned sensor and stream (auto-generated UUID if not provided)filePath — absolute path on disk where the file is storedcreated_at — epoch ms when file was uploadedDelete an uploaded file (removes physical file from disk AND removes sensor from all APIs):
# streamId: use the streamId returned in the upload response (or from sensor/{sensorId}/streams)
# startTime / endTime: use the timeline range for this streamId (fetch from /storage/<streamId>/timelines)
# Returns {spaceSaved: <MB>}
curl -s -X DELETE "http://<VST_ENDPOINT>/vst/api/v1/storage/file/<streamId>?startTime=<startTime>&endTime=<endTime>" | jq .
Identify sensor type before deleting: call
GET /sensor/<sensorId>/streamsand check theurlfield.
- If
urlstarts withrtsp://→ RTSP/IP sensor- If
urlis a file path (e.g./home/vst/.../video.mp4) → uploaded file sensorWhich delete to use:
- Uploaded file sensor — use ONLY
DELETE /storage/file/<streamId>?startTime=...&endTime=.... This deletes the physical file and removes the sensor from all APIs. Do NOT useDELETE /sensor/<sensorId>alone — it removes the sensor from APIs but leaves the physical file on disk.- RTSP sensor — use BOTH in order: first
DELETE /sensor/<sensorId>(stops recording, removes from APIs), thenDELETE /storage/file/<streamId>?startTime=...&endTime=...(deletes recordings from disk). Using only the storage delete on an RTSP sensor erases existing recordings but the sensor stays active and keeps recording.
File sensor timeline times: Uploaded file sensors report timelines relative to the timestamp provided at upload time, not the upload wall-clock time. If the default was used, timelines start at
2025-01-01T00:00:00.000Z. Always fetch the timeline first before building the delete command — never assume times based on upload time.
When the user has a sensor name or IP but needs a clip or snapshot:
curl -sf --connect-timeout 5 "http://<VST_ENDPOINT>/vst/api/v1/sensor/version"
sensorId:
curl -s "http://<VST_ENDPOINT>/vst/api/v1/sensor/list" | jq .
streamId (prefer isMain: true):
curl -s "http://<VST_ENDPOINT>/vst/api/v1/sensor/<sensorId>/streams" | jq .
curl -s "http://<VST_ENDPOINT>/vst/api/v1/storage/<streamId>/timelines" | jq .
streamId.Success with data: JSON object or array.
Success with no data: null — a null response means the API call succeeded but there is no data to return (e.g. no schedule configured, scan returned no results). It is not an error.
Success with boolean: Some endpoints return true on success (e.g. DELETE /sensor/{sensorId}).
Error: JSON object with error_code and error_message:
{
"error_code": "VMSInternalError",
"error_message": "VMS internal processing error"
}
Common codes: VMSInternalError, VMSNotFound, VMSInvalidParameter.
jq . for readability. Binary responses (clip download, snapshot) are not — they use -o <file> instead.2026-04-10T10:30:00Z or 2026-04-10T10:30:00.000Z.streamId as BOTH a path parameter AND a request header — include both./url variant to get a temporary download link rather than streaming bytes through curl.sensorId identifies a camera; streamId identifies a specific video stream from that camera (a sensor can have a main stream and sub-streams).GET /sensor/<sensorId>/streams and inspect the url field of each stream. If url starts with rtsp:// it is a live RTSP/IP camera stream. If url is a file path (e.g. "/home/vst/vst_release/streamer_videos/TruckAccident.mp4") it is an uploaded file sensor. This determines which delete flow to use — see Section 8.<VST_ENDPOINT> as a placeholder — substitute the resolved endpoint before executing.Deploy, debug, or tear down any VSS profile using a compose-centric workflow — config (dry-run) with env overrides, review resolved compose, then compose up. Use this skill when the user says "deploy vss", "deploy `profile`", "debug deploy", "verify deployment", or "why is my vss deploy broken".
Use this skill when working with the RTVI VLM or RT-VLM microservice API on VSS 3.1. Generate dense captions and alerts for stored video files and live RTSP streams via `/v1/generate_captions_alerts`; upload media via `/v1/files`; add and remove live streams with `/v1/streams/add` and `/v1/streams/delete/{stream_id}`; call OpenAI-compatible `/v1/chat/completions`; consume Kafka caption, incident, and error topics; or debug rtvi-vlm responses. For deployment, read `references/deploy-rt-vlm-service.md` first.
Summarize a video by calling the VLM NIM or the Long Video Summarization (LVS) microservice directly. For short videos (under 60s) call the VLM's OpenAI-compatible chat completions endpoint; for long videos (60s or longer) call the LVS microservice. Use when asked to summarize a video, describe what happens in a video, analyze a recording, call or debug LVS summarize/model/health/recommended-config/metrics endpoints, or configure and troubleshoot the LVS service that backs long-video summarization.
Manage and monitor VSS alerts after the alerts profile is deployed. The deployment's mode (CV vs VLM real-time) is fixed at deploy time and determines the workflow — start/stop real-time alerts via the VSS Agent on a VLM deployment, onboard CV alerts by adding RTSP streams to VIOS on a CV deployment, query incidents, customize verifier prompts. Use when asked to start/stop a real-time alert, check or list alerts, add a camera, use a sample video for alerts, customize alert prompts, or view verdicts.
Produce video analysis reports by discovering the deployed VSS agent, querying POST /generate for a timestamped captioned summary of the clip, then formatting the agent reply as the standard Video Analysis Report markdown.
Query video analytics data and metrics from Elastic search via the VA-MCP server (port 9901). This includes incidents, alerts, sensor data, and metrics. Use for any question about violations, alerts, incidents, object counts, speeds, occupancy, or anything that requires looking up recorded events. This is the primary way to answer a question that requires incidents, alerts and other metrics such as people counts and violations.