API reference

Screens API

Screens

HTTP reference. Generated from the backend contract. Browse endpoints below or download OpenAPI.

This group has 84 operations, generated from api/openapi.yaml. Filter by path, action, or authentication. Each endpoint lists its inputs; expand it for a request template and response codes. Templates need your own values and a schema-valid body.

Replace uppercase placeholders with your values. For a JSON request, save a body matching the schema in request.json. Cookie examples use a local cookie jar from an authenticated session.

Screens

GET/api/screens

List Screens

Default list returns pairing_pending and active screens. Pass state=archived to list archived screens only. Pass tag to list only screens whose tags contain that exact tag; untagged screens are omitted when the filter is present.

Pass field, once per field, as NAME:VALUE to list only screens whose fields hold every value, and near as LAT,LON,KM to list only screens located within KM kilometres of the point; screens with no location are omitted, and every filter combines with state and tag.

Pass folder as a screen folder ID to list only the screens directly inside it (not those of its subfolders), or root for the screens outside every folder.

Screens are newest first, at most 500 per page. next_cursor is the position of the last returned row while more rows remain; pass it back as after, with the same filters, for the next page. next_cursor is null on the last page. A caller limited to screens (docs/screen-scope.md) lists only the screens in its scope.

A request that names no project leaves out each project where the caller is limited to screens; name the project to list it.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
listScreens

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
statequeryoptionalOmit for pairing_pending and active. Pass archived to list archived screens only.
tagqueryoptionalExact screen tag. Untagged screens are omitted when this filter is present.
fieldqueryoptional

NAME:VALUE, split at the first colon: only screens whose field NAME holds exactly VALUE. Repeat the parameter for several fields; every one must match, and a name may be given once. A malformed or repeated one is invalid_request naming field.

nearqueryoptional

LAT,LON,KM in decimal degrees and kilometres, for example 47.6062,-122.3321,25: only screens whose location lies within KM kilometres of the point. Latitude is -90 to 90, longitude -180 to 180 and KM above 0 and at most 20038. Screens with no location are omitted. A malformed value is invalid_request naming near.

folderqueryoptionalA screen folder ID keeps only the screens directly inside that folder, not those of its subfolders; root keeps only the screens outside every folder. Omitted lists every screen.
afterqueryoptionalnext_cursor of the previous page of the same list, with the same filters. Omitted starts at the newest row. A value that is not such a cursor is invalid_request.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens'

Responses

