Supported Providers
Check a camera’scan_stream_live_video capability flag before you offer live video for it. The flag is at the top level of the device object and is true only for cameras whose provider supports live video and that are currently online.
How It Works
All three/cameras/live_views endpoints accept only a client session token. Use your API key on your backend to create that client session, then send the returned client_session.token in the seam-client-session-token header for live view requests. Your API key stays on your backend.
Authenticating a live view request directly with your workspace API key returns 401 Unauthorized. Follow Step 1 to create a client session scoped to the camera’s connected account.
Before You Begin
To stream live video, you need:- A production or sandbox workspace.
- A connected account with a Tapo, Arlo, Reolink, or UniFi Protect camera whose
can_stream_live_videoistrue. - A backend that can create client sessions with your API key.
- A browser that supports WebRTC (
RTCPeerConnection).
Step 1: Create a Client Session
On your backend, create a client session that has access to the camera’s connected account, and send its token to the browser. The live view can’t outlast the client session, so give the session a short lifetime.Live video only works with client sessions created from
connected_account_ids, connect_webview_ids, user_identifier_key, or user_identity_id. Client sessions created with customer_key can’t open a live view.can_stream_live_video is true:
false when the provider does not support live video or the camera is offline. For local cameras, the paired Seam Bridge must also be online. Check the flag again right before opening a live view.
A true flag describes device support and reported connectivity. Creating a session also depends on client-session authorization, workspace availability, and live-view capacity. Handle the live view errors even when the flag is true.
Step 2: Create a Live View Session
In the browser, call/cameras/live_views/create with the client session token in the seam-client-session-token header. A live view session reserves the camera for this viewer.
Request:
- The session ends at
expires_at, the earliest of the requested duration, the provider’s session limit, or the client session’s expiration. - The response’s
tokenauthorizes the offer and stop calls for this session only. Keep it in memory, and don’t log it. - Seam sends
Cache-Control: no-storeon all live view responses. - See the camera live view objects for the complete
camera_live_view_sessionandcamera_live_view_answerreference.
Step 3: Send a WebRTC Offer
Create anRTCPeerConnection with a STUN server, add a receive-only video transceiver, and create an offer. Wait for ICE gathering to finish, then send the local description’s SDP to /cameras/live_views/offer, along with the session ID and token.
Include the STUN server so you can use the same configuration for every camera.
JavaScript
camera_live_view_answer.sdp_answer is Seam’s WebRTC SDP answer, at most 64 KiB.
Seam connects to the camera while handling this request, so the response can take several seconds.
- One offer per session. Once you send an offer, you can’t send another one on the same session. To reconnect, create a new live view session.
- Send the offer promptly. If the stream hasn’t started within 30 seconds of creating the session, Seam closes the session.
- Match audio to
include_audio. Ifinclude_audioisfalse, the offer must not contain an audio section, so add only a video transceiver. If it’strue, also callpeerConnection.addTransceiver('audio', { direction: 'recvonly' }). - No ICE trickling. Send one offer to
/cameras/live_views/offerand apply the returned answer. There’s no endpoint for sending more ICE candidates, so wait for ICE gathering to finish (or a few seconds) and sendpeerConnection.localDescription.sdp. The SDP returned bycreateOffer()doesn’t include any candidates. - Size limit.
sdp_offercan be at most 64 KiB.
Step 4: Play the Stream
Apply the answer, then attach the incoming track to a<video> element.
JavaScript
ontrack before calling setRemoteDescription. Add autoplay, muted, and playsinline to the <video> element so that browsers start playback without a click. Unmute after a user gesture if you requested audio.
Step 5: Stop the Stream
When the user closes the viewer, close the peer connection and call/cameras/live_views/stop. This frees the camera for the next viewer right away. Always call /stop; closing the peer connection alone may leave the camera reserved until expires_at.
JavaScript
keepalive: true lets the request finish when it’s sent from a pagehide handler. Stopping a session that has already ended succeeds and returns {}.
Limits and Session Lifetime
Seam keeps checking that the viewer still has access while the stream is open. A live view ends when any of the following happens:
- The session reaches
expires_at. - You call
/cameras/live_views/stop. - The client session expires or is revoked, or it loses access to the camera.
- The camera is removed from Seam, or its connected account is deleted.
expires_at, stop the current session or wait for it to end, then create a new live view session and a new peer connection. Watch peerConnection.connectionState for failed or closed to detect the end of a stream.
Errors
For
409 and 503, wait a few seconds and create a new live view session. Retry with backoff, and stop after a few attempts.
Complete Example
This example serves a web page that plays one camera’s live feed. It uses Node.js 18 or later and theseam package.
- Run
npm install seam. - Set
SEAM_API_KEY,SEAM_CONNECTED_ACCOUNT_ID, andSEAM_DEVICE_IDto your API key, the camera’s connected account, and the camera’s device ID. - Save both files in the same directory and run
node server.mjs. - Open
http://localhost:3000and click Start.
server.mjs
server.mjs
JavaScript
index.html
index.html
HTML
Next Steps
- Camera Live Views reference: Full request and response reference for
/cameras/live_views/create,/cameras/live_views/offer, and/cameras/live_views/stop. - Retrieve event media: Get the clip and thumbnail for motion and doorbell events.
- Client session tokens: Scope client sessions to each user’s devices.
- Seam Bridge: Set up the Bridge that Tapo cameras need.