Skip to main content
By default you publish video into a Stream yourself: POST /streams hands back LiveKit credentials, and your client joins the room and pushes frames. A camera source inverts that. You pass a url, and the server connects to it and pulls the video. Nothing runs on your side, and there is no publisher to keep alive. Use this for fixed cameras — an IP camera, an NVR feed, a public HLS stream — where no browser or app is in the loop.

Create a Stream from a url

Pass a source object:
The response carries publish: null — there is no client publisher — and reports the source type:
The url is never returned in any response, because rtsp urls commonly carry camera credentials.

The camera must be publicly reachable

The server connects to your url from our infrastructure, so the camera needs a publicly routable address. Urls that resolve to private, loopback, or link-local addresses are rejected — 192.168.x.x, 10.x.x.x, localhost, 169.254.x.x. A camera on an office LAN will not connect. To use one, give it a public path first: a port forward, a static public IP, or a tunnel that exposes it on a public hostname. If none of those are available, publish into the Stream from inside your network instead.

Confirm frames are arriving

A 201 means the source opened. It does not yet mean frames are flowing. GET /streams/{stream_id} returns last_pull, the timestamp of the most recent frame pulled from the source:
A last_pull that keeps advancing means the pull is healthy. A last_pull that is null, or frozen seconds in the past, means the source has gone quiet — distinct from the Stream having failed, and worth separating in your monitoring.

Ask questions

Identical to any other Stream. Reference it with an ovs:// url:

Watch the feed

The server republishes the pulled video into the Stream’s LiveKit room, so you can watch exactly what the model sees. Request a viewer token and subscribe with any LiveKit client. Nothing has to be watching for the pull to run.

When the source drops

If the camera disconnects, the server reconnects on its own, backing off from 1 second to a maximum of 30 seconds between attempts. Brief network blips recover without action from you. A source that ends cleanly is treated differently from one that drops. If the video ends, and ends again shortly after a reconnect, the server treats the source as finished and ends the Stream rather than retrying indefinitely. A finite video file served over RTSP behaves this way.

Errors

A 422 means the source could not be opened. The server retries for roughly 15 seconds before returning it, so a failing request takes about that long.
Check, in order:
  • The host is reachable from the public internet
  • Credentials in the url are correct
  • type matches the scheme — rtsp needs rtsp:// or rtsps://, hls needs http:// or https://
  • The hostname resolves

Keepalive and teardown

Unchanged from any other Stream. Renew the lease with /keepalive, and DELETE the Stream when finished — that stops the pull. The keepalive response also carries publish: null for camera sources.