StatusMeaningBody and headers
200ScreensScreenList (application/json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screen-folders

List Screen Folders

Lists every screen folder in the project, at most 1000, ordered by name.

Folders organize screens and target them: a campaign audience leaf {"folder": ID} matches the screens in that folder and every folder inside it, a fleet action selector by:folder acts on the same screens, and a folder's default_playlist_id is what its screens without a playlist of their own show. parent_id is null at the project root; build the tree from parent_id. screens counts the live screens directly inside each folder.

A screen's folder is Screen.folder_id. A caller limited to screens (docs/screen-scope.md) lists the folders inside its scope and the folders above them, which are read-only so its tree has a root; folders above carry no screens count and sibling folders are hidden. A request that names no project leaves out each project where the caller is limited to screens.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
listScreenFolders

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screen-folders'

Responses

StatusMeaningBody and headers
200Screen foldersScreenFolderList (application/json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screen-folders

Create Screen Folder

Creates one screen folder at the project root (parent_id null or absent) or inside parent_id. Names are trimmed, hold 1 to 100 Unicode characters with no controls, are not "." or "..", and are unique among their siblings (resource_conflict).

An organization holds at most 1000 folders across its projects (quota_exceeded) nested at most 10 deep (invalid_request). default_playlist_id, when set, must name an approved playlist (playlist_not_approved). Emits screen.folder_created.

A caller limited to screens (docs/screen-scope.md) creates a folder only inside a folder of its scope; the project root or any other parent is outside_screen_scope. Creating a folder inside a protected folder is a protected_change review (202 pending_review) decided by a second approver.

Authentication
projectBearer OR dashboardSession
Request body
ScreenFolderCreate
Operation ID
createScreenFolder

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
name (required, string)Trimmed; 1 to 100 Unicode characters, no controls, not . or .., unique among its siblings. minLength: 1 maxLength: 100
parent_id (optional, inline)The folder to create it in; null or absent for the project root.
default_playlist_id (optional, string)An approved playlist for the folder's screens without their own. minLength: 1
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screen-folders'

Responses

StatusMeaningBody and headers
201Created folder.ScreenFolder (application/json); headers: ETag
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screen-folders/{id}

Get Screen Folder

A caller limited to screens (docs/screen-scope.md) reads the folders of its scope and the folders above them; any other folder, and an unknown id, is outside_screen_scope.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenFolder

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screen-folders/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200One screen folder.ScreenFolder (application/json); headers: ETag
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screen-folders/{id}

Update Screen Folder

Renames a folder (name), moves it with everything inside (parent_id, null for the project root) or sets the default playlist its screens without their own show (default_playlist_id, null clears it). A folder cannot move into itself or a folder inside it, and the move must keep every folder within 10 levels (invalid_request).

A move or a default change re-resolves the screens inside within about 15 seconds, and the response's levels name the campaigns and folder defaults those screens gain or lose. A change advances the folder revision and emits screen.folder_updated; the same values are a no-op.

If-Match optionally guards the revision. protected true protects the folder and every folder inside it, and false clears it; send it alone (invalid_request otherwise). Only a person who can approve sets it: an agent, a service client or a member who cannot approve gets approver_required.

A change appends screen.folder_protection_changed (details folder_id, protected). Clearing protection, and a move or a default playlist change on a folder that holds protected screens, is a protected_change review (202 pending_review) decided by a second approver.

A caller limited to screens (docs/screen-scope.md) changes only folders inside its scope: parent_id must name one too (the root is outside_screen_scope), and protected is not its to change on a folder its scope names. protected true is protected folders, which the Enterprise plan includes; a project whose plan lacks it is refused with feature_not_in_plan (402).

Protection that is set keeps holding changes for a second approver, and asking to remove it is a review on every plan.

Authentication
projectBearer OR dashboardSession
Request body
ScreenFolderPatch
Operation ID
updateScreenFolder

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
name (optional, string)Trimmed; 1 to 100 Unicode characters, no controls, not . or .., unique among its siblings. minLength: 1 maxLength: 100
parent_id (optional, inline)Move the folder into this one; null for the project root.
default_playlist_id (optional, inline)An approved playlist for the folder's screens without their own; null clears it.
protected (optional, boolean)

Protects the folder and every folder inside it (docs/screen-scope.md). Only a person who can approve sets it. Send it alone: with any other member the request is invalid_request. Clearing it on a protected folder is itself a protected change, a review decided by a second approver (202 pending_review).

Request template and responses
shell · request template
curl --request PATCH --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screen-folders/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200Updated folder.ScreenFolder (application/json); headers: ETag
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
402feature_not_in_plan — Protected folders are part of the Enterprise plan; the problem names the feature, the plan the account is on and required_plan.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screen-folders/{id}

Delete Screen Folder

Deletes one folder. Nothing inside is deleted: its screens and folders move up into the deleted folder's parent (the project root when it had none), each moved folder advancing its revision, and those screens re-resolve.

Refused with resource_conflict while a campaign audience names the folder, so no schedule loses its screens silently: change or delete those campaigns first. Answers the levels its screens gained or lost. Emits screen.folder_deleted. If-Match optionally guards the revision.

A caller limited to screens (docs/screen-scope.md) deletes only a folder inside its scope that its scope does not name itself (outside_screen_scope); the screens inside move up into the parent. Deleting a protected folder, or one that holds protected screens, is a protected_change review (202 pending_review) decided by a second approver.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
deleteScreenFolder

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screen-folders/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200Deleted; its contents now sit in its parent. levels names the folder default playlists its screens gained or lost.ScreenFolderDeleteResult (application/json)
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/move

Move Screens

Moves screens (screen_ids) and folders (folder_ids) into one folder (folder_id), or to the project root when folder_id is null, in one all-or-nothing request of at most 1000 ids. Every id must exist (not_found). A folder cannot move into itself or a folder inside it, and the move must keep every folder within 10 levels (invalid_request).

Items already in the destination are left as they are; each moved screen and folder advances its revision. Moved screens re-resolve their playlist within about 15 seconds: levels names the campaigns whose folder audience they enter or leave and the folder default playlists they gain or lose.

Emits screen.moved, whose details carry the counts (screens, folders) and where each moved item was: moves [{screen_id, from}] (from is the folder id, empty for the root) and folder_moves [{folder_id, from_parent}], at most 1000 each, so a history can move them back with this route.

A caller limited to screens (docs/screen-scope.md) moves screens and folders inside its scope into a folder of its scope; any id or destination outside it, and the project root, refuse the whole move (outside_screen_scope), also when a screen leaves the scope between the check and the write.

A move into or out of a protected folder is a protected_change review (202 pending_review) decided by a second approver.

Authentication
projectBearer OR dashboardSession
Request body
ScreenMove
Operation ID
moveScreens

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
folder_id (required, inline)Destination folder; null for the project root.
screen_ids (optional, array)
folder_ids (optional, array)
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/move'

Responses

StatusMeaningBody and headers
200How many screens and folders moved, and the levels the moved screens gain or lose.ScreenMoveResult (application/json)
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/schedule/calendar

Get Schedule Calendar

Answers what a subject's screens play over [from, to) and why, for the dashboard's Schedule calendar: exactly one of screen_id, folder_id (the screens in the folder and every folder inside it), tag, or campaign_id (the screens in its audience).

Screens whose stacks have identical inputs (the same levels, default, timezone and display count) share one group with one timeline, so a large subject costs tens of timelines; a group lists up to 500 of its screens and an answer at most 200 groups (truncated).

Each group carries its stack, highest first (takeover, campaigns that reach the screens, their own schedule entries, then the default playlist or the nearest folder's), each level's spans (plays on every display it targets, partial with the displays it plays on, outranked, or conditional while it waits on interaction or a data condition only a Player observes), what each display shows (on_screen; the main region of a full page), and conflicts (two campaigns of one priority holding at once; a level that holds yet never plays). from and to are RFC 3339 instants, to after from, at most 93 days apart; they are truncated to the minute.

Rules are read in each group's timezone as the sweep and every Player read them; every level is judged playable. A caller limited to screens (docs/screen-scope.md) must send a screen_id or a folder_id inside its scope; a tag, a campaign_id or no subject is outside_screen_scope.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScheduleCalendar

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
fromqueryrequired
toqueryrequired
screen_idqueryoptional
folder_idqueryoptional
tagqueryoptional
campaign_idqueryoptional
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/schedule/calendar?from=FROM&to=TO'

Responses

StatusMeaningBody and headers
200The subject's calendar.ScheduleCalendar (application/json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/pair

Pair Screen

Claims one fleet-global six-character Player pairing session. Exact Idempotency-Key retries return the durable original result without consuming quota again.

The dashboard session claims into its current project with the same body, Idempotency-Key, budgets and problems, except that its not_found for an unknown or already-claimed code names no CLI command; it is a state change, so it follows the dashboard mutation rules, a shadow session without staff write mode is refused, and the events the claim appends name the dashboard user. folder_id names the folder the screen lands in.

A caller limited to screens (docs/screen-scope.md) must send a folder inside its scope and pairs only as a person who can approve (outside_screen_scope, approver_required).

Authentication
projectBearer OR dashboardSession
Request body
PairScreen
Operation ID
pairScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Idempotency-Keyheaderrequired

Request body fields

FieldDescription
code (required, string)pattern: "^[23456789ABCDEFGHJKMNPQRSTUVWXYZ]{6}$"
label (optional, string)minLength: 1 maxLength: 120
folder_id (optional, string)

The screen folder the screen lands in; omitted lands it at the project root. A caller limited to screens must send a folder inside its scope (outside_screen_scope otherwise). A folder the project does not hold is invalid_request for a caller of the whole project.

Part of the idempotent request: another folder_id under the same Idempotency-Key is idempotency_mismatch. minLength: 1

Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Idempotency-Key: REQUEST_ID' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/pair'

Responses

StatusMeaningBody and headers
201Durable pairing_pending screen claim.PairingClaim (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
413

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
500

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/provision

Provision Screen

Optional browser-only new-screen provisioning. Always creates one new pairing_pending screen; at most five wait to pair at once (quota_exceeded). Exact retries redeliver the same fragment token for ten minutes. Six-character pairing remains the default and only recovery flow. folder_id names the folder the screen lands in.

A caller limited to screens (docs/screen-scope.md) must send a folder inside its scope (outside_screen_scope otherwise).

Authentication
projectBearer
Request body
ProvisionScreen
Operation ID
provisionScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Idempotency-Keyheaderrequired

Request body fields

FieldDescription
label (optional, string)minLength: 1 maxLength: 120
folder_id (optional, string)The screen folder the screen lands in, as on PairScreen. minLength: 1
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Idempotency-Key: REQUEST_ID' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/provision'

Responses

StatusMeaningBody and headers
201New browser provisioning link.ScreenProvisioning (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
410

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
413

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
500

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/actions

Apply Screen Actions

Applies one action to a selected fleet with no screen-count cap. Select unique screen_ids or a tag matching active screens in creation order. The resolved selection is pinned before any mutation, stored in bounded chunks, and kept for twenty-four hours under Idempotency-Key.

Each step uses its single-screen mutation path, preserving revisions, events, runtime signals and per-screen limits. A response contains one bounded page of results; matched, succeeded and failed describe that page. HTTP 202 includes total, offset and next_cursor. Continue with the same selector, action and Idempotency-Key, passing next_cursor as after.

Honor Retry-After when present, including a page with zero results. The response echoes Idempotency-Key, including a generated key when the caller omitted it; retain this key for continuations. HTTP 200 finishes the selection. Answered pages replay exactly, including per-screen failures; interrupted steps replay without repeating their effects.

Large actions are paced against the existing 600-per-minute organization budgets for reload, toast, takeover, playlist schedules, reboot, display and display schedules; organization exhaustion pauses the action instead of refusing the fleet. Per-screen exhaustion fails that screen alone.

An assign, takeover or set_playlist_schedule step that binds a playlist with a format to a screen whose wall has another shape fails that screen alone with 409 playlist_format_mismatch. Assign and tag changes have no message budget.

An assign whose playlist has an iframe src or application params that read a screen token some screen of the page lacks adds a screen_fact_missing warning to that page (warnings, PlaylistWarning). Partial failure is a normal result. All pages and retries under one key are one metered action.

Requests use a bounded byte payload; use a tag for a selection larger than the transport payload. A malformed selector or action is refused before any screen is touched.

A caller limited to screens (docs/screen-scope.md) selects by screen_ids or by folder, every screen inside its scope; a tag selector, a screen outside the scope or an unknown one refuses the whole action (outside_screen_scope) before anything is pinned or proposed.

Assign, takeover, takeover_clear, set_playlist_schedule and clear_playlist_schedule that reach a protected screen become a review decided by a second approver (202 pending_review) at every access level; set_tags, add_tags, remove_tags, toast, display, display_clear, set_display_schedule and clear_display_schedule on a protected screen are protected_target (409).

A set_playlist_schedule action with a paused entry (a draft) is schedule change control, which the Enterprise plan includes; a project whose plan lacks it is refused with feature_not_in_plan (402).

Authentication
projectBearer
Request body
ScreenActionRequest
Operation ID
applyScreenActions

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
afterqueryoptionalnext_cursor from the preceding result page. Reuse the original Idempotency-Key and request body.

Request body fields

FieldDescription
selector (required, ScreenActionSelector)
action (required, ScreenAction)One fleet action, discriminated by type. Each member carries only its own parameters; a member of another type is an unknown field and invalid_request.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/actions'

Responses

StatusMeaningBody and headers
200Per-screen results. Partial success is a normal answer.ScreenActionResult (application/json); headers: Idempotency-Key, Cache-Control, RateLimit-Policy, RateLimit
202

More screens remain (continue with next_cursor and the same Idempotency-Key and body, honoring Retry-After), or, with status pending_review, the action became a review under Propose access (docs/reviews.md), or at any access level because it reaches a screen in a protected screen folder (docs/screen-scope.md).

Only assign, takeover, takeover_clear, set_playlist_schedule and clear_playlist_schedule become reviews; every other action is insufficient_access for Propose.

inline (application/json); headers: Idempotency-Key, Retry-After, Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
402

feature_not_in_plan — set_reboot_schedule with enabled true (Scheduled reboots) and set_playlist_schedule with a displays lock (Video walls) are part of Plus; the clearing actions and one-off commands are open. payment_required — the project has no credit left. The problem names the feature, the project's plan and required_plan.

Problem (application/problem+json)
403insufficient_access, outside_screen_scope when a caller limited to screens selects outside its scope, or approver_required for a member limited to screens who cannot approve.Problem (application/problem+json)
409

playlist_format_mismatch and the other conflicts of the action, or protected_target when set_tags, add_tags, remove_tags, toast, display, display_clear, set_display_schedule or clear_display_schedule reaches a screen in a protected screen folder.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}

Get Screen

Returns pairing_pending, active, and archived screens. Deleted screens are not found.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200ScreenScreen (application/json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}

Update Screen

Updates the screen's name, playlist_id, timezone, wall, tags, fields, location, log_level, toast_level, display or kiosk. A tag change answers levels: the campaigns the screen enters or leaves, with each campaign's reach before and after. wall sets the screen's video wall (an object) or clears it (null).

Setting one needs a Player that declared the display.wall host capability, else 409 wall_unsupported.

Changing it remints the manifest revision and appends screen.updated with details.wall (the wall object, or null once cleared). fields merges into the screen's own values (a string sets a field, null removes it, a null fields clears every field) and location sets where the screen is (null clears it).

Changing either remints the manifest revision of a screen that shows a playlist, so its card placements expand their {screen.…} tokens again, and appends screen.updated with details.fields (the complete new object, {} once cleared) or details.location (the new object, or null once cleared).

A name or value the grammar refuses, or a thirty-third field, is invalid_request naming it. log_level (debug, info, warn, error) and toast_level (info, alert, error) set the lowest level the Player generates or shows, and null clears each; any other value is invalid_request.

Changing either remints the manifest revision, which carries them as the root member verbosity. display sets or clears the display's idle-dark and brightness settings: display.idle {after_s, wake} darkens the glass after after_s seconds (30 to 86400) without a touch or key or, when wake lists presence, anybody in front of the screen, and a wake event (touch, presence, or both, each once) lights it at once; display.brightness {mode} is auto (the device's light sensor sets the brightness) or fixed (the default, the operator's brightness).

A member you send replaces it, null clears it, a member you leave out stays, and a null display clears both. kiosk {lock} true pins the Player to the screen (Android screen pinning) and false or null releases it. The display schedule and override keep their own routes; a display member naming schedule or override is invalid_request.

A value out of range or of the wrong type is invalid_request naming the path (display.idle.after_s).

Changing any of them remints the manifest revision of a screen that shows a playlist and changes the manifest ETag of every screen; the manifest carries display.idle and display.brightness in the root display member and the lock as the root member kiosk, and screen.manifest_changed is appended; the screen reads them back as Screen.display.idle, Screen.display.brightness and Screen.kiosk.

The backend stores what you send whatever the Player: a Player applies a setting only when its host capabilities declare display_power.idle, brightness.auto or kiosk_lock, and older Players ignore them. Assigning a playlist whose format does not match the screen's wall is 409 playlist_format_mismatch.

Under Propose access a patch of playlist_id alone becomes a review (202 pending_review); any other field, wall, fields, location, display and kiosk included, is insufficient_access. A playlist with no approved version is playlist_not_approved.

When the playlist the screen then shows has an iframe src or application params that read a screen token the screen lacks, the answer carries a screen_fact_missing warning (warnings, PlaylistWarning) and the screen's manifest leaves that primitive out.

On a protected screen playlist_id is a review decided by a second approver (202 pending_review) at every access level and is sent alone (invalid_request with name); tags, fields, location, timezone, wall and display are protected_target (409), also beside playlist_id. Rename stays live. Clearing playlist_id (null) on an archived screen is 409 screen_archived.

Authentication
projectBearer
Request body
ScreenPatch
Operation ID
updateScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
name (optional, string)minLength: 1 maxLength: 120
playlist_id (optional, inline)

The screen default: a playlist id assigns it; null clears it; omission preserves it. Takeovers, campaigns, schedules and inherited folder defaults retain precedence. Without effective content the paired Player shows its idle display.

timezone (optional, string)

IANA time zone identifier, for example America/Los_Angeles. It is the zone every page visibility rule on this screen is evaluated in. Changing it remints the manifest revision. A screen assigned a playlist that uses page visibility must have one. minLength: 1 maxLength: 64

wall (optional, inline)The screen's video wall; null clears it. Setting one needs a Player that declared the display.wall host capability, else 409 wall_unsupported. Changing it remints the manifest revision.
tags (optional, ScreenTags)

Fleet selector tags, 0 to 16 unique exact tags, each matching the media tag grammar. On ScreenPatch the array replaces the whole set and an empty array clears it; a duplicate or malformed tag is invalid_request. Changing tags bumps the screen revision (If-Match guards it) and appends screen.updated with details.tags; it never changes the manifest revision.

Tags are never on the runtime manifest and never authorization.

fields (optional, inline)

Merges into the screen's own values, such as a store number or a region: a string sets a field, null removes it, and a null fields clears every field. Names are 1 to 32 lower case letters, digits or underscores; values 1 to 200 characters after trimming; a screen carries at most 32 fields.

Changing the fields remints the manifest revision of a screen that shows a playlist. Card placements read them through {screen.field.NAME} tokens.

location (optional, inline)Where the screen is; null clears it. Changing it remints the manifest revision of a screen that shows a playlist. Card placements read it through the {screen.location} token.
log_level (optional, inline)

The lowest log level the screen's Player generates: it writes no log line below it, and error lines are always generated; null clears it (the Player's default). Changing it remints the manifest revision, which carries it as verbosity.logLevel.

toast_level (optional, inline)

The lowest toast level the screen's Player shows: it shows no toast below it, and error toasts are always shown; null clears it (every toast shows). Changing it remints the manifest revision, which carries it as verbosity.toastLevel.

display (optional, inline)

The display's idle-dark and brightness settings (display.idle, display.brightness). A member you send replaces it, null clears it, a member you leave out stays; a null display clears both. Changing either remints the manifest revision of a screen that shows a playlist, and the manifest carries them in the root display member.

On a protected screen it is protected_target.

kiosk (optional, inline)

The kiosk lock (kiosk.lock). lock true pins the Player to the screen; false or null releases it. Changing it remints the manifest revision of a screen that shows a playlist, and the manifest carries it as the root member kiosk.

Request template and responses
shell · request template
curl --request PATCH --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID'

Responses

StatusMeaningBody and headers
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
200ScreenScreen (application/json)
402

feature_not_in_plan — Video walls are part of Plus: setting a wall other than the screen's own needs it, null clears it in every plan. The problem names the feature, the project's plan and required_plan.

Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
409

protected_target - the change reaches a screen in a protected screen folder and has no review form (docs/screen-scope.md). Clear the folder's protection through a review, make the change, and protect the folder again.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}

Delete Screen

Soft-deletes an eligible screen and immediately revokes its cookie credentials and runtime grants. Ordinary reads then return not_found; the tombstoned row is retained for at least 90 days before cleanup. If-Match guards the revision and Idempotency-Key replays the result.

A native identity-bound screen returns screen_archive_required: use archive to retain that binding; an identity-bound screen that is already archived stays archived (the same problem, saying so). This route does not grant administrative break-glass permission to release native enrollment. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
deleteScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID'

Responses

StatusMeaningBody and headers
204Screen soft-deleted; its tombstone is retained for at least 90 days.no body
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409screen_archive_required for a native identity-bound screen, or protected_target when the screen is in a protected screen folder (docs/screen-scope.md).Problem (application/problem+json)
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/tags

Patch Screen Tags

A signed-in person sets a screen's tags. tags is the complete new set: an empty array clears it, and a malformed or repeated tag is invalid_request at tags[i].

It is the tag change updateScreen makes, on the dashboard session: the screen revision moves by one, screen.updated carries details.tags and the person as its actor, and the manifest revision never changes. A pairing_pending, active or archived screen accepts it.

The body has no other member: a session renames a screen with patchScreenName and assigns its playlist with patchScreenPlaylist, and cannot change its timezone. If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale).

The dashboard session only; agents change tags with updateScreen or a set_tags, add_tags or remove_tags fleet action. listScreens with tag finds the screen by its new tags. On a protected screen the change is protected_target (409).

Authentication
dashboardSession
Request body
ScreenTagsPatch
Operation ID
patchScreenTags

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
tags (required, ScreenTags)

Fleet selector tags, 0 to 16 unique exact tags, each matching the media tag grammar. On ScreenPatch the array replaces the whole set and an empty array clears it; a duplicate or malformed tag is invalid_request. Changing tags bumps the screen revision (If-Match guards it) and appends screen.updated with details.tags; it never changes the manifest revision.

Tags are never on the runtime manifest and never authorization.

Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/tags'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/fields

Patch Screen Fields

A signed-in person changes a screen's fields with updateScreen's merge patch: a string sets a field, null removes it, and a null fields clears every field. A refused name or value, or a thirty-third field, is invalid_request at fields or fields.NAME.

The screen revision moves by one, a screen that shows a playlist gets a new manifest revision, and the event carries details.fields and the person as its actor. The body has no other member. If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale).

The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen). On a protected screen the change is protected_target (409).

