Skip to content

REST API Integration

RT Server exposes a comprehensive REST API for programmatic control and monitoring. It is the same API that powers the Web Panel and the CVEDIA-RT plugins for VMS, so anything you can do in the Web Panel you can also automate from your own applications, monitoring systems, and deployment pipelines.

This section is organized as an overview plus five task-focused tutorials:

Reference vs. tutorials

These pages are a practical, example-driven guide. For the exhaustive, auto-generated endpoint reference (every parameter and schema), use the interactive API documentation described in API reference below.

API namespaces

The REST API is served from a single host and port and is split into versioned namespaces. Every path begins with /v1/:

Namespace Prefix Purpose
RT Core /v1/core Instance lifecycle, input/output, system operations
SecuRT /v1/securt Security analytics configuration (areas, tripwires, detection options)
ONVIF /v1/onvif Camera discovery and ONVIF device management
Database /v1/database Historical analytics, event and track queries
Registry /v1/rtregistry Shared key/value store for dashboards and UI state

There is no /api prefix. The correct base path is, for example, http://localhost:3546/v1/core/instances.

Enabling and configuring the REST server

The REST server is enabled by default when running the CVEDIA-RT Windows Service, RT Studio, or CVEDIA-RT on Linux (both Docker and native).

It is configured through the web_server block of the rtconfig.json system-wide configuration file:

{
  "web_server": {
    "enabled": true,
    "ip_address": "0.0.0.0",
    "port": 3546,
    "cors": {
      "enabled": false
    }
  }
}
  • enabled - Set to false to disable the REST server (and Web Panel) entirely.
  • ip_address - Interface to bind to. Use 127.0.0.1 to accept local connections only, or 0.0.0.0 to listen on all interfaces.
  • port - TCP port for the API and Web Panel. The default is 3546.
  • cors - Cross-Origin Resource Sharing settings. See the CORS configuration reference for details.

Default endpoints

  • Base URL: http://<server-ip>:3546
  • Web Panel / interactive docs: http://<server-ip>:3546
  • OpenAPI specification: http://<server-ip>:3546/openapi.yaml
  • Engine version (health probe): http://<server-ip>:3546/v1/core/version

Authentication

By default the REST API does not require authentication. Make sure appropriate network controls are in place — bind to 127.0.0.1, restrict access at the firewall, or place the server behind an authenticating reverse proxy.

The API does accept an Authorization: Bearer <token> header where a deployment provides one, but no token is enforced in the default configuration.

Conventions

Understanding a few conventions makes the rest of this section easier to follow.

Instance identifiers

Instances are identified by a UUID (for example 2fa13902-7d9e-4e97-85e4-723f34d73f53), not by their display name. A new UUID is returned when you create an instance, and you can list existing instances and their IDs with GET /v1/core/instances.

Request and response bodies

  • Request bodies are JSON; send Content-Type: application/json.
  • Successful calls that return data respond with 200 OK; calls that succeed without a body respond with 204 No Content; instance creation responds with 201 Created.

Bodyless writes on reused (keep-alive) connections

Many write endpoints (start, stop, load, delete-all-areas, …) take no parameters. A POST/PUT/DELETE sent with no body and no Content-Length works on a fresh connection, but hangs if the connection is reused — the server keeps waiting for a body that never arrives. This bites HTTP clients that pool/keep-alive connections by default, such as axios, Python requests.Session, and the browser fetch.

The fix is to always send a body so a Content-Length is present: when a call takes no parameters, send an empty JSON object {}.

The standalone curl examples in this guide omit the body on purpose — each curl command opens its own fresh connection, so it is never affected. If you reproduce these calls with a pooled client, add the empty body, for example curl ... -d '{}', requests.post(url, json={}), or axios.post(url, {}).

The config path / jsonValue pattern

Many low-level settings are written through the instance configuration tree with POST /v1/core/instance/{instanceId}/config. The body has two fields:

  • path - the configuration key, with nested keys separated by / (for example Output/handlers/Mqtt).
  • jsonValue - the value to write, as a JSON-encoded string (the value itself is serialized into a string).
curl -X POST "http://localhost:3546/v1/core/instance/<instanceId>/config" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "Output/render_preset",
    "jsonValue": "\"Default\""
  }'

The example above writes the string "Default" to Output/render_preset. This pattern is used throughout the Configuring Exporting tutorial.

Error handling

The API uses standard HTTP status codes:

Status Meaning
200 OK Success, with a response body
201 Created Resource created (returns the new ID)
204 No Content Success, no response body
400 Bad Request Parsing error or invalid arguments
403 Forbidden Operation not allowed (for example, modifying a read-only instance)
404 Not Found Instance, area, or other resource does not exist
406 Not Acceptable Operation cannot be completed in the current state (for example, the instance is not loaded)
409 Conflict Resource already exists
500 Internal Server Error Unexpected server-side error

The most recent system-wide and per-instance errors can be retrieved with GET /v1/core/error and GET /v1/core/instance/{instanceId}/error respectively.

API reference and interactive docs

The full, auto-generated endpoint reference is available both online and on the device itself:

  • In this documentation: Core API, SecuRT API, and ONVIF API.
  • On the running server: open http://<server-ip>:3546 to browse and test every endpoint interactively, or fetch the raw specification from http://<server-ip>:3546/openapi.yaml.

CORS when testing from the documentation pages

To call a live server directly from the reference pages in your browser, either enable CORS in rtconfig.json or use a browser extension that relaxes CORS restrictions. Otherwise the browser blocks the cross-origin requests.

Securing the API with a reverse proxy

Because the API is unauthenticated by default, a common production pattern is to bind it to localhost and expose it through an authenticating, TLS-terminating reverse proxy:

server {
    listen 443 ssl;
    server_name rt-server.example.com;

    ssl_certificate     /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Require HTTP basic auth (or use your IdP / mTLS)
    auth_basic           "RT Server API";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://127.0.0.1:3546;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # Required for the SSE event stream
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        proxy_buffering off;
    }
}

The proxy_buffering off and proxy_http_version 1.1 directives are important if you proxy the SSE event stream; without them the proxy may buffer the stream and delay events.

Next steps