Framework-wide status: which VIS instances are connected, which streams are running, and which detection models are available on them. These endpoints are read-only.
- Reference
- REST API
- Create a stream group config
Wowza Video Intelligence Framework API (2.0.0)
This reference documents every endpoint in the Wowza Video Intelligence Framework (VIF) REST API, including the parameters each one takes and the request and response bodies it works with. VIF adds real-time AI video analysis, such as object detection and scene recognition, to streams running on Wowza Streaming Engine, and this API is served by the Video Intelligence Controller (VIC), a module that runs alongside the Engine's own REST interface, on port 8087 by default.
Almost everything you do with this API comes down to one idea: a config, the group of settings that tells VIF how to analyze a stream (which detector to run, what to do with the results, and so on). You'll run into a config in three places, and each one uses it a little differently. A stream group config applies a config to every stream whose name matches a pattern you choose, such as cam.*. An override applies a config to one specific stream, by its exact name instead of a pattern. A running stream reports the config it's actually using right now, alongside its live connection state and performance. Wherever you see one of these documents in the reference below, look for a config member: that's where the settings live. The rest of the document, the match rule, the stream's identity, its live state, just says how that config gets used, and isn't part of the config itself.
Configs also build on each other in layers: a stream's final settings come from a default config, then a matching stream group config, then a per-stream override, then any changes made directly to the running stream. Each layer can fill in whatever the one below it left unset. The Config schema, wherever it appears in this reference, explains exactly how that merge works, including the two members, detector and listeners, that don't merge field by field like the rest.
Endpoints are grouped below by what they work with: durable configuration you save to disk, the live streams currently running, one-off video analysis jobs, connectivity checks, and framework-wide status. Each group's description explains what you'll find in it.
A few things are worth knowing before you make your first request. Every error this API returns is application/problem+json (RFC 7807), so error.title, error.status, and error.detail tell you what went wrong; the exceptions are failures the API never gets to handle, like a URL the Engine can't route or an Engine-level authentication or license failure, which come back in the Engine's own {success, code, message} format instead. Every document you can edit under /persist comes with an ETag header; send that value back as If-Match when you write, and the API answers 428 if you forget it and 412 if it's gone stale, so you never overwrite a change you haven't seen yet. PATCH requests are a JSON Merge Patch (RFC 7386), not a full replacement: send only the fields you want to change, and anything you leave out keeps its current value. Sending a field as null removes it instead, letting it inherit from whatever's underneath, except on a running stream, where null isn't accepted for config or config.active, because a running instance needs values to actually run with; use POST .../reset there if you want to discard your changes instead. The verbs you'll use are GET, POST, PATCH, and DELETE: POST creates a document (409 if one already exists by that name) or triggers an action, like resetting a stream or resuming a job; PATCH edits a document that already exists (404 if it doesn't); DELETE removes one. This API has no PUT. Wherever an endpoint isn't JSON, uploading or downloading a video file, for example, its description says so explicitly; everything else you send or receive is JSON.
Note: This is version 2 of the VIF REST API. Version 1 is deprecated, and we strongly recommend moving any integration that writes configuration to v2. Saving through v1 rewrites your configuration files in an older format: a per-stream override saved that way loses what made it an override, and comes back instead as a stream group config matched to that one stream's literal name. Reading through v1 stays safe at any time; just make sure every integration that writes configuration moves to v2, and that you don't mix the two on one installation.
The stream instances currently running. A GET here shows a stream's live, resolved configuration alongside its health and performance. Writes are ephemeral: they change only the running instance, are never saved to disk, and are lost if the stream or the Engine restarts. A 404 on any Runtime endpoint means the stream isn't currently running, not that it doesn't exist at all.
The durable configuration that lives on disk whether or not a stream is running: stream group configs, which apply automatically to any stream whose name matches a pattern, and per-stream overrides. Writing here saves the document, and if a running stream is governed by it, applies the change to that stream immediately. You can also write an override for a stream that isn't running yet; it takes effect as soon as the stream starts.
- http://localhost:8087/v2/vif/persist/stream-group-configs
- curl
- Java
- Python
- JavaScript
curl -i -X GET \
-u <username>:<password> \
''The named stream group configs. The default config is not one of them — it has no match rule and lives at /persist/configs/default; per-stream overrides live under /persist/apps/{app}/streams/{stream}.
The group's identity, and the base name of the file it is stored in. Immutable: a write that changes it is a 409, and the match rule can be rewritten without re-keying the group. default is reserved, and regex metacharacters are a 400 — the name doubles as a file name and would be silently rewritten.
Which streams are in this group.
The settings that make a stream analyze: which detector runs, what its listeners do with the results, how frames are processed, which service analyzes them, and diagnostics. Every document that carries one keeps it under a member literally named config — see "Model" in this API's description for how stream group configs, overrides and running streams each use one.
Except on a running stream, where every layer is already resolved, a config is sparse: an omitted member isn't a value, it inherits from the layer below. Most members merge field by field; detector replaces the whole section at once instead, and listeners merge per entry by name — see "Model" for why.
This group's revision, to quote as If-Match on a write. Carried on the document so a client that listed stream group configs can write one without reading it again; a single-group read repeats it in the ETag header. Server-assigned and ignored on a write.
[ { "name": "string", "match": { … }, "config": { … }, "etag": "string" } ]
Request
name, match.application and match.stream_pattern are required (400 without them). 409 when a stream group config already answers to that name, and for the reserved name default.
The group's identity, and the base name of the file it is stored in. Immutable: a write that changes it is a 409, and the match rule can be rewritten without re-keying the group. default is reserved, and regex metacharacters are a 400 — the name doubles as a file name and would be silently rewritten.
Which streams are in this group.
The settings that make a stream analyze: which detector runs, what its listeners do with the results, how frames are processed, which service analyzes them, and diagnostics. Every document that carries one keeps it under a member literally named config — see "Model" in this API's description for how stream group configs, overrides and running streams each use one.
Except on a running stream, where every layer is already resolved, a config is sparse: an omitted member isn't a value, it inherits from the layer below. Most members merge field by field; detector replaces the whole section at once instead, and listeners merge per entry by name — see "Model" for why.
- http://localhost:8087/v2/vif/persist/stream-group-configs
- curl
- Java
- Python
- JavaScript
curl -i -X POST \
-u <username>:<password> \
'' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"match": {
"application": "string",
"stream_pattern": "string",
"priority": 50
},
"config": {
"active": true,
"detector": {
"type": "scene"
},
"listeners": {
"property1": {
"type": "overlay",
"name": "string",
"enabled": true,
"trigger": "immediate",
"min_confidence": 1,
"suppress_empty": true,
"etag": "string"
},
"property2": {
"type": "overlay",
"name": "string",
"enabled": true,
"trigger": "immediate",
"min_confidence": 1,
"suppress_empty": true,
"etag": "string"
}
},
"processing": {
"inference_fps": 0,
"window_seconds": 0,
"video_height": 0,
"grayscale": true,
"frame_source": "transcoder",
"grab_interval_seconds": 0,
"buffer_frames": 0,
"auto_throttle": true,
"catch_up": {
"enabled": true,
"max_behind_seconds": 0
},
"rollup_interval_seconds": 0,
"gpu_ids": [
0
]
},
"service": {
"url": "string",
"api_key": "string",
"model_idle_timeout_seconds": 0
},
"diagnostics": {
"save_images": true,
"timing_log_seconds": 0,
"max_logged_messages": 0
}
},
"etag": "string"
}'Stream group config created.
The group's identity, and the base name of the file it is stored in. Immutable: a write that changes it is a 409, and the match rule can be rewritten without re-keying the group. default is reserved, and regex metacharacters are a 400 — the name doubles as a file name and would be silently rewritten.
Which streams are in this group.
The settings that make a stream analyze: which detector runs, what its listeners do with the results, how frames are processed, which service analyzes them, and diagnostics. Every document that carries one keeps it under a member literally named config — see "Model" in this API's description for how stream group configs, overrides and running streams each use one.
Except on a running stream, where every layer is already resolved, a config is sparse: an omitted member isn't a value, it inherits from the layer below. Most members merge field by field; detector replaces the whole section at once instead, and listeners merge per entry by name — see "Model" for why.
{ "name": "string", "match": { "application": "string", "stream_pattern": "string", "priority": 50 }, "config": { "active": true, "detector": { … }, "listeners": { … }, "processing": { … }, "service": { … }, "diagnostics": { … } }, "etag": "string" }
- http://localhost:8087/v2/vif/persist/stream-group-configs/{name}
- curl
- Java
- Python
- JavaScript
curl -i -X GET \
-u <username>:<password> \
''Stream group config.
The group's identity, and the base name of the file it is stored in. Immutable: a write that changes it is a 409, and the match rule can be rewritten without re-keying the group. default is reserved, and regex metacharacters are a 400 — the name doubles as a file name and would be silently rewritten.
Which streams are in this group.
The settings that make a stream analyze: which detector runs, what its listeners do with the results, how frames are processed, which service analyzes them, and diagnostics. Every document that carries one keeps it under a member literally named config — see "Model" in this API's description for how stream group configs, overrides and running streams each use one.
Except on a running stream, where every layer is already resolved, a config is sparse: an omitted member isn't a value, it inherits from the layer below. Most members merge field by field; detector replaces the whole section at once instead, and listeners merge per entry by name — see "Model" for why.
{ "name": "string", "match": { "application": "string", "stream_pattern": "string", "priority": 50 }, "config": { "active": true, "detector": { … }, "listeners": { … }, "processing": { … }, "service": { … }, "diagnostics": { … } }, "etag": "string" }
On-demand analysis: the video files under the Engine's content directory, and the jobs that analyze them. Unlike a running stream, a job outlives its analysis and is neither a config nor a stream. It just names the config it should use when you submit it, and keeps a record of what it actually used once it's done.