Authentication
dashboardSession
Request body
ScreenFieldsPatch
Operation ID
patchScreenFields

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
fields (required, inline)

Merges into the screen's own values, such as a store number or a region: a string sets a field, null removes it, and a null fields clears every field. Names are 1 to 32 lower case letters, digits or underscores; values 1 to 200 characters after trimming; a screen carries at most 32 fields.

Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/fields'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/location

Patch Screen Location

A signed-in person sets or clears where a screen is with updateScreen's location: an object with latitude, longitude and an optional name and address replaces the location whole, and null clears it. A missing or mistyped member, a coordinate out of range, a name over 40 characters or an address over 200 is invalid_request at location.MEMBER.

The screen revision moves by one, a screen that shows a playlist gets a new manifest revision, and the event carries details.location and the person as its actor. The body has no other member. If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale).

The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen). On a protected screen the change is protected_target (409).

Authentication
dashboardSession
Request body
ScreenLocationPatch
Operation ID
patchScreenLocation

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
location (required, inline)Where the screen is: the object replaces the whole location and null clears it.
Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/location'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/verbosity

Patch Screen Verbosity

A signed-in person sets or clears a screen's log level and toast level with updateScreen's log_level (debug, info, warn, error) and toast_level (info, alert, error): a string sets the level, null clears it, and a member left out stays as it is. Any other value is invalid_request at log_level or toast_level.

The screen revision moves by one, a screen that shows a playlist gets a new manifest revision, and the Player reads the levels from the manifest member verbosity. The body names at least one of the two members and no other. If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale).

The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen).

Authentication
dashboardSession
Request body
ScreenVerbosityPatch
Operation ID
patchScreenVerbosity

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
log_level (optional, inline)The lowest log level the screen's Player generates; error lines are always generated. null clears it (the Player's default). Changing it remints the manifest revision.
toast_level (optional, inline)The lowest toast level the screen's Player shows; error toasts are always shown. null clears it (every toast shows). Changing it remints the manifest revision.
Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/verbosity'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/device-settings

Patch Screen Device Settings

A signed-in person sets or clears a screen's idle-dark and brightness settings and its kiosk lock with updateScreen's display and kiosk members: display.idle {after_s 30 to 86400, wake touch, presence or both}, display.brightness {mode auto or fixed} and kiosk.lock.

A member you send replaces it, null clears it, and a member left out stays as it is; a null display clears both. A value out of range or of the wrong type is invalid_request naming the path (display.idle.after_s).

The screen revision moves by one, a screen that shows a playlist gets a new manifest revision, and the Player reads the settings from the manifest members display (idle, brightness) and kiosk. The body names at least one of display and kiosk and no other member.

If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale). On a protected screen a display change is protected_target (409). The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen).

Authentication
dashboardSession
Request body
ScreenDeviceSettingsPatch
Operation ID
patchScreenDeviceSettings

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
display (optional, inline)

display.idle and display.brightness, as updateScreen's display: a member you send replaces it, null clears it, a member you leave out stays; a null display clears both. Changing either remints the manifest revision of a screen that shows a playlist. On a protected screen it is protected_target.

kiosk (optional, inline)kiosk.lock, as updateScreen's kiosk: lock true pins the Player to the screen, false or null releases it.
Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/device-settings'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/name

Patch Screen Name

A signed-in person renames a screen with updateScreen's name. The name is trimmed and must be 1 to 120 characters without control characters, else invalid_request at name (so is a missing or null name).

The screen revision moves by one and the event is screen.manifest_changed, addressed to the screen, with the person as its actor; the manifest revision stays, so playback is untouched and Players refresh the name from the changed ETag. A rename to the same name still moves the revision and appends screen.updated. The body has no other member.

If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale). The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen).

Authentication
dashboardSession
Request body
ScreenNamePatch
Operation ID
patchScreenName

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
name (required, string)The screen's name, trimmed; 1 to 120 characters after trimming, without control characters. minLength: 1 maxLength: 120
Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/name'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PATCH/api/screens/{id}/playlist

Patch Screen Playlist

A signed-in person assigns the screen's playlist with updateScreen's assignment: the playlist must belong to the project and have an approved version (playlist_not_approved), and a playlist with a format needs a screen whose wall has the same shape (409 playlist_format_mismatch).

The screen revision moves by one and the manifest is reissued from the new playlist; while a takeover, a campaign or a schedule entry is effective the playlist becomes the default behind it. Events carry the person as their actor.

The write is live, so only the project owner or a member who can approve makes it (approver_required); a staff session needs its write lease. The body has no other member. If-Match carries the screen revision and is required (invalid_request when absent, revision_conflict when stale).

The dashboard session only; agents use PATCH /api/screens/{id} (updateScreen). On a protected screen an approver's assignment is a review decided by a second approver (202 pending_review).

Authentication
dashboardSession
Request body
ScreenPlaylistPatch
Operation ID
patchScreenPlaylist

Parameters

NameSend inRequired?Description
idpathrequired
If-MatchheaderrequiredThe screen's current revision, quoted or bare (the ETag of the last read). A stale revision is revision_conflict with current_revision.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
playlist_id (required, inline)

The screen default playlist; null clears its own assignment. A takeover, campaign, schedule entry or inherited folder default can still show content; otherwise the paired Player shows its idle display.

Request template and responses
shell · request template
curl --request PATCH --cookie cookies.txt --cookie-jar cookies.txt --header 'If-Match: "REVISION"' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/playlist'

Responses

StatusMeaningBody and headers
200The screen as stored now; ETag carries its revision.Screen (application/json); headers: ETag
412revision_conflict — If-Match is stale; the error's current_revision carries the current revision.Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
202

The write became a review and waits for a person's approval (docs/reviews.md), under Propose access, or at any access level when it reaches a screen in a protected screen folder, where a second approver decides it (docs/screen-scope.md). A person approves, rejects or requests changes in the dashboard at review.url.

An Idempotency-Key replay answers the same body.

