Screens
A screen is one Player. These commands read it, point it at a playlist, and manage its life. Revision preconditions are optional on writes.
Tags group screens into fleets. Each screen carries 0 to 16 unique tags of 1 to 32 letters or digits, set with screen tag. screen assign, screen reload, screen toast, screen tag, and screen screenshot take one screen id, several ids, or --tag TAG, and a fleet answer reports every screen: see Fleet results.
Screen folders group screens by place, one folder per screen. A fleet command also takes --folder ID: see Screen folders.
A screen in a protected folder answers a playlist change with pending_review for a second approver, and refuses tag, field, location, timezone, wall, replace, delete, archive, suspend, display, volume, toast and play-page changes with protected_target (exit 5).
A storage_full warning on screen list, screen show, screen update, screen assign or screen publish means the device running the Player has no room for its content: free up storage there, then retry.
screen pair#
Pair a Player with the code shown on its screen.
screen pair <code...> [--name NAME] [--folder ID]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<code...> | string | yes | none | The six-character pairing code the Player shows. Spaces, dashes and letter case are ignored, so a code shown in two groups works with or without quotes. |
--name NAME | string | no | an unused Screen N | Display name for the screen, 1 to 120 characters. |
--folder ID | string | no | project root | The sfd_ screen folder to put the screen in. An agent limited to screen folders must name a folder of its scope; the project root and every other folder answer outside_screen_scope (exit 3). |
screenrig screen pair "$PAIRING_CODE" --name "Lobby"
screenrig screen pair "$PAIRING_CODE" --folder sfd_01EXAMPLEFOLDER000000000The answer carries public_url and the paired screen. The Player finishes pairing the next time it contacts the service, with nothing to do on the display: screen show reports state active and online true once it has. After an interrupted request, rerun the identical command to reuse the saved idempotency key.
browser setup#
Complete a browser Player's setup from the code it shows.
browser setup --code CODE [--open]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
--code CODE | string | yes | none | The setup code the browser Player shows. |
--open | boolean | no | off | Open the browser Player. |
screenrig browser setup --code SETUP_CODE --openThe answer carries code, status (claimed), screen_id and the screen's player_public_url. The CLI withholds a URL that fails its safety checks, with the warning player_url_withheld. An invalid or expired code creates no screen. After an interrupted request, rerun the identical command.
screen list#
List screens. Archived screens are omitted unless you ask for them.
screen list [--state archived] [--tag TAG] [--folder ID|root] [--field NAME=VALUE...] [--near LAT,LON,KM]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
--state | string | no | active screens | The only accepted value is archived, which lists archived screens only. |
--tag TAG | string | no | every screen | Lists only screens carrying this exact tag. |
--folder ID|root | string | no | every screen | Lists only the screens directly inside this sfd_ screen folder, not those of its subfolders, or with root only screens outside every folder. |
--field NAME=VALUE | string | no | none | Lists only screens whose field NAME holds exactly VALUE. Repeatable, each name once; a screen must match every one. |
--near LAT,LON,KM | string | no | none | Lists only screens located within KM kilometres of the point, in decimal degrees; KM is above 0. A screen with no location is left out. |
screenrig screen list --tag Lobby
screenrig screen list --folder sfd_01EXAMPLEFOLDER000000000
screenrig screen list --field region=north
screenrig screen list --near 47.6062,-122.3321,25The filters combine. Each row carries the screen's tags, folder_id, fields and location when it has them. With --human, the table adds a column only when a listed screen has the value: PLATFORM, REASON (an archived screen's archive_reason), TAGS, FOLDER, FIELDS, LOCATION, ASSIGNED (a screen that plays something other than its default playlist), HEALTH (a screen that needs attention) and UPGRADE (a screen whose Player is still switching to the issued playlist version, or failed to). --state archived also lists screens a Player archived itself (device_reset, device_unpair) and screens screen replace archived (replaced).
screen show#
Read one screen, including revision, assignment, and liveness.
screen show <id>| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
screenrig screen show scr_01EXAMPLESCREEN00000000tags lists the screen's fleet tags. effective_playlist, takeover, and playlist_schedule report what the screen plays and why; see Schedules and takeover. health and the Player's host capabilities are in Device health and power. online is true while a Player is connected, including a short reconnect window. Optional last_online_at and last_ip appear after the first connect. Optional observation reports the surfaces a Player has painted: id, width, height, pixel_ratio, and presentation. All of these are read-only; screen update cannot send them, and an archived screen still returns its row.
commands lists the screen's last 10 reboots, reloads, cache clears, app restarts and updates, oldest first, each with its type, its state (queued, sent, done, failed, expired, cancelled, or superseded), its source (schedule for a reboot a reboot schedule issued; absent for one a person asked for), its expires_at, and when it was sent or done. reboot_schedule and next_reboot_at report the screen's reboot schedule and the start of its next reboot window. A cache clear, app restart or update the Player ended also carries its cause and a short detail, which --human prints as a CAUSE column and a line under the table. suspension carries the message and since of a suspended screen. A screen archived by screen replace reports replaced_by, the screen its device moved to. With --human, screen show prints each of them.
last_outage reports the screen's latest outage: offline_since, back_at and duration_s, and, once a health report decides it, a likely_cause of device_restart, app_crash, app_restart, network or platform; it is absent when screenRIG cannot tell. A restart is decided as the screen comes back, while a network or screenRIG cause waits for the Player's next health report, which can take up to fifteen minutes. glass carries the verdicts screenRIG drew from the screen's play reports and screenshots. With --human, screen show prints Last outage and Likely cause, and Playlist stalled, Blank screen or Frozen picture for a verdict that found a problem; Notifications says what the verdicts leave alone.
folder_id names the screen's folder and is absent at the project root. fields, location and wall appear once set: see screen update and screen wall set. Each observation.surfaces entry also carries rotation when the Player can read it, and a video wall reports one entry per output, named as screen wall set takes them.
manifest_upgrade reports whether the Player has switched to the playlist version issued to it. Its state is none, pending, downloading, preparing, activating, retrying, failed, blocked, partial or current, beside desired_playlist and active_playlist (id, name and revision), the last version the Player acknowledged, which does not prove that every session shows it. A failing or partial upgrade also carries code, attempt, retry_at and missing_page_count. --human prints Target v42 · Playing v41. A failed upgrade schedules no retry: fix the cause, then run screen reload or assign the playlist again. A saved assignment does not confirm playback.
applications_unsupported appears while the paired Player cannot show application or iframe pages: the manifest is unchanged and the Player skips them. recovery_pending appears while a display that lost its stored identity offers to reconnect as this screen, with the expires_at of the offer and the platform, model, firmware and manufacturer the display reports: see screen recover.
screen update#
Patch a screen's name, playlist assignment, timezone override, fields, or location in one call.
screen update <id> [--name NAME] [--playlist-id ID | --clear-playlist] [--timezone ZONE | --clear-timezone] [--field NAME=VALUE...] [--unset-field NAME...] [--clear-fields] [--location LAT,LON [--location-name NAME] [--address TEXT] | --clear-location] [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--name NAME | string | no | unchanged | Display name for the screen. |
--playlist-id ID | string | no | unchanged | The pl_ playlist this screen should run. Not with --clear-playlist. |
--clear-playlist | boolean | no | off | Clears the screen's own default assignment. Pairing and every other content level stay, and the screen shows idle when none applies. An archived screen answers screen_archived. Not with --playlist-id. |
--timezone ZONE | string | no | unchanged | Overrides the screen's time zone with an IANA zone identifier such as America/Los_Angeles. Validated against the server's zone database. Not with --clear-timezone. |
--clear-timezone | boolean | no | off | Removes the override, so the screen follows the zone its device reports again. Not with --timezone. |
--field NAME=VALUE | string | no | unchanged | Sets one field and leaves the others. Repeatable, each name once. NAME is 1 to 32 lower case letters, digits or underscores, VALUE is 1 to 200 characters after trimming, and a screen holds at most 32 fields. Not with --clear-fields. |
--unset-field NAME | string | no | unchanged | Removes one field. Repeatable. Not with --clear-fields. |
--clear-fields | boolean | no | off | Removes every field. Not with --field or --unset-field. |
--location LAT,LON | string | no | unchanged | Where the screen is, in decimal degrees: latitude from -90 to 90, longitude from -180 to 180. Replaces the whole location, so repeat --location-name and --address to keep them. Not with --clear-location. |
--location-name NAME | string | no | none | The short place name a card shows, 1 to 40 characters. Requires --location. |
--address TEXT | string | no | none | An address for people and agents, 1 to 200 characters. Requires --location. |
--clear-location | boolean | no | off | Removes the location. Not with --location. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
Provide at least one of --name, --playlist-id, --clear-playlist, --timezone, --clear-timezone, --field, --unset-field, --clear-fields, --location or --clear-location.
screenrig screen update scr_01EXAMPLESCREEN00000000 --name "Lobby"
screenrig screen update scr_01EXAMPLESCREEN00000000 --field store_number=0142 --field region=north
screenrig screen update scr_01EXAMPLESCREEN00000000 --location 47.6062,-122.3321 --location-name "Seattle HQ"
screenrig screen update scr_01EXAMPLESCREEN00000000 --clear-playlist --expect-rev 3Under review, a change of --playlist-id alone is proposed like screen assign; a Propose session cannot change the other fields.
Changing fields or location changes the screen's manifest revision, so a screen that shows a playlist picks up the new values. Cards and iframe pages read them per screen, so one playlist shows each screen's own values: {screen.field.NAME}, {screen.name} and {screen.timezone} fill any text param of a card, "location": "{screen.location}" fills a card's location in the shape that card takes, and a card data key may carry {screen.field.NAME}, such as menu-{screen.field.store_number}. A screen that lacks a field shows that text empty, and the card goes without that data key or location. screen show lists a screen's fields and location, and screen list finds screens by them. See Screen tokens in iframe addresses and application params.
screen publish#
Create a new playlist from a prepared file and assign it to a screen.
screen publish <id> <file> [--expect-rev REVISION] [--note TEXT] [--no-wait] [--poll-ms MS] [--timeout MS] [--no-progress]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
<file> | path | yes | none | The prepared playlist document, or - for stdin. |
--expect-rev REVISION | string | no | none | Optional screen revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
--no-wait | boolean | no | off | Return after assignment without waiting for the Player to show the playlist. |
--poll-ms MS | integer | no | 2000 | Interval between screen polls while waiting. |
--timeout MS | integer | no | 120000 | Deadline for the wait. It also bounds each underlying request. |
--no-progress | boolean | no | off | Suppress the stage lines on stderr. |
screenrig screen publish scr_LOBBY lobby.jsonThis creates a new playlist and assigns it. It does not update an existing playlist by name. Inspect the prepared document first. Repeat identical input to resume an ambiguous failure. Assignment readback does not prove playback; request a screenshot separately. Under review it returns stage: pending_review with both reviews. See Prepare, publish, and edit playlists.
After assignment the command waits until the Player shows the playlist: data.stage is playing and data.playback_verified is true. Stage changes print to stderr as they happen, as JSON lines or, with --human, as text. Repeating the identical command after a publish finished reports that publish (data.already_published) while the screen still shows its playlist, and publishes afresh once the screen has moved on.
screen assign#
Point a screen, or a fleet of screens, at a playlist.
screen assign (<id>... | --tag TAG | --folder ID) --playlist-id ID [--expect-rev REVISION] [--note TEXT]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | one of <id>, --tag or --folder | none | One or more scr_ screen ids. Several ids run as one fleet request. |
--tag TAG | string | one of <id>, --tag or --folder | none | Every active screen carrying this tag. |
--folder ID | string | one of <id>, --tag or --folder | none | Every active screen in this sfd_ screen folder and the folders inside it. |
--playlist-id ID | string | yes | none | The pl_ playlist to run. |
--expect-rev REVISION | string | no | none | One screen id only. Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
screenrig screen assign scr_01EXAMPLESCREEN00000000 --playlist-id pl_01EXAMPLEPLAYLIST000000
screenrig screen assign --tag Lobby --playlist-id pl_01EXAMPLEPLAYLIST000000
screenrig screen assign --folder sfd_01EXAMPLEFOLDER000000000 --playlist-id pl_01EXAMPLEPLAYLIST000000A playlist that schedules pages assigns to any screen: the schedules are read in the screen's own timezone (its override, else the zone its device reports, else UTC).
To publish to a fleet, create the playlist once with playlist create, then run screen assign --tag TAG --playlist-id ID. screen publish targets one screen.
Under Propose access, or in a project that requires review for agent changes, the change to one screen or to the whole fleet answers pending_review instead: data.review carries the review id and its dashboard url, a pending_review warning names the url, and data.next is reviews show ID. Nothing changes on glass until a person approves it, so do not repeat the write. On a screen in a protected folder this answers pending_review at every access level, and an approver other than you and other than the person you work for decides it (second_approver_required, exit 3, otherwise). A caller limited to screen folders assigns only on screens of its scope. A saved assignment does not confirm playback; screen screenshot shows the glass.
screen set-timezone#
Override the time zone a screen's civil rules are read in, or remove the override.
screen set-timezone <id> (--timezone ZONE | --clear) [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--timezone ZONE | string | one of --timezone or --clear | none | Overrides the screen's time zone with an IANA zone identifier such as Europe/Berlin. |
--clear | boolean | one of --timezone or --clear | off | Removes the override, so the screen follows the zone its device reports again. Not with --timezone. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen set-timezone scr_01EXAMPLESCREEN00000000 --timezone America/Los_Angeles
screenrig screen set-timezone scr_01EXAMPLESCREEN00000000 --clearEvery screen has an effective timezone, and every civil rule reads it: page visibility, ad slots, playlist schedules, takeovers, campaigns, display and reboot schedules, and {screen.timezone}. It is this override, else the zone the screen's Player reports from its device, else UTC. A screen needs no override while its device reports the right zone. screen show prints the effective zone as Timezone with where it comes from, effective_timezone and timezone_source (screen, device or default) in --json. Changing the effective zone remints the manifest revision.
ZONE is Area/City, such as America/New_York or Asia/Tokyo, or UTC.
screen wall set#
Set the video wall of a screen: one Player driving two to twelve displays as one canvas.
screen wall set <id> --outputs NAMES --arrangement row|column|grid [--columns N] [--rotation 0|90|180|270] [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--outputs NAMES | string | yes | none | Two to twelve comma-separated output names in physical order, left to right then top to bottom, as screen show lists them under observation.surfaces, such as HDMI-A-1,HDMI-A-2. Each is 1 to 64 letters, digits, dots, underscores or dashes, listed once. |
--arrangement ARRANGEMENT | string | yes | none | row (one row, left to right), column (one column, top to bottom) or grid (rows of --columns outputs, top to bottom). |
--columns N | integer | yes, for grid | none | Outputs per row of a grid: 2 to 6, dividing the outputs into at least 2 rows. Refused for row and column. |
--rotation DEGREES | string | no | 0 | Clockwise rotation of every output: 0, 90, 180 or 270. 90 and 270 are portrait panels. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen wall set scr_01EXAMPLESCREEN00000000 --outputs HDMI-A-1,HDMI-A-2 --arrangement row
screenrig screen wall set scr_01EXAMPLESCREEN00000000 --outputs DP-1,DP-2,DP-3 --arrangement row --rotation 90 --expect-rev 4
screenrig screen wall set scr_01EXAMPLESCREEN00000000 --outputs DP-1,DP-2,DP-3,DP-4,DP-5,DP-6 --arrangement grid --columns 3One Player drives the displays as one wall, so a playlist page spans all of them. The set replaces the whole wall, so repeat --rotation and --columns to keep them. Only the Linux Player's kiosk install and the Windows Player declare the display.wall capability; any other Player answers wall_unsupported (exit 5) and nothing changes. Propose access cannot change a wall (insufficient_access). A wall of 2 or 3 displays needs Plus or above and a wall of 4 to 12 displays Enterprise: a plan without it answers feature_not_in_plan (exit 8), while screen wall clear and a set that keeps the stored wall stay open. See Video walls.
Author the playlist for the wall's shape with playlist init and the screen's id, which writes the matching canvas and format (displays, arrangement, orientation, and columns for a grid). A primitive's displays, such as [2] or [1, 2, 5, 6], name the display numbers it covers, counted from 1 left to right then top to bottom, and must fill a rectangle of the wall. Assigning a playlist whose format is not the wall's shape is playlist_format_mismatch (exit 5); a playlist without a format plays the same on every display. Once the screen plays a playlist with a matching format, every display shows its number and name for 20 seconds after a change, so you can check the order on glass.
screen wall clear#
Remove a screen's video wall.
screen wall clear <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen wall clear scr_01EXAMPLESCREEN00000000The assigned playlist is not re-checked: if it has a format, the screen's manifest degrades (wall_format_mismatch) and the Player keeps its last good page until you assign a playlist without a format. A screen without a wall answers unchanged. Propose access cannot change a wall (insufficient_access).
screen archive#
Hide a screen and darken its glass.
screen archive <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen archive scr_01EXAMPLESCREEN00000000Archiving hides the screen from the default listing and darkens the glass. It does not unbind the Player.
Whoever holds the display's key can still connect while the screen is archived. To retire hardware for good, leave the screen archived, or move the screen to new hardware with screen recover or screen replace, which retire the old key.
screen unarchive#
Restore an archived screen to the default listing.
screen unarchive <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen unarchive scr_01EXAMPLESCREEN00000000A Player can also archive its own screen: a confirmed reset on a Player that holds a key, or unpairing a browser Player paired by cookie. screen show then reports archive_reason as device_reset or device_unpair (project for an archive you request), with archived_at. The screen keeps its device binding for every reason, so a Player that still holds that key or device cookie stays dark and resumes on unarchive with no re-pairing. The Player that was reset or unpaired drops its key or cookie and pairs again as a new screen. A key replaced by a confirmed screen recovery stays retired.
A screen archived as replaced by screen replace keeps no device binding, so unarchive refuses it and screen delete removes it.
screen suspend#
Show a notice on a screen instead of its content, until it is resumed.
screen suspend <id> --message TEXT [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--message TEXT | string | yes | none | The notice the screen shows: 1 to 280 characters after trimming. Line feed is the only control character, and the Player wraps the text and keeps its line feeds. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen suspend scr_01EXAMPLESCREEN00000000 --message "Closed for stocktake. Back at 9am."A suspended screen shows the message in place of its content. Nothing else changes: its playlist, schedule, takeover, and display control stay and keep evolving, and screen resume shows what the screen would be showing now. screen show reports suspension with the message and since; suspending a suspended screen replaces the message and keeps since. Suspending bumps the screen revision, and the Player refetches at once. An archived screen answers screen_archived.
screen resume#
End a screen's suspension so it shows its own content again.
screen resume <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen resume scr_01EXAMPLESCREEN00000000Resume shows the screen's own content again, from what the screen would be showing now, and the Player refetches at once. A screen that is not suspended answers unchanged, with no revision change. An archived screen answers screen_archived.
screen delete#
Delete a screen.
screen delete <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen delete scr_01EXAMPLESCREEN00000000Delete removes a screen only while no Player key is bound to it, and screen show reports deletable: true for that screen. A Player that pairs by code, a native Player or the browser Player, holds a key, and the key stays bound to its screen, so deleting that screen answers 409 screen_archive_required (exit code 5): archive it instead. Only a browser Player paired by cookie holds no key, and its screen deletes whether it is paired or still pending.
To pair a display that holds a key as a new screen, confirm a reset on the Player itself, then claim the code it shows with screen pair; the old screen stays archived. To move a screen to replacement hardware, use screen recover, or screen replace when that hardware is already paired as its own screen.
screen recover#
Reconnect a display that lost its stored identity to the screen it was paired as.
screen recover <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen show scr_01EXAMPLESCREEN00000000
screenrig screen recover scr_01EXAMPLESCREEN00000000A display that lost its stored identity and now reports this screen's hardware identifiers while pairing makes an offer. screen show reports it as recovery_pending with its deadline and, when the display reports them, its platform, model, firmware and manufacturer. Nothing is rebound until this command confirms it: the screen keeps its label, playlist, timezone, schedules, and history, and the display's new key replaces the previous one, which retires after a fifteen-minute grace window. A screen archived by a device reset stays archived until screen unarchive.
Compare the reported model and firmware with the display you expect before confirming: any application running on a display can read its identifiers, so the offer alone does not prove which display is asking. The service refuses an offer while the screen's current Player is still online, and a screen accepts at most three offers an hour. Without an offer the command answers recovery_not_offered, an offer whose pairing session lapsed answers recovery_expired, and identifiers attached to more than one screen answer recovery_ambiguous; nothing is rebound. Recovery never crosses projects.
screen replace#
Move the device paired as another screen onto this screen, keeping this screen's settings and history.
screen replace <id> --with ID [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen to keep. |
--with ID | string | yes | none | The scr_ screen whose paired device takes over. It must be another screen of the project. |
--expect-rev REVISION | string | no | none | Optional revision precondition on the screen to keep. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen replace scr_01EXAMPLESCREEN00000000 --with scr_01EXAMPLENEWSCREEN000000Pair the new hardware as its own screen first, then replace. The device's key, or a browser Player's credential, now opens <id>, which keeps its name, tags, timezone, playlist, schedules, takeover, display schedule and override, video wall, comments, fields, location, and history, and takes the replacement's host and Player. Its health, status, storage, and queued commands start over. The screen named by --with is archived with archive_reason replaced and replaced_by naming <id>. It keeps no device binding, so screen unarchive cannot restore it and screen delete removes it. The key <id> held retires after a fifteen-minute grace window, then its old device is refused. Both screens must be active with a paired Player: a screen still waiting to pair answers resource_conflict, an archived one answers screen_archived, and a video wall needs a replacement Player that declares display.wall (wall_unsupported). The request always carries an idempotency key, and an exact retry returns the original answer.
To move a display that lost its stored identity and now reports this screen's identifiers, use screen recover.
screen rotate-public-id#
Issue a new public id for a screen.
screen rotate-public-id <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen rotate-public-id scr_01EXAMPLESCREEN00000000The screen's public_id, the credential in its public URL, is replaced and every session opened with the old one ends. The Player's pairing is kept: a paired Player opens a new session and keeps showing its content.
screen link create#
Create a screen's link, or replace it, and print its Player URL.
screen link create <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. The screen is active: its Player has paired once with its code. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen link create scr_01EXAMPLESCREEN00000000Prints data.url, the Player URL (https://play.screenrig.ai/player/#screen=…) to paste as the URL of a browser source in vMix or OBS, which keeps no storage and would otherwise lose its pairing on every load. The Player runs from the URL on every load: the URL is the whole pairing. Creating the link again replaces it (data.replaced is true): the old URL stops working at once and the Player opened from it shows a notice with no content. The URL is a credential that opens the screen: it is printed under a sensitive label, kept out of the operation log, and shown again by screen link show. Open it in one place. A screen that has not paired answers resource_conflict (exit code 5), and an archived screen answers screen_archived. After an interrupted request, rerun the identical command: it reuses the saved idempotency key and returns the same link.
screen link show#
Print a screen's link and its Player URL.
screen link show <id>| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
screenrig screen link show scr_01EXAMPLESCREEN00000000Prints data.url under a sensitive label with data.hint (the last four characters of the secret), data.created_at and data.last_used_at once a Player has opened the link. A Read only credential receives url empty with url_redacted true, and human output says the URL is withheld; a Manage sign-in receives it. A screen without a link answers screen_link_not_found (exit code 4) and names the command that creates one. screen show prints Screen link: on (…HINT) for a screen that has one, and never its URL.
screen link delete#
Turn a screen's link off.
screen link delete <id> [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
screenrig screen link delete scr_01EXAMPLESCREEN00000000The URL stops working at once and every session it opened ends: a browser source still showing it shows a notice and no content until it is given a new URL. The screen, its pairing and its content are untouched. It succeeds, changing nothing, when the screen has no link.
screen reload#
Ask a screen's Player, or every Player in a fleet, to reload once.
screen reload (<id>... | --tag TAG | --folder ID) [--expires-in DURATION] [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | one of <id>, --tag or --folder | none | One or more scr_ screen ids. Several ids run as one fleet request. |
--tag TAG | string | one of <id>, --tag or --folder | none | Every active screen carrying this tag. |
--folder ID | string | one of <id>, --tag or --folder | none | Every active screen in this sfd_ screen folder and the folders inside it. |
--expires-in DURATION | string | no | 24h, applied by the server | How long the request waits for an offline screen to come online: 90s, 30m, 2h, or 1d, from 60s to 24h. |
--expect-rev REVISION | string | no | none | One screen id only. Optional revision precondition. |
screenrig screen reload scr_01EXAMPLESCREEN00000000
screenrig screen reload scr_01EXAMPLESCREEN00000000 --expires-in 2h
screenrig screen reload --tag Lobby
screenrig screen reload --folder sfd_01EXAMPLEFOLDER000000000The answer carries a reload_id, a state, and an expires_at. A screen that is online is sent the reload at once (state sent); an offline screen holds it queued and is sent it when it comes online before expires_at, 24 hours after the request unless --expires-in says otherwise. A newer reload supersedes one still queued, screen show lists the screen's commands, and screen command cancel cancels one still queued. In a fleet, each result's reload carries the same state. A web Player reloads at its next page boundary; a native Player reconnects, refetches its manifest, and checks for an update. A Player ignores a reload within ten minutes of the last one it acted on. Reload works on active and archived screens and does not change the screen revision.
screen toast#
Post one transient message as stage chrome on a live screen or a fleet.
screen toast (<id>... | --tag TAG | --folder ID) --text TEXT [--level info|alert|error] [--duration-ms MS]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | one of <id>, --tag or --folder | none | One or more scr_ screen ids. Several ids run as one fleet request. |
--tag TAG | string | one of <id>, --tag or --folder | none | Every active screen carrying this tag. |
--folder ID | string | one of <id>, --tag or --folder | none | Every active screen in this sfd_ screen folder and the folders inside it. |
--text TEXT | string | yes | none | One to 120 characters, line feed as the only break, at most three lines. |
--level LEVEL | string | no | info | info, alert, or error. A screen can set the lowest toast level it shows, and error toasts always show. A Player shows a toast on one line, a line feed as a space. Command success does not establish visibility. |
--duration-ms MS | integer | no | 60000, applied by the server | Between 2000 and 60000 when supplied. |
screenrig screen toast scr_01EXAMPLESCREEN00000000 --text "Lobby closed"
screenrig screen toast --tag Lobby --text "Closing in ten minutes"
screenrig screen toast --folder sfd_01EXAMPLEFOLDER000000000 --text "Closing in ten minutes"A toast is not a primitive: it occupies no canvas slot, has no layer, and takes no part in readiness or crossfade. Latest wins, there is no queue and no cancel, and the accepted envelope is { expires_at } only. Never put credentials or other secret material in the text.
screen identify#
Show a screen's name over its content for a while, to find it on site.
screen identify <id> [--duration DURATION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--duration DURATION | string | no | 60s, applied by the server | How long the overlay stays up, counted from when the Player receives the request: 30s, 2m, or 1m30s, from 2s to 10m. |
screenrig screen identify scr_01EXAMPLESCREEN00000000
screenrig screen identify scr_01EXAMPLESCREEN00000000 --duration 2mThe Player draws a full-screen overlay above its content, with the screen's name very large and its id small below it. Playback continues underneath, and a newer identify replaces the overlay. The accepted envelope carries identify_id, duration_ms, and an expires_at 60 seconds after the request, so a screen that is offline never shows it later. Only a Player that declares the identify capability shows the overlay: any other screen answers 409 identify_unsupported (exit code 5) and nothing is sent, so update the Player or show the name with screen toast. An archived screen answers screen_archived and a screen still waiting to pair answers resource_conflict. Identify does not change the screen revision.
screen play-page#
Start a page of the playlist a screen is playing now, to check that page with a screenshot.
screen play-page <id> --page-id ID| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--page-id ID | string | yes | none | A page of the playlist the screen is playing now: 1 to 128 characters. |
screenrig screen play-page scr_01EXAMPLESCREEN00000000 --page-id welcome
screenrig screen screenshot scr_01EXAMPLESCREEN00000000The page starts from its beginning on the screen's Player and the rotation continues from there, so a screenshot taken next shows that page without waiting out the rotation. The page must belong to the playlist the screen plays now: its takeover, else a campaign that holds, else its schedule, else its assigned playlist. Any other page answers page_not_on_screen (exit 5), and the problem names that playlist. A Player that does not declare the play_page capability in its host report answers play_page_unsupported (exit 5) and nothing is sent: update the Player.
The answer carries playlist_id, page_id, manifest_revision and expires_at. The request expires after 60 seconds and does not change the screen revision. An archived screen answers screen_archived and a screen still waiting to pair answers resource_conflict. A retry with the same idempotency key replays the original answer.
screen screenshot#
Capture one still of an active screen, or of every screen in a fleet, and write it to disk.
screen screenshot <id> [--output FILE] [--timeout MS] [--poll-ms MS]
screen screenshot (<id> <id>... | --tag TAG | --folder ID) [--output DIRECTORY] [--concurrency N] [--timeout MS] [--poll-ms MS]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | one of <id>, --tag or --folder | none | One or more scr_ screen ids. |
--tag TAG | string | one of <id>, --tag or --folder | none | Every active screen carrying this tag, with no screen-count cap. |
--folder ID | string | one of <id>, --tag or --folder | none | Every active screen in this sfd_ screen folder and the folders inside it, with no screen-count cap. |
--output FILE | path | no | ./<id>.webp | For one screen, a file path; an existing file is overwritten without a prompt. For several ids, --tag or --folder, a directory, created if missing, that receives one <screen_id>.webp per screen. |
--concurrency N | integer | no | 4 | Captures in flight at once for several ids, --tag or --folder, from 1 to 8. |
--timeout MS | integer | no | 35000 | How long to wait for the capture. |
--poll-ms MS | integer | no | 500 | Interval between capture-status polls. |
screenrig screen screenshot scr_01EXAMPLESCREEN00000000 --output ./lobby.webpscreenrig screen screenshot --tag Lobby --output ./lobby-shotsscreenrig screen screenshot --folder sfd_01EXAMPLEFOLDER000000000 --output ./north-shotsThe command blocks until the WebP is on disk. The envelope reports screen_id, capture_id, path, bytes, sha256, width, and height, and never image bytes. Latest wins: a later request replaces an in-flight capture. A screenshot of the Player web app draws each iframe page as a dark grey tile labelled "Embedded web page" and each application as the application renders itself; the image carries no marker for the tile, so it does not prove that an iframe page rendered.
For several ids, --tag or --folder, the answer is a fleet result with action: "screenshot", the selector, and the output directory; each ok result carries path, bytes, sha256, width, and height. With --tag, the CLI first lists the tagged screens, following every list page; each list page is one agent request and the captures themselves are not counted, and several ids need no list. --idempotency-key is refused in this form, because each capture uses its own key. If a capture fails unexpectedly, that screen's result is unexpected_error, no new captures start, the screens still waiting report not_attempted, and the exit code is 1.
For one screen the envelope also carries frame.flat, whether this one image is a single flat tone, and picture, the screen's blank or frozen verdict when it has one. A flat image alone is no verdict: a transition between pages, or a page that is black on purpose, looks the same. With --folder, the CLI lists the folder and every folder inside it, one screen list --folder per folder, and a screen the list shows offline is reported failed without a capture.
The server admits 10 captures per screen, 30 per organization and 30 per address a minute; the CLI retries 429 and 5xx answers with backoff and honors Retry-After. A capture that cannot finish is screenshot_unavailable (exit 5): the screen is offline, the request timed_out, the page shown holds a surface the Player cannot capture (unsupported_surface, such as a visible third-party iframe in the browser Player), the Player's capture failed (capture_failed), or the capture was still pending when --timeout ran out. --timeout 0 leaves the wait to the server, which expires an unanswered request after 30 seconds. A failed capture carries error.display when the Player has reported its display: power, connected, reported_at and stale (after 35 minutes). A fresh off or standby report suggests retrying when the display is on.
screen live start#
Start live view of a screen, or renew it, and print the dashboard page that shows it.
screen live start <id> [--duration DURATION] [--wait DURATION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--duration DURATION | string | no | 5m | How long the session lasts unless renewed: 30s to 5m, such as 90s or 5m. A session ends five minutes after it began at the latest. |
--wait DURATION | string | no | 30s | How long to wait for the Player to start publishing: 1s to 10m, or 0 to return at once. |
screenrig screen live start scr_01EXAMPLESCREEN00000000
screenrig screen live start scr_01EXAMPLESCREEN00000000 --duration 2m --wait 60sLive view shows what a screen plays as video in the dashboard; the CLI starts, reads and stops the session and never carries the video. data is the session with viewer_url, the page to open. Starting a screen that has a session renews it: the lease becomes the later of its current end and --duration from now, never past five minutes after the session began. Then the session ends by itself: nothing renews or restarts it, and the next session needs a new screen live start. It ends earlier when the lease passes, on screen live stop, or when the Player ends it.
The command asks the Player to publish and reads the session every second for --wait until the Player reports connected. If the Player has not connected when the wait is over, the answer is still ok with the warning live_not_ready: read screen live status again, or open viewer_url. A session that ended while waiting is live_unavailable (exit 5) and its detail names ended_reason, such as consent_timeout (on Android, someone at the screen allows screen capture once each time the Player starts). An offline screen is live_unavailable too, and an archived one answers screen_archived. A Player that does not declare the live_view capability answers live_unsupported (exit 5) and nothing is sent: update the Player. A server without a media relay answers feature_unavailable: use screen screenshot. Live view is free. See Live view.
screen live status#
Read a screen's live view session.
screen live status <id>| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
screenrig screen live status scr_01EXAMPLESCREEN00000000state is idle (no session), requested (the Player was asked), publishing (the relay holds its video) or ended, with ended_reason for ten minutes. publisher.connected is the Player's own report, at most 45 seconds old, and is not proof of a picture. data includes viewer_url.
screen live stop#
End a screen's live view session.
screen live stop <id>| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
screenrig screen live stop scr_01EXAMPLESCREEN00000000Ends the session and tells the Player to stop publishing, then prints the session as it stands: ended with ended_reason stopped. It succeeds when there is no session. A session also ends by itself when its lease passes.
screen live frame#
Save JPEG frames of what a screen plays, from its live stream, to check playback and motion.
screen live frame <id> [--output PATH] [--count N] [--interval DURATION] [--duration DURATION] [--wait DURATION] [--stop]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The scr_ screen id. |
--output PATH | path | no | the working directory | A file for one frame, or a directory that receives frame-<captured_at>.jpg per frame, with the colons of the time written as hyphens. --count above 1 needs a directory. |
--count N | integer | no | 1 | How many new frames to save. |
--interval DURATION | string | no | 1s | Pause between frames: 1s to 5m, or 0 to take each frame as it arrives. |
--duration DURATION | string | no | 2m | Lease of the live session this command starts: 30s to 5m. It is lengthened to cover the frames plus 30 seconds, and a run that needs more than five minutes is refused. |
--wait DURATION | string | no | 30s | How long to wait for the Player to start publishing, and for each frame: 1s to 10m, or 0 to try once. |
--stop | boolean | no | off | End the live session when done, also when a frame failed. |
screenrig screen live frame scr_01EXAMPLESCREEN00000000
screenrig screen live frame scr_01EXAMPLESCREEN00000000 --output now.jpg --stop
screenrig screen live frame scr_01EXAMPLESCREEN00000000 --output frames/ --count 5 --interval 1sThe command starts the live session, waits for the Player to publish, asks the media relay for frames, and reads each new frame once. A frame is the video as the Player's encoder sent it, scaled to at most 1280x720 and lossy, about one a second: it shows motion and what is on glass now, so compare frames (--count 5 --interval 1s) to check that content moves. It is not a screenshot, which stays the layout proof. Frames are free.
data is {screen_id, live_id, frames}, with path, captured_at, width, height, bytes and sha256 per frame, and stopped true when --stop ended the session. Without --stop the session is left to its lease. A Player that does not publish within --wait, or sends no new frame within it, is live_not_ready (exit 5); on Android, someone at the screen allows screen capture once each time the Player starts. A session that ended, or whose frames stopped arriving, is live_unavailable (exit 5). A Player without the live_view capability answers live_unsupported, and a server without a media relay or frames answers feature_unavailable (exit 4): use screen screenshot.
screen tag#
Set, add, remove, or clear the tags on a screen or a fleet.
screen tag (<id>... | --tag TAG | --folder ID) (--set TAGS | --add TAGS | --remove TAGS | --clear) [--expect-rev REVISION]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | one of <id>, --tag or --folder | none | One or more scr_ screen ids. Several ids run as one fleet request. |
--tag TAG | string | one of <id>, --tag or --folder | none | Every active screen carrying this tag. |
--folder ID | string | one of <id>, --tag or --folder | none | Every active screen in this sfd_ screen folder and the folders inside it. |
--set TAGS | string | exactly one action | none | Replace the whole set with these comma-separated tags, such as Lobby,Floor2. |
--add TAGS | string | exactly one action | none | Add these comma-separated tags. |
--remove TAGS | string | exactly one action | none | Remove these comma-separated tags. |
--clear | boolean | exactly one action | off | Remove every tag. |
--expect-rev REVISION | string | no | none | One screen id only. Optional revision precondition. |
screenrig screen tag scr_01EXAMPLESCREEN00000000 --set Lobby,Floor2
screenrig screen tag scr_01EXAMPLESCREEN00000000 --add Spring
screenrig screen tag --tag Lobby --add Spring
screenrig screen tag --folder sfd_01EXAMPLEFOLDER000000000 --add SpringA tag is 1 to 32 letters or digits, and a screen carries at most 16 unique tags. Tags select fleets; they are never authorization and never reach the Player. Changing tags bumps the screen revision, not the manifest revision. For one screen the envelope is the updated screen. --add and --remove read the screen first and write the new set guarded by --expect-rev or the revision just read, so a concurrent change returns revision_conflict (exit 6) instead of being overwritten; rerun the command. In a fleet, --add and --remove apply against each screen's stored set atomically, and a screen that would pass 16 tags fails in its own result with invalid_request.
Wherever tags change (screen tag, a screen update through the API, the dashboard tag editor), the answer's levels lists, under gained and lost, the campaigns whose tag audience the screen entered or left, each with its source (campaign), id, the screens count and, when the campaign has a reach, reach_before and reach_after. A fleet screen tag sums them over the fleet. Read levels.lost before calling a tag edit harmless: removing the last matching tag from a campaign's screens empties that group and raises the reach_dropped and group_empty notifications.
screen move#
Move screens and screen folders into a screen folder, or back to the project root.
screen move <id>... (--folder ID | --root) [--note TEXT]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id>... | string | yes | none | scr_ screen ids and sfd_ screen folder ids in any mix, each once, at most 1000 in all. |
--folder ID | string | one of --folder or --root | none | The destination sfd_ screen folder. |
--root | boolean | one of --folder or --root | off | Move to the project root, outside every folder. |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
screenrig screen move scr_01EXAMPLESCREEN00000000 --folder sfd_01EXAMPLEFOLDER000000000
screenrig screen move sfd_01EXAMPLEFOLDER000000000 --rootThe move is one all-or-nothing request. A folder moves with everything inside it and cannot move into itself or a folder inside it; folders nest at most 10 deep. Items already in the destination stay as they are and are not counted. data.screens and data.folders count what moved. data.levels lists, under gained and lost, the campaigns whose folder audience the moved screens entered or left (source campaign, with reach_before and reach_after) and the folder default playlists they started or stopped showing (source folder). The screens re-resolve their playlist within about 15 seconds; screen show reports effective_playlist, and campaign explain SCREEN_ID says why.
A caller limited to screen folders moves only screens and folders inside its scope into a folder inside it; anything else, including the project root, refuses the whole move with outside_screen_scope (exit 3). A move into or out of a protected folder answers pending_review with a protected_change review that a second approver decides, so do not repeat the write; --note tells the approver why. After an interrupted request, rerun the identical command to reuse the saved idempotency key.
screen folder list#
List the project's screen folders as a tree, with the live screens directly in each and its default playlist.
screen folder listscreenrig screen folder listReturns every screen folder of the project, at most 1000, ordered by name. data.items carries each folder's id, name, parent_id (null at the project root), default_playlist_id when set, protected when set, screens (the live screens directly inside, not those of the folders below) and revision. With --human, the output is the tree, one row per folder with its path. A screen's folder is folder_id on screen list and screen show, absent at the project root. Read only access is enough.
screen folder show#
Inspect a screen folder.
screen folder show <id>| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The sfd_ screen folder id. |
screenrig screen folder show sfd_01EXAMPLEFOLDER000000000Returns one folder with the fields screen folder list returns. Read only access is enough.
screen folder create#
Create a screen folder at the project root or inside another folder.
screen folder create --name NAME [--parent ID] [--default-playlist-id ID] [--note TEXT]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
--name NAME | string | yes | none | Folder name, trimmed: 1 to 100 characters, no control characters, not . or .., and unique among its siblings (resource_conflict, exit 5). |
--parent ID | string | no | project root | Create it inside this sfd_ screen folder. |
--default-playlist-id ID | string | no | none | The approved pl_ playlist its screens show when they have none of their own, unless a folder nearer the screen sets one (playlist_not_approved, exit 5). |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
screenrig screen folder create --name "North Tower"
screenrig screen folder create --name "Level 2" --parent sfd_01EXAMPLEFOLDER000000000 --default-playlist-id pl_01EXAMPLEPLAYLIST000000An organization holds at most 1000 folders across its projects (quota_exceeded), nested at most 10 deep (invalid_request). Put screens in with screen move. A folder then targets its screens in the fleet commands and as a campaign audience: see Screen folders.
A caller limited to screen folders creates folders only inside its scope: --parent must be a folder of it (outside_screen_scope, exit 3). A folder created inside a protected folder answers pending_review with a protected_change review that an approver other than you, and other than the person you work for, decides, so do not repeat the write; --note tells the approver why. After an interrupted request, rerun the identical command to reuse the saved idempotency key.
screen folder update#
Rename a screen folder, move it with everything inside, or set or clear its default playlist.
screen folder update <id> [--name NAME] [--parent ID | --root] [--default-playlist-id ID | --clear-default] [--expect-rev REVISION] [--note TEXT]
screen folder update <id> --unprotect [--expect-rev REVISION] [--note TEXT]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The sfd_ screen folder id. |
--name NAME | string | no | unchanged | New folder name, with the rules of screen folder create. |
--parent ID | string | no | unchanged | Move it, with everything inside, under this sfd_ screen folder. Not with --root. |
--root | boolean | no | off | Move it to the project root. Not with --parent. |
--default-playlist-id ID | string | no | unchanged | The approved pl_ playlist its screens show when they have none of their own. Not with --clear-default. |
--clear-default | boolean | no | off | Remove its default playlist. Not with --default-playlist-id. |
--unprotect | boolean | no | off | Propose removing the folder's protection. It is sent alone, with none of the options above, and a second approver decides the review. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
Provide at least one of --name, --parent, --root, --default-playlist-id, --clear-default or --unprotect.
screenrig screen folder update sfd_01EXAMPLEFOLDER000000000 --name "Northern"
screenrig screen folder update sfd_01EXAMPLEFOLDER000000000 --root
screenrig screen folder update sfd_01EXAMPLEFOLDER000000000 --default-playlist-id pl_01EXAMPLEPLAYLIST000000 --expect-rev 3
screenrig screen folder update sfd_01EXAMPLEFOLDER000000000 --clear-default
screenrig screen folder update sfd_01EXAMPLEFOLDER000000000 --unprotect --note "Menu boards move next week"A folder cannot move into itself or a folder inside it, and the same values are a no-op. A move or a default change re-resolves the screens inside within about 15 seconds, and data.levels lists the campaigns whose folder audience those screens entered or left (source campaign) and the folder default playlists they gained or lost (source folder).
A rename stays live on a protected folder. A move, or a default playlist, of a folder that is or holds a protected one answers pending_review with a protected_change review that a second approver decides (an approver other than you, and other than the person you work for; second_approver_required, exit 3, otherwise). Nothing changes until then, so do not repeat the write; --note tells the approver why. A person who can approve protects a folder in the dashboard; the CLI only proposes removing protection with --unprotect. See Protected folders. A caller limited to screen folders changes only folders inside its scope and moves them only to a parent inside it (outside_screen_scope, exit 3), and never the protection of a folder its scope names.
screen folder delete#
Delete a screen folder; its screens and folders move up one level.
screen folder delete <id> [--expect-rev REVISION] [--note TEXT]| Parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
<id> | string | yes | none | The sfd_ screen folder id. |
--expect-rev REVISION | string | no | none | Optional revision precondition. Omit to write the current resource. A supplied stale value is revision_conflict: refetch, reapply, retry. |
--note TEXT | string | no | none | A note for the person who reviews the change: plain text, at most 280 characters. Ignored when the change applies at once. |
screenrig screen folder delete sfd_01EXAMPLEFOLDER000000000
screenrig screen folder delete sfd_01EXAMPLEFOLDER000000000 --expect-rev 3Deletes only the folder: its screens and folders move up into its parent (the project root when it has none) and those screens re-resolve their playlist. data is id, deleted true and levels, the campaigns and folder default playlists the moved screens gained or lost, with a campaign's reach_before and reach_after. A campaign audience that names the folder refuses the delete with resource_conflict (exit 5): change or delete those campaigns first.
A caller limited to screen folders deletes only folders inside its scope, never a folder its scope names (outside_screen_scope, exit 3). A folder that is or holds a protected one answers pending_review with a protected_change review that a second approver decides, so do not repeat the write; --note tells the approver why.
Fleet results
With several screen ids or --tag, screen assign, screen reload, screen toast, and screen tag run one action with no screen-count cap. The CLI follows bounded result pages automatically, waits when control budgets are exhausted, and retains the same key and selected fleet throughout. --tag selects active screens only; ids may name any screen. One screen id keeps the single-screen answer. Fleet commands take no --expect-rev, because revision guards are per screen. Each fleet command carries an idempotency key. After an interrupted request, such as a lost connection, rerun the identical command to replay finished screens without repeating their side effects. After a definite answer with failures, retry only the failed ids: rerunning the whole command acts on every screen again. Reusing the same explicit --idempotency-key within 24 hours returns the recorded answer instead.
A fleet command takes screen ids, --tag TAG or --folder ID; giving more than one of them is a usage error (exit 2).
The envelope keeps ok: true. Partial success is a normal answer, not a transport error:
{
"ok": true,
"data": {
"action": "reload",
"matched": 3, "succeeded": 2, "failed": 1,
"results": [
{ "screen_id": "scr_LOBBY", "status": "ok", "reload": { "reload_id": "…", "expires_at": "…", "state": "sent" } },
{ "screen_id": "scr_GONE", "status": "failed", "problem": { "code": "not_found", "status": 404 } },
{ "screen_id": "scr_ENTRANCE", "status": "ok", "reload": { "reload_id": "…", "expires_at": "…", "state": "queued" } }
]
},
"warnings": [{ "code": "fleet_partial_failure", "message": "1 of 3 screens failed; 2 succeeded." }]
}An ok result carries the single-screen result: revision for assign, revision and tags for tag changes, reload for reload, and toast for toast. A failed result carries the problem that screen's own request would have returned. Per-screen limits still apply inside a fleet action, so a fleet reload or toast can report rate_limited for a screen that was just reloaded or toasted; retry that screen id later. Per-screen limits are 6 reloads and 20 toasts a minute. Fleet reloads and toasts also draw on an organization budget of 600 screens a minute: the server pauses when the remaining budget is exhausted, and the CLI honors Retry-After before continuing automatically.
| Outcome | Exit code | Warning |
|---|---|---|
| Every matched screen succeeded | 0 | none |
| Some or all screens failed | The first failed screen's code, such as 4 for not_found or 6 for revision_conflict | fleet_partial_failure |
| No screen matched | 0 | fleet_no_match |
| Malformed selector or action | 2 or the request's own code; no screen changes | none |
Screen folders
A screen folder organizes screens by place. A folder ID starts sfd_, and a screen sits in at most one folder, reported as folder_id on screen show and screen list and absent at the project root. An organization holds at most 1000 folders across its projects, nested at most 10 levels deep, with names of 1 to 100 characters that are unique among their siblings. Tags stay for groups that cut across places.
screen folder list
screen folder show <id>
screen folder create --name NAME [--parent ID] [--default-playlist-id ID] [--note TEXT]
screen folder update <id> [--name NAME] [--parent ID | --root] [--default-playlist-id ID | --clear-default] [--unprotect] [--expect-rev REVISION] [--note TEXT]
screen folder delete <id> [--expect-rev REVISION] [--note TEXT]
screen move <id>... (--folder ID | --root) [--note TEXT]screenrig screen folder create --name "North Tower"
screenrig screen folder create --name "Level 2" --parent sfd_01EXAMPLEFOLDER000000000 --default-playlist-id pl_01EXAMPLEPLAYLIST000000
screenrig screen move scr_01EXAMPLESCREEN00000000 --folder sfd_01EXAMPLEFOLDER000000000screen folder list returns every folder in data.items with id, name, parent_id (null at the project root), default_playlist_id when set, screens (the live screens directly inside) and revision. screen move takes screen and folder IDs in any mix, at most 1000 in one all-or-nothing request; a folder moves with everything inside it and cannot move into itself or a folder inside it. screen list --folder ID lists only the screens directly inside one folder.
On every fleet command that takes --tag TAG, --folder ID selects every active screen in that folder and in every folder inside it. A campaign takes the same: --folder ID on campaign create and campaign update, or a {"folder":"sfd_…"} rule in --audience, which combines with tag rules as in {"all":[{"folder":"sfd_BUILDING"},{"tag":"overhead"}]}.
A folder's default playlist is what its screens show when they have no playlist of their own. The nearest folder above a screen that sets one wins, and effective_playlist reports source folder with the folder id as entry_id. A takeover, a campaign, a schedule and the screen's own assigned playlist all rank above it; see Schedules and takeover. The playlist must be approved (playlist_not_approved, exit 5).
Moving screens or a folder, or changing a folder's default playlist, re-resolves the affected screens within about 15 seconds. The answer's levels lists, under gained and lost, the campaigns whose folder audience those screens entered or left and the folder default playlists they started or stopped showing, each with its source (campaign or folder), id and screens count. Deleting a folder deletes nothing inside it: its screens and folders move up into its parent, and resource_conflict (exit 5) refuses the delete while a campaign audience names the folder. The delete answers 200 with levels, as a move does.
Writes need Manage access: a Propose session answers 403 insufficient_access. A change that reaches a protected folder waits for a second approver and answers pending_review, and --note TEXT tells the approver why. Each write appends screen.folder_created, screen.folder_updated, screen.folder_deleted or screen.moved to the project events.