/media/get to get the media’s status and a short-lived signed URL for downloading or playing it.
How It Works
- Seam creates a
camera.activatedevent. The event’smedia_idsarray lists one ID for each piece of media Seam expects for the event. - You call
/media/getwith amedia_id. Seam returns amediaobject with astatusand, once the media is ready, a signedurl. - You download or play the media from
urlright away. The URL expires within minutes, so call/media/getagain whenever you need a new one.
media_id, not the url. Signed URLs expire within minutes, while a media ID stays valid for about 30 days. After that, /media/get returns media_not_found for it.
Supported Providers
For Arlo and Tapo, Seam copies the clip into Seam’s private storage and extracts a JPEG thumbnail from it. Seam converts clips to MP4 with H.264 video so that browsers can play them.
Ring event clips and thumbnails are available only in the Seam Console, not through
/media/get, the API, or webhooks. See Ring Cameras.Before You Begin
To retrieve event media, you need:- A workspace with camera events and event media turned on.
- A connected account with a supported camera.
- A webhook subscribed to
camera.activated. - An API key, or a client session token that has access to the device.
Step 1: Receive a Camera Event
Subscribe your webhook tocamera.activated. Verify the webhook signature, then store the event’s media_ids along with its event_id and device_id.
Example camera.activated event:
media_idsdoesn’t guarantee any order. Call/media/getfor each ID and readmedia_typeto find the clip (video) and the thumbnail (image).media_idsis missing when Seam isn’t capturing media for the event. For example, event media might not be turned on for an Arlo or Tapo workspace, or the provider might not supply media for that event type.motion_sub_type(human,vehicle,package, orother) is included when the provider reports it.video_urlandimage_urlare still included for compatibility. They point to/media/getwithformat=redirect, and requests to them need the same authentication as any other Seam API request. New integrations should usemedia_ids.
Media usually isn’t ready when the event arrives. Seam sends the event first, and then retrieves the recording in the background.
Step 2: Get the Media
Call/media/get with a media_id. The default format is json, which returns the media object.
Request:
Media Object
See the media object reference for the complete property list.
The response has no field for when
url expires, and the lifetime varies by provider. Treat every URL as valid for only a few minutes, and call /media/get again for a new one rather than caching it.
Media Statuses
pending is the only status that changes. After the media’s expires_at passes, /media/get returns a media_not_available error for it. About 30 days after the event, Seam deletes the media record entirely, and /media/get returns media_not_found.
Step 3: Wait for Pending Media
Seam can’t retrieve an Arlo or Tapo recording until the provider finishes it, so media often stayspending for a minute or more after the event. Seam doesn’t send an event when media becomes available, so poll /media/get with backoff:
- Wait about 15 seconds after the event before the first request.
- Double the delay after each
pendingresponse, up to 30 seconds between requests. - Stop after about 10 minutes and treat the media as unavailable.
- Poll from a background job, not from the webhook handler. Return a
2xxfrom the webhook handler as soon as you store the event.
JavaScript
Step 4: Use the Signed URL
Theurl is a signed, short-lived link to the media file. It expires within minutes, and the exact lifetime varies by provider. The response doesn’t say when: expires_at is when the media itself stops being available, not when the URL expires.
- Don’t store the URL. Store the
media_idand call/media/getwhen you need a URL. - Request a new URL when playback fails. A video player can request byte ranges from the URL long after the page loads, for example when the user seeks. If the player reports an error, call
/media/getagain and set the new URL as the source. - Keep the URL private. Anyone who has the URL can download the media until it expires. Don’t log it or put it in analytics events.
- Keep your own copy if you need it longer. Seam keeps stored Arlo and Tapo media for 7 days, and
expires_attells you when. After that,/media/getreturnsmedia_not_available.
JSON vs. Redirect
/media/get accepts a format parameter:
Browsers can’t add an
Authorization header to an <img> or <video> element’s request, so you can’t point one straight at /media/get. In a browser, request the JSON format with your client session token, then set the returned url as the element’s src. This works for media that Seam stores, such as Arlo clips:
JavaScript
cURL
302. See Errors.
Authorization
/media/get accepts the same credentials as other Seam read endpoints: an API key, a personal access token with a workspace, or a client session token.
A client session can only get media for the devices it has access to. That is, devices in the connected accounts, Connect Webviews, or user identity that you associated with the client session when you created it, or, for a client session created with a customer_key, that customer’s devices. For any other device’s media, Seam returns media_not_found, the same error it returns for an ID that doesn’t exist, so a client can’t probe for media in other accounts.
Use client sessions to show media in your users’ browsers or mobile apps without exposing your API key.
Errors
Provider Notes
TP-Link Tapo
- Seam retrieves the clip from the camera’s microSD card through the paired Seam Bridge, so the Bridge and the camera must stay online after the event.
- Seam needs the Tapo account password, which is the password for the Tapo app, not the Camera Account password. Enter it in the optional Tapo account password field of the Connect Webview. For a camera connected without it, media ends up
unavailable. To add it, reconnect the camera. Recordings start with the next motion event. See Tapo event recordings. - Without a microSD card, or when the card has no recording that contains the event, the media ends up
unavailable. - The sandbox Tapo camera has no microSD recordings.
UniFi Protect
- Seam retrieves a 20-second clip (5 seconds before and 15 seconds after the start of the event) from the console’s own recordings, through the paired Seam Bridge. The clip comes from the camera’s high-quality channel and is an H.264 MP4 file. Seam creates the thumbnail from the clip. In Seam’s testing, the clip was available about 30 seconds after the motion started.
- Seam needs a local-only UniFi user with View Only Protect access. Enter it in the optional local user fields of the Connect Webview. Without it, events still arrive, but their media ends up
unavailablewith a reason. A UniFi cloud account can’t be used. See UniFi Protect event clips. - Because clips come from the console’s own storage, the console must be recording the camera.
Arlo
- Seam retrieves the clip from the Arlo cloud library. Without a subscription that includes cloud recording, Arlo stores no recording, and the media ends up
unavailable. - Arlo clips are often recorded in HEVC. Seam converts them to H.264 so that browsers can play them.
Next Steps
- Get Media: Full request and response reference for
/media/get. - Stream live video: Watch a camera’s live feed in the browser over WebRTC.
- Webhooks: Receive and verify camera events.
- Client session tokens: Give your users’ browsers scoped access to their devices.