ReviewPending (application/json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/public-id/rotate

Rotate Screen Public Id

Authentication
projectBearer
Request body
none
Operation ID
rotateScreenPublicId

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/public-id/rotate'

Responses

StatusMeaningBody and headers
200

Public URL credential rotated; player public-key enrollment preserved. Every runtime session is invalidated by the new content_access_generation and the live desired and active grants are reissued at that generation for their unchanged manifest revision, so a paired player that re-mints its session keeps authorizing the content it is already showing.

Screen (application/json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/recovery/confirm

Confirm Screen Recovery

Confirms a pending screen recovery. A native pairing start that presented a host duid or serial matching exactly one screen in exactly one project, under a different bound public key, records an offer on that screen (Screen.recovery_pending, project event screen.recovery_offered).

The host object is a hint, never a credential: nothing is rebound until the owning project calls this route. A DUID is readable by any application on the panel, so an offer is a phishing surface.

It is mitigated by liveness (no offer while the bound key showed life in the last ten minutes), a limit of three offers per screen per rolling hour, and this same-project confirmation; recovery_pending.host and the event carry the offering device's platform, model, firmware, and manufacturer so the operator can compare them with the display in front of them before confirming.

Confirmation completes the pending native pairing onto the EXISTING screen: the pairing device receives pairing.claimed as usual and proves possession with pairing.complete, the new key becomes the screen identity, and the previous key retires with a fifteen-minute grace window in which its runtime sessions keep working and it may still mint, after which it is refused.

Playlists, label, timezone, schedules, and history are preserved. Same project only; another project's screen is not_found. If-Match is optional. Emits screen.recovered. recovery_not_offered when nothing is pending, recovery_expired when the pairing session lapsed, recovery_ambiguous when the identifier is attached in more than one place.

Problem responses never echo device identifiers.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
confirmScreenRecovery

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to create or overwrite a key; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/recovery/confirm'

Responses

StatusMeaningBody and headers
200Screen recovered onto the pairing device's key; the response carries the current ETag.Screen (application/json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
410

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/replace

Replace Screen

Moves the device paired as another screen of the project onto this one and archives that screen, so this screen keeps its name, tags, timezone, playlist, schedules, takeover, display schedule and override, video wall, comments and history on new hardware.

The device's public key (or browser credential) now opens this screen, which takes the replacement's host and Player; its health, status, storage, observation and queued commands start over. The key this screen held retires with the recovery grace window: it may still mint for fifteen minutes, then is refused (key_retired). Nothing is unbound.

The replaced screen is archived with archive_reason replaced and keeps no binding or host. Both screens advance content_access_generation, so every session either held ends; the device receives a player.reload addressed to the screen it left (details.reason replaced, valid for 24 hours) and mints again as this screen.

Both screens must be active with a paired Player (a pairing_pending screen or an unpaired replacement is resource_conflict, an archived one screen_archived); with names another screen of the project (invalid_request; another project's screen is not_found); a screen with a video wall needs a replacement Player that declared display.wall (wall_unsupported).

If-Match is optional and checks this screen's revision. Emits the project event screen.replaced (details.from_screen_id) and no screen.archived. An exact Idempotency-Key retry returns this same answer for twenty-four hours.

A caller limited to screens (docs/screen-scope.md) needs the screen and with inside its scope (outside_screen_scope; nothing is archived). A replace where either screen is protected is protected_target.

Authentication
projectBearer OR dashboardSession
Request body
ScreenReplaceWrite
Operation ID
replaceScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to create or overwrite a key; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
with (required, string)

The id of the screen, in the same project, whose paired device takes over the screen in the path. It must be another active screen with a paired Player; it is archived with archive_reason replaced. minLength: 1 maxLength: 256

Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/replace'

Responses

StatusMeaningBody and headers
200The device now opens this screen; the response is this screen with its new revision and the current ETag.Screen (application/json)
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409resource_conflict, screen_archived, wall_unsupported, or protected_target when either screen is in a protected screen folder.Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/archive

Archive Screen

Hides the screen from the default list and clears the live glass to the "Screen archived" status. Does not unbind the player public key. Releases screen_count quota. Cancels the screen's queued reboot, clear_cache, restart_app and update commands; a queued reload is still delivered. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
archiveScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/archive'

Responses

StatusMeaningBody and headers
200Screen archived.Screen (application/json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/unarchive

Unarchive Screen

Restores an archived screen to the default list and remints a normal manifest. Must pass screen admission. Does not change the bound public key.

The manifest is issued again, so the screen's playlist is checked as an assignment is; a playlist that references missing or unready content answers resource_conflict naming the playlist, and the screen stays archived until the playlist is fixed.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
unarchiveScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/unarchive'

Responses

StatusMeaningBody and headers
200Screen unarchived.Screen (application/json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
413

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/reload

Reload Screen

Asks the Player of the named active or archived screen to reload (docs/player-compatibility.md §6.3). The optional body sets expires_in_s, how long the reload stays actionable (60 to 86400 seconds, default 86400, 24 hours); a value out of range is invalid_request naming expires_in_s.

A screen that is online is sent the durable per-screen player.reload event at once (details.reason project, a new reload_id, spread_s 0, expires_at) and the reload is recorded in Screen.commands as sent.

A screen that is offline holds the reload as queued with no event; when the backend applies the screen's next online transition before expires_at the event is appended, with the same reload_id and expires_at, and the command becomes sent. A newer reload supersedes an older one still queued.

A queued reload past expires_at reads expired, and POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued. The runtime SSE stream relays the event to every runtime session. A Player ignores a reload within ten minutes of the last one it acted on.

A web Player reloads at its next page boundary; a native Player remints, refetches its manifest, and checks for an update. The screen revision does not change. If-Match and Idempotency-Key are optional, as on archive; an exact Idempotency-Key retry returns the original body for twenty-four hours.

A pairing_pending screen has no Player yet and answers resource_conflict. Screen messages are exempt from the 1-credit API meter.

Authentication
projectBearer OR dashboardSession
Request body
ScreenCommandWrite
Operation ID
reloadScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
expires_in_s (optional, integer)How long the command stays actionable, in seconds from the request. A queued command is sent only before it expires; a Player ignores one after expires_at. default: 86400 minimum: 60 maximum: 86400
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/reload'

Responses

StatusMeaningBody and headers
202

Accepted. state is sent when the reload went to the online screen's Player, queued when it waits for the screen to come online. The reload is actionable until expires_at. The ETag is the unchanged screen revision.

ScreenReloadAccepted (application/json); headers: Cache-Control, ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/playlist-schedule

Get Screen Playlist Schedule

Returns the screen's server-evaluated playlist schedule: entries in priority order (empty when the screen has none), updated_at, and the effective_playlist they currently produce. The ETag is the screen revision. pairing_pending, active, and archived screens are readable; another project's screen is not_found.

Authentication
projectBearer
Request body
none
Operation ID
getScreenPlaylistSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule'

Responses

StatusMeaningBody and headers
200Playlist schedule.ScreenPlaylistScheduleView (application/json); headers: ETag
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PUT/api/screens/{id}/playlist-schedule

Set Screen Playlist Schedule

Replaces the screen's playlist schedule. The server evaluates it, never the Player: the first entry whose rule matches the screen's civil time (screenrig.schedule/v1 windows and from/until, in the screen timezone, including daylight-saving transitions and windows that cross midnight) is the effective playlist; when none matches, the assigned playlist_id is.

A takeover still wins over every entry. The screen must have a timezone and an assigned default playlist_id (invalid_request otherwise), so there is always something to fall back to.

Every referenced playlist is validated against the screen exactly as an assignment is (owned, ready references, page visibility needs a timezone, and a playlist with a format needs a screen whose wall has the same shape, else 409 playlist_format_mismatch), so a playlist the screen would refuse is refused here; the check writes the playlist document, so a concurrent playlist delete conflicts instead of racing it.

If a scheduled playlist later cannot be shown (for example its content no longer resolves), its entries are skipped at evaluation and screen.playlist_unavailable (warning, details playlist_id, entry_ids, code) is appended.

When the effective playlist changes the manifest is re-minted from it and the Player is signalled with screen.manifest_changed, as for an assignment, and screen.playlist_switched is appended. The screen revision is bumped (If-Match guards it) and screen.updated is appended with details.playlist_schedule_entries.

An archived screen answers screen_archived; its schedule, takeover, and default stay referenced (they block playlist delete) and are re-resolved when it is unarchived. Rate limits: screen-control-org 600, screen-control-screen 20, and screen-control-ip 60 per minute, shared with DELETE and the takeover routes.

On a protected screen the schedule is a review decided by a second approver (202 pending_review) at every access level. A new entry with paused true (a draft) is schedule change control, which the Enterprise plan includes; a project whose plan lacks it is refused with feature_not_in_plan (402).

Entries already stored may stay paused, and pausing a stored entry is open on every plan.

Authentication
projectBearer
Request body
ScreenPlaylistScheduleWrite
Operation ID
setScreenPlaylistSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
entries (required, array)Priority order: the first matching entry wins. DELETE clears the schedule.
Request template and responses
shell · request template
curl --request PUT --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule'

Responses

StatusMeaningBody and headers
202The write became a review under Propose access and waits for a person's approval (docs/reviews.md). An Idempotency-Key replay answers the same body.ReviewPending (application/json); headers: RateLimit-Policy, RateLimit
200Screen with the stored schedule and its effective_playlist. The ETag is the new revision.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
402

feature_not_in_plan — Schedule change control is part of the Enterprise plan; the problem names the feature, the plan the account is on and required_plan. An entry that locks a playlist to display 2 or beyond of a video wall (displays) other than the screen's stored entry is part of Plus. The problem names the feature, the project's plan and required_plan.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/playlist-schedule

Clear Screen Playlist Schedule

Removes the screen's playlist schedule; the takeover, else a campaign that holds, else the assigned playlist, becomes effective, with the same manifest signalling as PUT. A screen without a schedule answers 200 unchanged (no revision bump, no event).

On a protected screen clearing the schedule is a review decided by a second approver (202 pending_review) at every access level.

Authentication
projectBearer
Request body
none
Operation ID
clearScreenPlaylistSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule'

Responses

StatusMeaningBody and headers
202The write became a review under Propose access and waits for a person's approval (docs/reviews.md). An Idempotency-Key replay answers the same body.ReviewPending (application/json); headers: RateLimit-Policy, RateLimit
200Screen without a playlist schedule.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/playlist-schedule/preview

Preview Screen Playlist Schedule

What replacing the screen's playlist schedule with entries would change, without making it.

The entries are checked as PUT checks them (grammar, the screen's timezone and displays, a default playlist, and each playlist as an assignment: it exists, has an approved version, fits the screen's wall and the region it covers, and its references resolve), so a preview refuses what the PUT refuses.

The answer says whether the screen would gain or lose levels of its schedule on its stack (a paused entry is on no stack, so publishing one gains it), and the screen's schedule calendar as it is (before) and as it would be (after) over from to to (default: a week from now; at most 93 days). Read access: nothing is written.

Authentication
projectBearer OR dashboardSession
Request body
ScreenSchedulePreviewRequest
Operation ID
previewScreenPlaylistSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired

Request body fields

FieldDescription
entries (required, array)
from (optional, string)Start of the calendars; defaults to now. format: "date-time"
to (optional, string)End of the calendars; defaults to a week after from, at most 93 days after it. format: "date-time"
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule/preview'

Responses

StatusMeaningBody and headers
200The preview.SchedulePreview (application/json)
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/playlist-schedule/revisions

List Screen Playlist Schedule Revisions

The screen's playlist schedule revisions, newest first: the whole entries list as stored after each write (a PUT, a DELETE, a restore, a schedule import), with the kind of change and who made it. A revision is numbered by the screen's revision at the write, so numbers have gaps where the screen changed otherwise.

A screen whose history has no row yet lists its schedule as it stands, with change baseline. Revisions go with the screen's purge. At most 50 per page; next_cursor while more remain, null on the last page.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
listScreenPlaylistScheduleRevisions

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
afterqueryoptionalnext_cursor of the previous page of the same list, with the same filters. Omitted starts at the newest row. A value that is not such a cursor is invalid_request.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule/revisions'

Responses

StatusMeaningBody and headers
200The screen's schedule revisions, newest first.ScreenScheduleRevisionList (application/json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/playlist-schedule/revisions/{revision}/restore

Restore Screen Playlist Schedule Revision

Puts an earlier revision's entries back as the screen's schedule: the same write as PUT /api/screens/{id}/playlist-schedule with those entries (or DELETE when that revision had none), checked as they are checked now (a playlist deleted since refuses it), so under Propose access the restore becomes the same screen_change review the PUT becomes.

If-Match is required and names the screen's current revision. Earlier revisions stay as they were.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
restoreScreenPlaylistScheduleRevision

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
revisionpathrequiredA revision of the record, as its revisions list numbers them.
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://api.screenrig.ai/api/screens/RESOURCE_ID/playlist-schedule/revisions/REVISION/restore'

Responses

StatusMeaningBody and headers
202The write became a review under Propose access and waits for a person's approval (docs/reviews.md). An Idempotency-Key replay answers the same body.ReviewPending (application/json); headers: RateLimit-Policy, RateLimit
200Screen with the restored schedule and its effective_playlist. The ETag is the new revision.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/takeover

Set Screen Takeover

Takes over the screen with one playlist ahead of campaigns, its playlist schedule and assigned playlist, until until (RFC 3339, strictly in the future and at most 7 days ahead) or, when until is null or omitted, until the takeover is cleared. reason is optional, at most 120 characters.

The screen must have an assigned default playlist_id (invalid_request otherwise). A takeover replaces an earlier one (screen.takeover_ended with reason replaced, or expired when the earlier one had already ended).

The playlist is validated as an assignment, including its format (a playlist with a format needs a screen whose wall has the same shape, else 409 playlist_format_mismatch). A takeover whose playlist later cannot be shown ends (screen.takeover_ended with reason playlist_deleted or playlist_unavailable).

Appends screen.takeover_started and, when the effective playlist changes, screen.playlist_switched plus the Player's screen.manifest_changed. When until passes, the boundary worker ends the takeover within 60 seconds (screen.takeover_ended with reason expired). The screen revision is bumped (If-Match guards it).

An archived screen answers screen_archived; unarchive re-resolves first, so a takeover that ended while archived ends then. The same screen-control rate limits as the schedule routes apply. On a protected screen a takeover is a review decided by a second approver (202 pending_review) at every access level.

Authentication
projectBearer
Request body
ScreenTakeoverWrite
Operation ID
setScreenTakeover

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
playlist_id (required, string)minLength: 1
until (optional, inline)Strictly in the future and at most 7 days ahead. null or omitted holds the takeover until it is cleared.
reason (optional, string)Operator note carried on the takeover and its events. No control characters. maxLength: 120
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/takeover'

Responses

StatusMeaningBody and headers
202The write became a review under Propose access and waits for a person's approval (docs/reviews.md). An Idempotency-Key replay answers the same body.ReviewPending (application/json); headers: RateLimit-Policy, RateLimit
200Screen with the takeover and its effective_playlist. The ETag is the new revision.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/takeover

Clear Screen Takeover

Ends the takeover (screen.takeover_ended with reason cleared); the schedule, else the assigned playlist, becomes effective with the same manifest signalling. A screen without a takeover answers 200 unchanged (no revision bump, no event).

An archived screen's takeover is cleared too: it stays archived, its Player gets no signal, and unarchive resolves the effective playlist. On a protected screen clearing a takeover is a review decided by a second approver (202 pending_review) at every access level.

Authentication
projectBearer
Request body
none
Operation ID
clearScreenTakeover

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Screenrig-Review-Noteheaderoptional

Optional proposer note on a review-class write, sent as percent-encoded UTF-8 (what JavaScript's encodeURIComponent writes). The server percent-decodes it (an invalid escape is 400 invalid_request); the decoded note is plain text, at most 280 characters after trimming, no control characters (else 400 invalid_request).

Stored on the review when the write becomes one; ignored when it applies live.

If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/takeover'

Responses

StatusMeaningBody and headers
202The write became a review under Propose access and waits for a person's approval (docs/reviews.md). An Idempotency-Key replay answers the same body.ReviewPending (application/json); headers: RateLimit-Policy, RateLimit
200Screen without a takeover.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/tab-shares

Start Tab Share

Shows browser tabs on screens. Makes one temporary playlist of a full-canvas 1920x1080 iframe page per tab and takes every target screen over with it (reason "Shared browser tab") until until, at most 24 hours ahead (the default).

Targets are the union of screen_ids, every active screen in folder_ids and the folders inside them, and every active screen carrying any of tags; offline screens are included and show the share when they return.

A caller limited to screens (docs/screen-scope.md) reaches only the screens in its scope: a screen outside it is skipped (outside_screen_scope), and the schedule of the request is otherwise the same.

One tab stays up until the share ends; several advance after each tab's duration_s. reload_s reloads every page. qr adds a QR code of the page address, about 14% of the canvas height, in the bottom-right corner. cookies are the sender's sign-in for the pages: they are sealed at rest, never returned by any read, event, audit entry or revision, and served only in the runtime manifest of a screen showing the share (the iframe cookies member); a Player that cannot set them ignores them, and the web Player and the shells that hand off to it do.

A target that cannot be taken over (protected folder, no default playlist, archived, not found, format mismatch, outside scope, rate limited) is listed in skipped and does not fail the request. A screen already showing an earlier share is taken over by this one, and the earlier playlist is deleted once no screen shows it.

When no target is taken over the temporary playlist is deleted and the answer is the problem of the one target, or 409 resource_conflict naming the reasons. warnings lists tab addresses the backend could not embed (embedding_blocked: X-Frame-Options or frame-ancestors refuse the Player web app), checked once per address with a 3 second budget; it never blocks the share.

The screen-control rate limits apply per target screen (organization and screen), and the IP limit once per request. Every call is a new share; an Idempotency-Key replays nothing. The change is live: refused with insufficient_access under Propose access, and on the dashboard lane with approver_required to a member who cannot approve reviews.

On the dashboard lane the session's current project is used (no_project when none), and the request may come from the dashboard origin or from a Chrome or Firefox extension origin (chrome-extension://ID, moz-extension://UUID) with Sec-Fetch-Site absent, same-origin or none; a present X-ScreenRig-CSRF header must match csrf_token from GET /api/session.

Only this route, DELETE /api/tab-shares/{id}, POST /api/playlists/{id}/pages and POST /api/screens/{id}/screenshot take an extension origin.

Authentication
projectBearer OR dashboardSession
Request body
TabShareWrite
Operation ID
startTabShare

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.

Request body fields

FieldDescription
screen_ids (optional, array)Screens by id. Duplicates collapse.
folder_ids (optional, array)Screen folders; each includes every folder inside it.
tags (optional, array)A screen carrying any of the tags.
tabs (required, array)
cookies (optional, array)The sender's cookies for the pages, at most 64 KiB encoded. Secrets; see POST /api/tab-shares.
reload_s (optional, integer)0 (never, the default) or 60 to 86400: every page's iframe reloads this often.
until (optional, string)Strictly in the future and at most 24 hours ahead; 24 hours from now when omitted. The end of the takeover on every target and the expiry of the temporary playlist. format: "date-time"
qr (optional, boolean)When true every page carries a QR code of its address in the bottom-right corner. Default false.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/tab-shares'

Responses

StatusMeaningBody and headers
200The share. At least one screen was taken over.TabShare (application/json); headers: RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/tab-shares/{id}

Get Tab Share

Reads a share: its end time and the screens whose takeover is still its playlist (a screen someone took over since, or that was archived, is not listed). 404 not_found once the share ended, expired or never was. A caller limited to screens (docs/screen-scope.md) sees only the screens in its scope. No extension-origin rule applies to a read.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getTabShare

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/tab-shares/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200The share and the screens still showing it.TabShareState (application/json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/tab-shares/{id}

Stop Tab Share

Ends a share: clears the takeover of every screen whose takeover is still its playlist (screen.takeover_ended with reason cleared, the schedule, else the assigned playlist, becoming effective with the same manifest signalling) and deletes the playlist. Allowed on screens in protected folders.

A screen someone took over since is left alone. 404 not_found when the share already ended; a client treats that as ended. One unit of each screen-control limit is spent per request. A caller limited to screens clears only the screens in its scope. The lanes, access rules and extension-origin rule are those of POST /api/tab-shares.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
stopTabShare

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/tab-shares/RESOURCE_ID'

Responses

StatusMeaningBody and headers
200The screens that were cleared.TabShareStopped (application/json); headers: RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/play-page

Play Screen Page

Asks the screen's Player to start one page of the playlist it is playing now, so a screenshot taken next shows that page without waiting out the rotation (docs/player-compatibility.md §6.3.1).

The page must be a page of the screen's effective playlist, the one its manifest is built from: an active takeover, else a campaign that holds, else the current playlist schedule entry, else the assigned playlist. Otherwise 409 page_not_on_screen, whose detail names that playlist.

The screen's host hint must declare the play_page capability, else 409 play_page_unsupported and nothing is sent; update the Player. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict.

Appends the per-screen runtime command player.play_page (details page_id, playlist_id, manifest_revision, expires_at sixty seconds later; never delivered after expires_at). The Player starts the page from its beginning as if the rotation had reached it and continues the rotation from there. The screen revision does not change.

The Idempotency-Key is required, as for toast; an exact retry returns the original body for twenty-four hours. A refused request, a failed one, and an exact replay spend no rate-limit budget. Screen messages are exempt from the 1-credit API meter. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer
Request body
ScreenPlayPageWrite
Operation ID
playScreenPage

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Idempotency-Keyheaderrequired

Request body fields

FieldDescription
page_id (required, string)The id of a page of the playlist the screen is playing now (an id in that playlist's pages). minLength: 1 maxLength: 128
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Idempotency-Key: REQUEST_ID' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/play-page'

Responses

StatusMeaningBody and headers
202Accepted. The command is actionable until expires_at. An exact idempotent retry returns this same body.ScreenPlayPageAccepted (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/identify

Identify Screen

Asks the screen's Player to show the screen's name over its content for duration_ms (2000 to 600000, default 60000), so a person in front of several displays can tell which one a record is (docs/player-compatibility.md §6.3.2).

Appends the per-screen runtime command player.identify (details identify_id, label, screen_id, duration_ms, at, expires_at sixty seconds after at; never delivered after expires_at).

The Player draws a full-screen overlay above its content, the name very large and the screen id small below it, for duration_ms from receipt; playback continues underneath and a newer identify replaces the overlay.

The screen's host hint must declare the identify capability, else 409 identify_unsupported and nothing is sent; update the Player, or show the name with a toast. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict. The screen revision does not change.

The body and the Idempotency-Key are optional; an exact retry returns the original body for twenty-four hours. A refused request, a failed one, and an exact replay spend no rate-limit budget. Screen messages are exempt from the 1-credit API meter.

Authentication
projectBearer OR dashboardSession
Request body
ScreenIdentifyWrite
Operation ID
identifyScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
duration_ms (optional, integer)How long the overlay stays up, in milliseconds from the Player's receipt. Omitted values default to 60000. default: 60000 minimum: 2000 maximum: 600000
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/identify'

Responses

StatusMeaningBody and headers
202Accepted. The command is actionable until expires_at. An exact idempotent retry returns this same body.ScreenIdentifyAccepted (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/suspend

Suspend Screen

Suspends the screen: its Player shows message instead of its content (docs/player-compatibility.md §6.9). The message is 1 to 280 characters after trimming; line feed is the only accepted control character.

Nothing else changes: the playlist, schedule, takeover, display control and every other setting stay and keep evolving, and resume shows what the screen would be showing now. Screen.suspension carries the message and since. Suspending a suspended screen replaces the message and keeps since.

The runtime manifest of a suspended screen has pages [] and a suspension member, and a manifest revision of its own, with or without an assigned playlist; the Player is told to refetch it at once. Appends the project-only screen.suspended (details message). An archived screen answers screen_archived. If-Match and Idempotency-Key are optional, as on archive.

A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer OR dashboardSession
Request body
ScreenSuspendWrite
Operation ID
suspendScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
message (required, string)The notice the screen shows, 1 to 280 characters after trimming. Line feed is the only accepted control character; a Player wraps the text and keeps line feeds. minLength: 1 maxLength: 280
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/suspend'

Responses

StatusMeaningBody and headers
200Screen suspended. The ETag is the new screen revision.Screen (application/json); headers: ETag
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/resume

Resume Screen

Ends the screen's suspension: its Player shows the screen's own content again, from the manifest the screen would be served now (docs/player-compatibility.md §6.9). The Player is told to refetch at once. Appends the project-only screen.resumed. Resuming a screen that is not suspended answers 200 with the screen unchanged: no revision bump and no event.

An archived screen answers screen_archived. No body. If-Match and Idempotency-Key are optional, as on archive.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
resumeScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/resume'

Responses

StatusMeaningBody and headers
200Screen resumed, or not suspended. The ETag is the screen revision.Screen (application/json); headers: ETag
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/reboot

Reboot Screen

Asks the screen's Player to reboot the device (docs/player-compatibility.md §6.5). The optional body sets expires_in_s, how long the reboot stays actionable (60 to 86400 seconds, default 86400, 24 hours); a value out of range is invalid_request naming expires_in_s. Always appends the project-only screen.reboot_requested.

A screen that is online is sent the per-screen runtime command player.reboot at once (details reboot_id, reason project, at, expires_at; never delivered after expires_at) and the reboot is recorded in Screen.commands as sent.

A screen that is offline holds the reboot as queued with no event; when the backend applies the screen's next online transition before expires_at the event is appended, with the same reboot_id and expires_at, and the command becomes sent. A sent reboot becomes done when a health report carrying uptime_s puts the boot after it was sent.

A newer reboot supersedes an older one still queued. A queued reboot past expires_at reads expired, and POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict.

The screen's host hint must declare the reboot capability, else 409 reboot_unsupported and nothing is recorded. The screen revision does not change. If-Match and Idempotency-Key are optional; an exact retry returns the same body for twenty-four hours.

At most 2 per screen per 10 minutes; a refused request (reboot_unsupported, not_found, a conflict), a failed one, and an exact Idempotency-Key replay spend nothing.

From the moment the reboot is sent until a health report proves it done or ten minutes pass, the screen raises no screen_offline, display_disconnected or crashing notice or alert; a condition that still holds then opens normally. The reboot schedule (PUT /api/screens/{id}/reboot-schedule) issues the same reboot with source schedule.

Authentication
projectBearer OR dashboardSession
Request body
ScreenCommandWrite
Operation ID
rebootScreen

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
expires_in_s (optional, integer)How long the command stays actionable, in seconds from the request. A queued command is sent only before it expires; a Player ignores one after expires_at. default: 86400 minimum: 60 maximum: 86400
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/reboot'

Responses

StatusMeaningBody and headers
202

Accepted. state is sent when the reboot went to the online screen's Player, queued when it waits for the screen to come online. The reboot is actionable until expires_at. The ETag is the unchanged screen revision.

ScreenRebootAccepted (application/json); headers: Cache-Control, ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/clear-cache

Clear Screen Cache

Asks the screen's Player to clear its caches (docs/player-compatibility.md §6.5.1). The Player deletes its downloaded media, application packages and data caches, keeps its pairing, identity and settings, then fetches the manifest and content again.

The optional body sets expires_in_s, how long the command stays actionable (60 to 86400 seconds, default 86400, 24 hours); a value out of range is invalid_request naming expires_in_s. Always appends the project-only screen.command_requested.

A screen that is online is sent the per-screen runtime command player.clear_cache at once (details command_id, command, reason project, at, expires_at; never delivered after expires_at) and the command is recorded in Screen.commands as sent.

A screen that is offline holds the command as queued with no event; when the backend applies the screen's next online transition before expires_at the event is appended, with the same command_id and expires_at, and the command becomes sent.

The Player reports how it ended: the command becomes done or failed in Screen.commands with the cause the Player reported (cause, detail), and the project-only screen.command_result is appended. A sent command with no report stays sent.

A newer command of the same type supersedes one still queued, and POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict.

The screen's host hint must declare the clear_cache capability, else 409 command_unsupported and nothing is recorded. The screen revision does not change. If-Match and Idempotency-Key are optional; an exact retry returns the same body for twenty-four hours.

At most 2 per screen per 10 minutes across clear-cache, restart-app and update; a refused request (command_unsupported, not_found, a conflict), a failed one, and an exact Idempotency-Key replay spend nothing.

Authentication
projectBearer OR dashboardSession
Request body
ScreenCommandWrite
Operation ID
clearScreenCache

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
expires_in_s (optional, integer)How long the command stays actionable, in seconds from the request. A queued command is sent only before it expires; a Player ignores one after expires_at. default: 86400 minimum: 60 maximum: 86400
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/clear-cache'

Responses

StatusMeaningBody and headers
202

Accepted. state is sent when the command went to the online screen's Player, queued when it waits for the screen to come online. The command is actionable until expires_at. The ETag is the unchanged screen revision.

ScreenMaintenanceAccepted (application/json); headers: Cache-Control, ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/restart-app

Restart Screen App

Asks the screen's Player to restart its application, not the device (docs/player-compatibility.md §6.5.1). The Player process restarts and reports from the new process. The optional body sets expires_in_s, how long the command stays actionable (60 to 86400 seconds, default 86400, 24 hours); a value out of range is invalid_request naming expires_in_s.

Always appends the project-only screen.command_requested. A screen that is online is sent the per-screen runtime command player.restart_app at once (details command_id, command, reason project, at, expires_at; never delivered after expires_at) and the command is recorded in Screen.commands as sent.

A screen that is offline holds the command as queued with no event; when the backend applies the screen's next online transition before expires_at the event is appended, with the same command_id and expires_at, and the command becomes sent.

The Player reports how it ended: the command becomes done or failed in Screen.commands with the cause the Player reported (cause, detail), and the project-only screen.command_result is appended. A sent command with no report stays sent.

A newer command of the same type supersedes one still queued, and POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict.

The screen's host hint must declare the restart_app capability, else 409 command_unsupported and nothing is recorded. The screen revision does not change. If-Match and Idempotency-Key are optional; an exact retry returns the same body for twenty-four hours.

At most 2 per screen per 10 minutes across clear-cache, restart-app and update; a refused request (command_unsupported, not_found, a conflict), a failed one, and an exact Idempotency-Key replay spend nothing.

Authentication
projectBearer OR dashboardSession
Request body
ScreenCommandWrite
Operation ID
restartScreenApp

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
expires_in_s (optional, integer)How long the command stays actionable, in seconds from the request. A queued command is sent only before it expires; a Player ignores one after expires_at. default: 86400 minimum: 60 maximum: 86400
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/restart-app'

Responses

StatusMeaningBody and headers
202

Accepted. state is sent when the command went to the online screen's Player, queued when it waits for the screen to come online. The command is actionable until expires_at. The ETag is the unchanged screen revision.

ScreenMaintenanceAccepted (application/json); headers: Cache-Control, ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/update

Update Screen Player

Asks the screen's Player to check for the newest Player release now and install it (docs/player- compatibility.md §6.5.1). The result cause is up_to_date when the newest release already runs and updated when a release was installed; a store-managed or device-managed install declares no update capability.

The optional body sets expires_in_s, how long the command stays actionable (60 to 86400 seconds, default 86400, 24 hours); a value out of range is invalid_request naming expires_in_s. Always appends the project-only screen.command_requested.

A screen that is online is sent the per-screen runtime command player.update at once (details command_id, command, reason project, at, expires_at; never delivered after expires_at) and the command is recorded in Screen.commands as sent.

A screen that is offline holds the command as queued with no event; when the backend applies the screen's next online transition before expires_at the event is appended, with the same command_id and expires_at, and the command becomes sent.

The Player reports how it ended: the command becomes done or failed in Screen.commands with the cause the Player reported (cause, detail), and the project-only screen.command_result is appended. A sent command with no report stays sent.

A newer command of the same type supersedes one still queued, and POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued. The screen must be active; an archived screen answers screen_archived and a pairing_pending one resource_conflict.

The screen's host hint must declare the update capability, else 409 command_unsupported and nothing is recorded. The screen revision does not change. If-Match and Idempotency-Key are optional; an exact retry returns the same body for twenty-four hours.

At most 2 per screen per 10 minutes across clear-cache, restart-app and update; a refused request (command_unsupported, not_found, a conflict), a failed one, and an exact Idempotency-Key replay spend nothing.

Authentication
projectBearer OR dashboardSession
Request body
ScreenCommandWrite
Operation ID
updateScreenPlayer

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
expires_in_s (optional, integer)How long the command stays actionable, in seconds from the request. A queued command is sent only before it expires; a Player ignores one after expires_at. default: 86400 minimum: 60 maximum: 86400
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/update'

Responses

StatusMeaningBody and headers
202

Accepted. state is sent when the command went to the online screen's Player, queued when it waits for the screen to come online. The command is actionable until expires_at. The ETag is the unchanged screen revision.

ScreenMaintenanceAccepted (application/json); headers: Cache-Control, ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/commands

List Screen Commands

Lists every reboot and reload asked of an active or archived screen, newest first: the commands Screen.commands holds (its newest 10) and every older one, with the state each reached. A queued command past expires_at reads expired. A command that was still queued when the screen's device was replaced reads cancelled.

Cancel one still queued with POST /api/screens/{id}/commands/{command_id}/cancel.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
listScreenCommands

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
cursorqueryoptionalThe next_cursor of the previous page.
limitqueryoptional
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/commands'

Responses

StatusMeaningBody and headers
200One page of the screen's commands.ScreenCommandPage (application/json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/commands/{command_id}/cancel

Cancel Screen Command

Cancels a reboot or reload that is still queued for the screen, so it is never sent (docs/player-compatibility.md §6.3, §6.5). command_id is an id in Screen.commands, or the reboot_id or reload_id of the 202 answer. Only a command whose state is queued can be cancelled; it becomes cancelled.

A command already sent (sent, done) answers 409 resource_conflict "The command was already sent."; one that is no longer queued (expired, cancelled, superseded) answers 409 resource_conflict "The command is no longer queued."; an id the screen does not list answers 404 not_found. The screen's list keeps its newest 10 commands.

The screen revision does not change. If-Match and Idempotency-Key are optional; an exact retry returns the same screen for twenty-four hours.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
cancelScreenCommand

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
command_idpathrequiredThe id of one of the screen's commands: the id in Screen.commands, the reboot_id or reload_id of the 202 answer.
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/commands/COMMAND_ID/cancel'

Responses

StatusMeaningBody and headers
200The screen, with the command cancelled. The ETag is the unchanged screen revision.Screen (application/json); headers: ETag
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/display

Set Screen Display

Requests display on or off now: a manual override of the display schedule (docs/player-compatibility.md §6.5). power is on or off. until (RFC 3339, strictly future, at most 7 days ahead) ends it; without until it ends at the display schedule's next boundary when a schedule is enabled, else it holds until replaced.

Stores the override (Screen.display.override), re-mints the manifest (its display member carries the override so an offline Player keeps it), appends the runtime command player.display (details override_id, power, until, at, expires_at) and the project-only screen.display_changed, and bumps the screen revision (If-Match guards it). The screen must be active.

What the Player achieved is reported back in its health display.power (Screen.display.reported). Success saves intent without waiting for a report; Screen.display.override_status compares subsequent observations and Screen.display.control names the advertised control method.

A scrim-only Player removes its overlay on an on request without a hardware wake command.

Without until and without a schedule boundary inside the next eight days (no enabled schedule, or none that changes), the override holds until DELETE /api/screens/{id}/display or a replacement; a later display-schedule PUT or DELETE, or a timezone change, re-bounds an until-less override to the new next boundary.

A refused or failed request, and an exact Idempotency-Key replay, spend no budget. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer OR dashboardSession
Request body
ScreenDisplayWrite
Operation ID
setScreenDisplay

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
power (required, string)Allowed: "on", "off"
until (optional, inline)Strictly future, at most 7 days ahead. Omitted or null: until the display schedule's next boundary, else until replaced.
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/display'

Responses

StatusMeaningBody and headers
200Screen with its display state.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/display

Clear Screen Display

Ends the manual display override so the display schedule (else on) applies again. Re-mints the manifest (its display member drops the override; the Player follows screen.manifest_changed), appends screen.display_changed with change override_cleared, and bumps the revision. A screen without an active override answers 200 unchanged.

A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
clearScreenDisplay

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/display'

Responses

StatusMeaningBody and headers
200Screen with its display state.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/display-schedule

Get Screen Display Schedule

Returns display_schedule (null when none) and the screen's display state. The ETag is the screen revision.

Authentication
projectBearer
Request body
none
Operation ID
getScreenDisplaySchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/display-schedule'

Responses

StatusMeaningBody and headers
200Display schedule.ScreenDisplayScheduleView (application/json); headers: ETag
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PUT/api/screens/{id}/display-schedule

Set Screen Display Schedule

Replaces the display schedule: enabled and 1 to 16 screenrig.schedule/v1 windows (days, start/end HH:MM, end <= start crosses midnight owned by the start day, whole day without edges) when the display is ON; outside every window the Player puts the display to standby.

Evaluated on the device in the screen timezone (required, invalid_request otherwise), so it keeps working offline: the manifest's display member carries it. enabled false keeps the windows and leaves the display on. Re-mints the manifest, appends screen.display_changed, bumps the revision (If-Match guards it). The screen must be pairing_pending or active.

A screen with no manifest yet (never minted, or no playlist) stores the schedule and its first manifest carries it; a screen without a playlist applies it once a playlist is assigned. An until-less override is re-bounded to the new schedule's next boundary. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer
Request body
ScreenDisplayScheduleWrite
Operation ID
setScreenDisplaySchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
enabled (required, boolean)
windows (required, array)ON windows.
Request template and responses
shell · request template
curl --request PUT --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/display-schedule'

Responses

StatusMeaningBody and headers
200Screen with its display state.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/display-schedule

Clear Screen Display Schedule

Removes the display schedule (the display stays on unless overridden). Clearing none answers 200 unchanged. A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer
Request body
none
Operation ID
clearScreenDisplaySchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/display-schedule'

Responses

StatusMeaningBody and headers
200Screen with its display state.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403outside_screen_scope as on OutsideScreenScope, or approver_required - a member limited to screens who cannot approve reviews does not change what a screen plays or when (docs/screen-scope.md).Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/reboot-schedule

Get Screen Reboot Schedule

Returns reboot_schedule (null when none) and next_reboot_at, the start of the next window the backend reboots the screen at (null when there is none). The ETag is the screen revision.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenRebootSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/reboot-schedule'

Responses

StatusMeaningBody and headers
200Reboot schedule.ScreenRebootScheduleView (application/json); headers: ETag
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PUT/api/screens/{id}/reboot-schedule

Set Screen Reboot Schedule

Replaces the reboot schedule: enabled and 1 to 16 screenrig.schedule/v1 windows (days, start/end HH:MM, end <= start crosses midnight owned by the start day, whole day without edges), each 5 minutes to 24 hours long.

At the start of each window in the screen timezone (required, invalid_request otherwise) the backend issues the same reboot POST /api/screens/{id}/reboot does, with source schedule in Screen.commands, screen.reboot_requested and the player.reboot details.

A start inside a spring-forward gap fires at the first valid minute of the window; a window with no valid minute that day, because it lies wholly inside the gap, is skipped with screen.reboot_skipped reason window_missed (next_reboot_at shows the minute the gap ends). A fall-back repeat fires once per window per local date.

A screen that is online is sent the reboot at once; an offline one keeps it queued only until its window ends (expires_at), so a late reboot never lands outside it. An occurrence never replaces a reboot a person asked for that still waits for the screen: it is skipped with screen.reboot_skipped reason reboot_pending.

A timezone change cancels the scheduled reboots still waiting and moves next_reboot_at to the new zone.

A reboot, scheduled or asked for, raises no screen_offline, display_disconnected or crashing alert for ten minutes after it is sent, and a notice for one of them that falls due in that time waits until the period ends plus its hold (a crashing notice is skipped as planned_reboot). enabled false keeps the windows and reboots nothing.

Time windows that leave no gap, so that no start follows, are invalid_request. The screen's host hint must declare the reboot capability, else 409 reboot_unsupported and nothing is stored; a screen that loses it later skips each window with screen.reboot_skipped and keeps its schedule.

Appends screen.reboot_schedule_changed, bumps the revision (If-Match guards it), and never re-mints the manifest. The screen must be active.

Authentication
projectBearer
Request body
ScreenRebootScheduleWrite
Operation ID
setScreenRebootSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.

Request body fields

FieldDescription
enabled (required, boolean)
windows (required, array)Reboot windows: the backend reboots the screen at the start of each, in the screen timezone. Each is 5 minutes to 24 hours long.
Request template and responses
shell · request template
curl --request PUT --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/reboot-schedule'

Responses

StatusMeaningBody and headers
200Screen with its reboot schedule and next_reboot_at.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
402feature_not_in_plan — Scheduled reboots are part of Plus; enabled true needs it, enabled false and DELETE do not. The problem names the feature, the project's plan and required_plan.Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/reboot-schedule

Clear Screen Reboot Schedule

Removes the reboot schedule and next_reboot_at; a reboot already issued is not cancelled (POST /api/screens/{id}/commands/{command_id}/cancel cancels one still queued). Clearing none answers 200 unchanged.

Authentication
projectBearer
Request body
none
Operation ID
clearScreenRebootSchedule

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
If-MatchheaderoptionalOptional positive resource revision. Omit to write the current resource; a supplied stale revision is revision_conflict.
Idempotency-KeyheaderoptionalOmit for a fresh operation. Supply and reuse a key to deduplicate retries; the CLI manages keys automatically.
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://screenrig.ai/api/screens/RESOURCE_ID/reboot-schedule'

Responses

StatusMeaningBody and headers
200Screen without a reboot schedule.Screen (application/json); headers: ETag, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/toast

Post Screen Toast

Posts one transient stage-chrome toast to the named screen. A toast is not a primitive: it does not occupy a canvas slot, has no layer, and never participates in readiness or crossfade. The durable event type is screen.toast on the existing runtime SSE stream. Runtime scan never delivers a toast after expires_at, so a persisted cursor cannot replay it later.

Level colours are player chrome and are not API fields. Text is 1 to 120 characters, line feed is the only accepted line break, and at most three lines are accepted; a Player shows a toast on one line, a line feed as a space.

Recognizable ScreenRig credential material and other control characters are rejected. duration_ms defaults to 60000 and must be between 2000 and 60000 inclusive. An exact Idempotency-Key retry returns the original expires_at for twenty-four hours. Latest-wins: there is no queue and no cancel verb. Screen messages are exempt from the 1-credit API meter.

A screen in a protected screen folder is protected_target (409).

Authentication
projectBearer
Request body
ScreenToastWrite
Operation ID
postScreenToast

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Idempotency-Keyheaderrequired

Request body fields

FieldDescription
level (required, string)Closed severity token. Player chrome chooses the fill; the API never carries a colour. Allowed: "error", "alert", "info"
text (required, string)

1 to 120 characters. Line feed is the only accepted line break. At most three lines; a Player shows the toast on one line, a line feed as a space. Other control characters and recognizable ScreenRig credential material are rejected. minLength: 1 maxLength: 120

duration_ms (optional, integer)Visible duration in milliseconds. Omitted values default to 60000. default: 60000 minimum: 2000 maximum: 60000
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Idempotency-Key: REQUEST_ID' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/toast'

Responses

StatusMeaningBody and headers
202Accepted. The toast is durable until expires_at. An exact idempotent retry returns this same expiry.ScreenToastAccepted (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

protected_target when the screen is in a protected screen folder (docs/screen-scope.md; clear the folder's protection through a review, make the change, protect it again), or the other conflicts of the operation.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/storage-forecast

Forecast Screen Storage

Pre-assignment fit dry run: answers whether one playlist would fit the named screen before it is assigned, with the same target selection as Screen.storage_forecast (the screen's last reported capacity, plan A.3 only, no transition prediction, nothing treated as local).

It writes nothing: no assignment, no screen revision, no event, and the screen's storage_forecast read model is untouched. The project bearer is authoritative; a screen or playlist of another project is not_found. fit is unknown when the screen has no storage report, or when the playlist's content references are not ready, and both byte counts are null then.

An optional playlist_revision refuses a playlist that changed since the caller read it with revision_conflict. A report older than 24 hours is stale but still forecast from, exactly like Screen.storage_forecast.

Authentication
projectBearer
Request body
ScreenStorageForecastRequest
Operation ID
forecastScreenStorage

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired

Request body fields

FieldDescription
playlist_id (required, string)minLength: 1
playlist_revision (optional, integer)Optional expected playlist revision. A different stored revision is revision_conflict and no forecast is returned. minimum: 1
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/storage-forecast'

Responses

StatusMeaningBody and headers
200Dry-run forecast. fit unknown means there is nothing to forecast from; the byte counts and received_at are null.ScreenStorageForecastDryRun (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
412revision_conflict — playlist_revision is not the playlist's current revision; no forecast is returned.Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/campaigns

Explain Screen Campaigns

Why each campaign of the project plays on this screen or not, in precedence order, with the screen's effective playlist. items and effective_playlist are the screen's state now.

With at (and optionally to), at is the same resolver the boundary sweep runs, asked about that instant, with a verdict for the takeover, every campaign and every schedule entry (won, outranked, not_started, ended, outside_hours, off), the playlist at that instant, and what the answer does not judge.

With to as well, at.timeline lists the spans between at and to in which the playlist does not change. The schedule, takeover and campaigns are read as they are now.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
explainScreenCampaigns

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
atqueryoptional

The instant to explain, either RFC 3339 with a zone (2026-03-08T09:30:00Z or 2026-03-08T01:30:00-08:00) or a time on the screen's own clock (2026-03-08T09:30, optionally with seconds). A clock time that daylight saving skips or repeats is refused with invalid_request naming at, and a repeated one names the two instants to choose from.

Defaults to now when only to is given.

toqueryoptional

End of the timeline of switches that starts at at, in the same two forms as at. Later than at, with no limit on how far; one answer lists at most 500 spans, a stretch of eight days with no change counting as one, and timeline_truncated says it stopped before reaching to.

Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://api.screenrig.ai/api/screens/RESOURCE_ID/campaigns'

Responses

StatusMeaningBody and headers
200Every campaign's standing on the screen.ScreenCampaigns (application/json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/screenshot

Get Screen Screenshot

Returns the current ready still WebP for the named screen. Optional capture_id must match that ready slot. A named capture_id that expired with no upload is screenshot_unavailable. A named capture_id replaced by a later request is resource_conflict. Image bytes are never a signed URL or object key. Range is not accepted.

Screen messages are exempt from the 1-credit API meter. The ETag is the strong SHA-256 of the stored WebP. A dashboard session response is private, no-cache, and a dashboard If-None-Match that matches the current image, checked after the screen and capture resolve in the session's project, returns 304 without opening the stored bytes.

A project bearer response stays private, no-store.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenScreenshot

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
capture_idqueryoptional
If-None-MatchheaderoptionalStrong ETag of a screenshot this route returned. Honored for a dashboard session.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/screenshot'

Responses

StatusMeaningBody and headers
200Current ready still WebP.string (image/webp); headers: Content-Type, Content-Length, ETag, X-ScreenRig-Capture-ID, X-ScreenRig-Captured-At, Cache-Control, Content-Disposition
304

Dashboard session only. The current image's ETag matches If-None-Match. No body is produced and object storage is not read. The capture headers name the current capture, which can differ from the stored response's when a later capture encoded to the same bytes.

no body; headers: ETag, Cache-Control, X-ScreenRig-Capture-ID, X-ScreenRig-Captured-At
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/screenshot

Request Screen Screenshot

Requests one still screenshot of the named active screen. Latest-wins: a new request replaces any in-flight capture_id and does not 409. The current ready slot is kept until a later upload succeeds. capture_id is an optional environment prefix, then shot_ and a random suffix. expires_at is thirty seconds after accept.

The durable event type is screen.screenshot_requested on the existing runtime SSE stream; runtime scan never delivers it after expires_at. Event details name capture_id, expires_at, max_width_divisor 2, max_height_divisor 2, format image/webp, quality 80, and max_bytes 2097152. Image bytes never appear on SSE.

Prepaid remaining credit is not a gate, and this screen-message path is exempt from the 1-credit API meter. An exact Idempotency-Key retry returns the original capture_id and expires_at for twenty-four hours.

On the dashboard lane the request may come from a Chrome or Firefox extension origin as POST /api/tab-shares may, to confirm a shared tab (GET /api/screens/{id}/screenshot/status and GET /api/screens/{id}/screenshot need no origin rule).

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
requestScreenScreenshot

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Idempotency-Keyheaderrequired
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Idempotency-Key: REQUEST_ID' 'https://screenrig.ai/api/screens/RESOURCE_ID/screenshot'

Responses

StatusMeaningBody and headers
202Accepted. The request is durable until expires_at. An exact idempotent retry returns this same capture_id and expiry.ScreenScreenshotAccepted (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/screenshot/status

Get Screen Screenshot Status

Returns the screenshot state machine for the named screen when it exists for this project. idle has no request and no ready slot. pending is the current capture_id before expires_at with no upload. ready means the last successful upload matches the current capture_id. timed_out means the current id reached expires_at with no upload.

Timeout is lazy: the first status GET or next POST after expiry records it and appends screen.screenshot_failed once with reason expired. A timed-out request does not delete an older ready slot. Screen messages are exempt from the 1-credit API meter.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenScreenshotStatus

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/screenshot/status'

Responses

StatusMeaningBody and headers
200Screenshot status for this project's screen.ScreenScreenshotStatus (application/json); headers: Cache-Control
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/live

Get Screen Live

Returns the screen's live session after lazy expiry: idle when it has none, requested while the Player has been asked to publish, publishing once the media relay holds its video, ended with ended_reason (stopped, expired, consent_denied, consent_timeout, capture_failed, connection_failed or player_stopped; an open enum) for ten minutes after it ended. publisher.connected is true only while the Player's last report, at most 45 seconds old, said it is connected; it is the Player's own word, not proof of picture. 404 feature_unavailable when the server has no media relay configured.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenLive

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/live'

Responses

StatusMeaningBody and headers
200The screen's live session.LiveSession (application/json); headers: Cache-Control
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/live

Start Screen Live

Starts live view of the named screen, or renews the one it has (docs/player-compatibility.md §6.10): sub-second video of what the screen plays, from the Player through a media relay to the dashboard. A screen has one live session, shared by every viewer.

Its lease runs duration_s from now (30 to 300, default 300) and a start or renewal sets lease_until to the later of its current end and that instant, never past max_until, five minutes after the session began. The session ends by itself at the latest then: nothing renews or restarts it, and a new session needs a new start.

It ends earlier when the lease passes with no renewal, on DELETE, or when the Player ends it; the Player stops publishing within about 20 seconds of the lease ending.

With live_id the request only renews that session: when it is not the screen's live session (it ended, or the screen started another) the answer is 409 live_unavailable naming ended_reason, and no session starts or is extended.

A new session appends the per-screen runtime command player.live_publish (details live_id, at, expires_at sixty seconds later, max_until; never delivered after expires_at); a renewal sends it again only when the Player never joined and the last command expired.

The screen must be active and online and its host hint must declare the live_view capability: 409 live_unsupported (update the Player, or use a screenshot), 409 live_unavailable (offline), screen_archived. 404 feature_unavailable when the server has no media relay configured. 201 is a new session, 200 a renewed one; both return the LiveSession with a viewer_url that opens the dashboard viewer.

State requested lasts until the Player publishes: poll GET until publisher.connected. Live view is free and exempt from the 1-credit API meter, like a screenshot.

Authentication
projectBearer OR dashboardSession
Request body
LiveStartRequest
Operation ID
startScreenLive

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired

Request body fields

FieldDescription
duration_s (optional, integer)How long the lease runs from now, in seconds. A session lasts five minutes at most, whatever the lease. default: 300 minimum: 30 maximum: 300
live_id (optional, string)

Renew this session only. When it is not the screen's live session, the answer is live_unavailable (the detail names ended_reason) and nothing starts or is extended. Without it, a start begins a session when the screen has none. pattern: "^lv_[a-z2-7]{26}$"

Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/live'

Responses

StatusMeaningBody and headers
201A new live session; the Player was asked to publish.LiveSession (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
200The screen's live session, renewed.LiveSession (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
DELETE/api/screens/{id}/live

Stop Screen Live

Ends the screen's live session (ended_reason stopped), appends player.live_stop (details live_id, at, expires_at sixty seconds later), and closes its tracks on the media relay. 204 also when the screen has no live session. A Player that misses the command stops at its next heartbeat. 404 feature_unavailable when the server has no media relay configured.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
stopScreenLive

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request DELETE --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/live'

Responses

StatusMeaningBody and headers
204Stopped, or there was nothing to stop.no body; headers: Cache-Control
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/live/viewers

Create Screen Live Viewer

Opens a viewer of the screen's live session: a new media relay session that subscribes to the Player's video, and the relay's WebRTC offer.

Apply offer with setRemoteDescription on an RTCPeerConnection built with ice_servers (short-lived credentials), create the answer, wait for ICE gathering to complete or two seconds, then PUT the answer to /api/screens/{id}/live/viewers/{viewer_id} within two minutes.

Candidates travel inside the SDP; there is no separate candidate call. 409 live_not_ready while the session is requested, 409 live_unavailable when the screen has no live session or it ended (the detail names ended_reason). 404 feature_unavailable when the server has no media relay configured.

Authentication
projectBearer OR dashboardSession
Request body
object
Operation ID
createScreenLiveViewer

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/live/viewers'

Responses

StatusMeaningBody and headers
201A viewer and the relay's offer.LiveViewer (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
PUT/api/screens/{id}/live/viewers/{viewer_id}

Answer Screen Live Viewer

Applies the viewer's WebRTC answer to the relay's offer. A viewer answers once, within two minutes of its offer; an unknown, expired, already answered or another screen's viewer_id is 404 not_found. 204 once the relay accepts the answer; media then flows from the relay to the viewer. 404 feature_unavailable when the server has no media relay configured.

Authentication
projectBearer OR dashboardSession
Request body
LiveViewerAnswer
Operation ID
answerScreenLiveViewer

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
viewer_idpathrequired

Request body fields

FieldDescription
answer (required, SessionDescription)
Request template and responses
shell · request template
curl --request PUT --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt --header 'Content-Type: application/json' --data '@request.json' 'https://screenrig.ai/api/screens/RESOURCE_ID/live/viewers/VIEWER_ID'

Responses

StatusMeaningBody and headers
204The relay accepted the answer.no body; headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
POST/api/screens/{id}/live/frames

Start Screen Live Frames

Starts JPEG frames of the screen's live session, for an agent that has HTTPS and no WebRTC: the media relay decodes the Player's published video and delivers one JPEG about every second, and GET /api/screens/{id}/live/frame returns the latest.

The session must be publishing (409 live_not_ready until then, 409 live_unavailable when there is none or it ended; start one with POST /api/screens/{id}/live).

Frames are started once per session: asking again answers the same adapter's progress, and a Player that reconnects ends its frames, so ask again. state is starting until the first frame arrives, streaming while frames arrive, and silent when the adapter is older than fifteen seconds and none has arrived in that time (last_frame_at, when present, says when frames last came).

The frames end with the session. 404 feature_unavailable when the server has no media relay or no frames origin configured. Live frames are free and exempt from the 1-credit API meter, like a screenshot. They are what the Player's encoder sent, scaled and lossy; they do not replace a screenshot as proof of layout.

Authentication
projectBearer
Request body
object
Operation ID
startScreenLiveFrames

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
Request template and responses
shell · request template
curl --request POST --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --header 'Content-Type: application/json' --data '@request.json' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/live/frames'

Responses

StatusMeaningBody and headers
202The frame adapter, and how far it has come.LiveFrames (application/json); headers: Cache-Control, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/live/frame

Get Screen Live Frame

Returns the latest JPEG frame of the screen's live session.

Without after it returns the latest frame there is; with after (the ScreenRig-Captured-At of the frame you already have) it returns the first frame captured later, waiting up to five seconds for one, so a loop that passes each answer's ScreenRig-Captured-At back as after receives every new frame once.

ScreenRig-Captured-At is when the backend received the frame.

When no new frame comes in time the answer is 409 live_not_ready with Retry-After: 1; 409 resource_conflict answers a session whose frames were not started (POST /api/screens/{id}/live/frames first, and again after the Player reconnects); 409 live_unavailable answers a session that has ended or whose adapter is silent.

Frames are relay-decoded JPEGs of the live stream, at most 1280 by 720: they show what the Player encoded and sent, not a screenshot. They end with the session (max_until at the latest). 404 feature_unavailable when the server has no media relay or no frames origin configured. Free and exempt from the 1-credit API meter.

Authentication
projectBearer
Request body
none
Operation ID
getScreenLiveFrame

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
afterqueryoptionalReturn a frame captured after this instant (RFC 3339, as in ScreenRig-Captured-At).
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' 'https://api.screenrig.ai/api/screens/RESOURCE_ID/live/frame'

Responses

StatusMeaningBody and headers
200The frame.string (image/jpeg); headers: Content-Type, Content-Length, ETag, Cache-Control, ScreenRig-Live-Id, ScreenRig-Captured-At, ScreenRig-Frame-Width, ScreenRig-Frame-Height, RateLimit-Policy, RateLimit
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
409

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
429

Stable rate_limited problem. Retry only after the authoritative Retry-After interval. Fixed-window denials also include the applicable RateLimit-Policy and RateLimit members; concurrency and byte-budget denials omit those optional disclosures.

Problem (application/problem+json); headers: Retry-After, RateLimit-Policy, RateLimit
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/live/frames

Connect Live Frames

The media relay's frame adapter connects here with a WebSocket upgrade; no client, agent or Player calls it. The token is the credential: POST /api/screens/{id}/live/frames hands it to the relay inside the adapter's endpoint and stores only its SHA-256.

Each binary message the relay sends is one protobuf Packet (field 1 sequenceNumber, field 2 timestamp, field 5 payload) whose payload is one whole JPEG of at most 2 MiB; anything else is skipped. The backend keeps the latest frame for fifteen seconds. One connection per token: a newer one replaces the older.

The connection is closed with 1000 when the live session ends, and a token of an ended session is refused with 401 before the upgrade. 404 feature_unavailable when the server has no frames origin configured.

Authentication
none
Request body
none
Operation ID
connectLiveFrames

Parameters

NameSend inRequired?Description
tokenqueryrequiredThe adapter's token, 43 characters.
Request template and responses
shell · request template
curl --request GET 'https://api.screenrig.ai/live/frames?token=TOKEN'

Responses

StatusMeaningBody and headers
101Switching Protocols to WebSocket.no body
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/health/history

Get Screen Health History

The health a screen reported over time. resolution=raw (default) returns each accepted report in time order, shaped like Screen.health without stale; resolution=hour returns one summary per UTC hour (reports, peak and average temperature, peak load and memory ratio, weakest Wi-Fi signal, whether the display was disconnected, peak crash and renderer-restart counts). from (inclusive) and to (exclusive) default to the last 24 hours; the range is at most 31 days for raw and 93 days for hour.

A page holds at most limit rows (default 100, at most 500) with next_cursor, null at the end. History is kept for the plan's event retention. Raw reports reach this view within seconds, hourly summaries within about 5 minutes. A screen of another project is not_found. Screen.health, the latest report, is unchanged.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenHealthHistory

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
formatqueryoptionaljson (default) returns the report as JSON. csv, xlsx and pdf return the same rows as a file attachment (every page of a paged report, up to 50000 rows).
fromqueryoptionalInclusive lower bound on the report time. Defaults to 24 hours before to.
toqueryoptionalExclusive upper bound on the report time. Defaults to now.
resolutionqueryoptionalraw returns each report; hour returns one summary per UTC hour.
limitqueryoptionalPage size.
cursorqueryoptionalnext_cursor of the previous page, with the same filters. Opaque.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/health/history'

Responses

StatusMeaningBody and headers
200A page of reports or hourly summaries.ScreenHealthHistory (application/json); headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/uptime

Get Screen Uptime

Daily availability of one screen over inclusive UTC days (day_to defaults to today and day_from to 29 days before it, at most 366 days). Each row holds the online and offline seconds recorded that day, availability (online over recorded time, null when nothing was recorded) and coverage (the share of the day with a recorded state).

Time with no recorded state is never counted as downtime: it lowers coverage only. The screen's current open interval is included up to now and marks its days live. Days with nothing recorded have no row. Offline is recorded after the screen has been unreachable for 60 seconds. A screen of another project is not_found.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenUptime

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
formatqueryoptionaljson (default) returns the report as JSON. csv, xlsx and pdf return the same rows as a file attachment (every page of a paged report, up to 50000 rows).
day_fromqueryoptionalFirst UTC day, inclusive. Defaults to 29 days before day_to. With day_to spans at most 366 days.
day_toqueryoptionalLast UTC day, inclusive. Defaults to today (UTC).
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/uptime'

Responses

StatusMeaningBody and headers
200Daily uptime rows, oldest first.ScreenUptime (application/json); headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/screens/{id}/presence

Get Screen Presence

The screen's online and offline transitions, newest first, from its screen.online and screen.offline events whatever the log lane stores. since (inclusive) and until (exclusive) bound the event time; until defaults to now and since to 30 days before it, at most 366 days. Transitions are kept for the plan's event retention.

A page holds at most limit transitions (default 100, at most 500) with next_cursor, null at the end; pass it back as before. An offline transition the server noticed only when the screen reconnected carries detected_on_reconnect, and its at is when the presence lease ended. Offline is recorded after the screen has been unreachable for 60 seconds.

A screen of another project is not_found.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getScreenPresence

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
idpathrequired
sincequeryoptionalInclusive lower bound on the transition event time. Defaults to 30 days before until.
untilqueryoptionalExclusive upper bound on the transition event time. Defaults to now. until - since is at most 366 days.
limitqueryoptionalPage size. A value outside 1-500 is refused with invalid_request naming limit.
beforequeryoptionalnext_cursor of the previous page, with the same since and until.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/screens/RESOURCE_ID/presence'

Responses

StatusMeaningBody and headers
200Presence transitions, newest first.ScreenPresenceHistory (application/json); headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
404

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/health/trend

Get Health Trend

The project's fleet health by UTC hour: how many screens reported, and how many of them were hot (at or above 80 °C), had a disconnected display, or were crashing (3 or more crashes in 24 hours). from (inclusive) and to (exclusive) default to the last 24 hours, at most 93 days; a page holds at most limit rows (default 100, at most 500) with next_cursor, null at the end.

Hours follow reports by up to about 5 minutes. Refused to a caller limited to screens (outside_screen_scope); GET /api/screens/{id}/health/history is the per-screen form.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getHealthTrend

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
formatqueryoptionaljson (default) returns the report as JSON. csv, xlsx and pdf return the same rows as a file attachment (every page of a paged report, up to 50000 rows).
fromqueryoptionalInclusive lower bound on the report time. Defaults to 24 hours before to.
toqueryoptionalExclusive upper bound on the report time. Defaults to now.
limitqueryoptionalPage size.
cursorqueryoptionalnext_cursor of the previous page, with the same filters. Opaque.
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/health/trend'

Responses

StatusMeaningBody and headers
200A page of hourly fleet health.HealthTrend (application/json); headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
GET/api/uptime/daily

Get Project Uptime

Daily availability of the project's screens over inclusive UTC days (defaults and range as GET /api/screens/{id}/uptime). Each row sums the online and offline seconds of the screens with a recorded state that day; coverage is the share of those screens' day with a recorded state.

Intervals count when they end, so today's row covers intervals that ended so far; the live online count is in the dashboard summary. Refused to a caller limited to screens (outside_screen_scope); GET /api/screens/{id}/uptime is the per-screen form.

Authentication
projectBearer OR dashboardSession
Request body
none
Operation ID
getProjectUptime

Parameters

NameSend inRequired?Description
ScreenRig-ProjectheaderoptionalDeprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange.
formatqueryoptionaljson (default) returns the report as JSON. csv, xlsx and pdf return the same rows as a file attachment (every page of a paged report, up to 50000 rows).
day_fromqueryoptionalFirst UTC day, inclusive. Defaults to 29 days before day_to. With day_to spans at most 366 days.
day_toqueryoptionalLast UTC day, inclusive. Defaults to today (UTC).
Request template and responses
shell · request template
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/uptime/daily'

Responses

StatusMeaningBody and headers
200Daily uptime rows, oldest first.ProjectUptime (application/json); headers: Cache-Control
400

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
401

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)
403

outside_screen_scope - the caller is limited to screens and the screen, screen folder, selector or audience the request names or reaches is outside them (docs/screen-scope.md). An id outside the scope and an id that does not exist get the same answer; errors[0].screen_scope carries the caller's scope, and the write is refused whole, never narrowed.

Problem (application/problem+json)
default

Stable RFC 9457 problem response. A 421 server_draining carries Retry-After of 1 second, a 500 not_ready or dependency_unavailable carries 5, and a 500 manifest_degraded carries 60, unless the handler set a more specific value.

Problem (application/problem+json)