Skip to main content
List and fetch recordings for a twin or an environment, then inspect the fetched artifacts locally.

Defaults at a glance

recordings.list() deliberately narrows a request before it downloads catalog pages. Its defaults are the same for twin.recordings.list() and cw.environments.recordings.list(); twin-scoped calls additionally apply that twin filter on the server. Pass both start and end to select an older or wider UTC date range.

Twin-scoped

Environment-scoped

An environment id is always required.

Date filtering

start/end accept a date, a datetime, or an ISO 8601 string (both date-only and full datetime forms, with or without a Z/offset suffix). Provide both bounds together — a one-sided window is rejected:
With no start/end, list() checks which days have recordings and lists the most recent one, rather than the environment’s whole history. Pass an explicit window to reach older recordings.

Paging

list() fetches recordings in pages of 50 and returns at most limit (default 200). Use limit=0 to keep following pages until the window is exhausted.
filter= narrows the recordings that were fetched, so widen limit (or the date window) rather than relying on filter to search further back. Like the replay picker, list() excludes materializing or failed recordings by default. Pass include_unready=True only when those rows are needed. list() warns when it returns a partial view, so a truncated result never looks complete:
Silence them with logging.getLogger("cyberwave.managers.recordings").setLevel(logging.ERROR). If the API gateway rejects a catalog response because its payload is too large, the SDK raises RecordingPayloadTooLargeError instead of exposing the opaque platform HTTP 500. Its message includes the selected window, cloud trace, and instructions to use a shorter start/end interval or lower limit.

Types & viewers

Recording types: camera, robot, pointcloud (colored/lidar points), depth (raw depth maps), audio. A depth camera typically matches camera + depth, and also pointcloud when colored points are produced. get() downloads every artifact to a temp directory. The readers require the data extra:
The data extra installs headless OpenCV (decoding only). For GUI video playback with show_video(), also install a non-headless build: pip install opencv-python.

Contextual accessors

A fetched recording exposes only the accessors that apply to its streams — dir(rec) and autocomplete list just the relevant ones. info() is always available.
Point-cloud frames come from the on-demand Parquet (see below); if it is still being prepared, read_* raises with a “retry in a few minutes” hint.

Point clouds as Parquet

When you get() a recording, point-cloud data is downloaded as a single Parquet file (one row per frame: timestamp_us, rows, cols, dtype, and the raw frame data). read_depth() / read_pointcloud() reconstruct the frames; to read the file directly with pyarrow:
The Parquet is materialized on demand: the first time a recording is opened the server may still be preparing it. If so, get() logs a notice (“being generated / updated, retry in a few minutes”) — call get() again shortly to receive the complete file.

Playback readiness

Each recording returned by GET /api/v1/environments/{uuid}/recordings includes an optional playback_readiness object. Its top-level state tells you whether the recording is ready, materializing, or failed; its streams list gives the same detail for each available camera, robot, audio, depth, or point-cloud stream.

HTTP API defaults

GET /api/v1/environments/{uuid}/recordings and GET /api/v1/environments/{uuid}/recordings/availability share the same filters, but their defaults are intentionally different from Python recordings.list(): To apply a date window, send both start_date and end_date (or both legacy start_timestamp and end_timestamp aliases). A one-sided date query does not produce a date-window filter. Repeated twin_uuid, context, and source_type values are ORed within each kind and ANDed across kinds.

Include recordings that are not ready

Pass include_unready=false for ready recordings only. Pass include_unready=true to include recordings that are still materializing or have failed; that value requires staff/administrator access:

Browse a large catalog or populate a calendar

Pass limit to receive a stable page ordered newest-first. Follow the opaque next_cursor while has_more is true; cursors are signed and bound to the current filters, so a 400 Invalid recording catalog cursor means restart the query. limit is capped at 100.
You can repeat twin_uuid, context, or source_type; values are ORed within the same filter and combined with other filters. Source values are camera, robot, audio, depth, and pointcloud. Responses include source, twin, context, and readiness facets for the fully filtered catalog. For calendar day counts without loading media, request availability with the same filters. Use an IANA timezone when the calendar is not UTC.
Availability does not sign media URLs or probe object storage.

Retry materializing playback

GET /api/v1/environments/{uuid}/recordings/{recording_uuid}/data can return 202 Accepted when the recording is known but its playback files are not ready yet. The response includes retry_after_seconds; wait approximately that long and retry the same request instead of treating it as a missing recording.