OpenAPI YAMLOpenAPI JSONproblems YAMLAPI overview
This group has 4 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.
Playback aggregates
List Playback Aggregates
Daily playback aggregates.
JSON returns at most 200 rows and is not rate limited. format=csv (or Accept text/csv without application/json) streams every matching row inside day_from to day_to (inclusive UTC days; defaults day_to today and day_from 30 days earlier; at most 366 days, else invalid_request) as CSV with a fixed header row (PlaybackAggregateCsv); only the CSV form spends the playback-export-org (30 per minute) and playback-export-ip (60 per minute) budgets.
Either form is one metered API request. Responses carry Vary Accept. A caller limited to screens (docs/screen-scope.md) must send screen_id and it must be a screen inside its scope (outside_screen_scope otherwise); the CSV forms follow the same rule.
Parameters
| Name | Send in | Required? | Description |
|---|---|---|---|
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| screen_id | query | optional | |
| media_id | query | optional | |
| day | query | optional | UTC calendar day of the aggregate. |
| day_from | query | optional | First UTC day, inclusive. Excludes day. With day_to spans at most 366 days. CSV defaults it to 30 days before day_to. |
| day_to | query | optional | Last UTC day, inclusive. Excludes day. CSV defaults it to today (UTC). |
| format | query | optional | json (default), csv, xlsx or pdf. Omitted, an Accept header naming text/csv but not application/json selects csv. xlsx and pdf write the first 50000 rows of the same list. |
Request template and responses
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/playback'Responses
| Status | Meaning | Body and headers |
|---|---|---|
| 200 | Daily playback aggregates for the calling project, images and videos alike. One row per screen, media, and UTC day. Newest days first. Identifiers filter the caller's own rows and are never a cross-project lookup. | PlaybackAggregateList (application/json), PlaybackAggregateCsv (text/csv); headers: Vary, 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) |
| 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) |
List Playback Plays
Per-play records: one row per accepted playback.media_started (or legacy playback.video_started) and one row per accepted playback.application_started (release_id set, media fields empty) of the calling project, oldest first by received_at, ties by insertion. from (inclusive) and to (exclusive) bound received_at; to defaults to now, from to 24 hours before to, and the range is at most 31 days (invalid_request otherwise).
The newest 5 seconds are not returned yet: the effective to is at most now minus 5 seconds (settle lag), so a live tail never skips a row that commits behind its cursor. screen_id, media_id, playlist_id (the playlist the start was shown from), and tag (a screen tag the screen carried when the play was received) filter.
A playlist_id page may hold fewer than limit rows, even none, with a next_cursor when a long stretch of plays of other playlists was scanned; null still ends the range.
JSON is a page of at most limit rows (default 200, at most 1000) with next_cursor, null at the end of the range; pass it back as cursor with the same filters. order=desc (or before) pages newest first within the same range: next_cursor is then the cursor of the oldest returned row, null at the start of the range, and is passed back as before (exclusive) with the same filters; order=asc with before is refused with invalid_request naming order, and cursor with a newest-first page naming cursor.
A newest-first page may hold fewer than limit rows, even none, with a next_cursor; null still ends it.
A later page never skips a row that existed when the earlier page was read and does not repeat one, except that a start the Player re-sent after an unacknowledged report (the same play_id, received a moment later) can appear again on a later page; the CSV stream lists it once. format=csv (or Accept text/csv without application/json) streams every play from cursor to the end of the range as CSV (PlaybackPlayCsv), newest first below before with order=desc; limit is refused with CSV.
Metering is per request: every JSON page costs one API request credit, while one CSV stream of the whole range costs one. Every plays request (page or stream) spends the playback-export-org (30 per minute) and playback-export-ip (60 per minute) budgets.
A stream bounds each write (15 seconds) and ends when the client disconnects; if it fails after the 200 header the connection is aborted, so an export that reads to a clean end is complete. Responses carry Vary Accept. Plays are kept for the plan's event retention (30 days is the shipped floor; plan-based retention uses the plan's own 7- or 90-day window).
A caller limited to screens (docs/screen-scope.md) must send screen_id and it must be a screen inside its scope (outside_screen_scope otherwise); the CSV forms follow the same rule.
Parameters
| Name | Send in | Required? | Description |
|---|---|---|---|
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| from | query | optional | Inclusive lower bound on received_at. Defaults to 24 hours before to. |
| to | query | optional | Exclusive upper bound on received_at. Defaults to now. to - from is at most 31 days. |
| screen_id | query | optional | |
| media_id | query | optional | |
| playlist_id | query | optional | Only plays shown from this playlist. |
| tag | query | optional | A screen tag the screen carried when the play was received. |
| cursor | query | optional | next_cursor of the previous page, with the same filters. Opaque. |
| order | query | optional | asc pages oldest first with cursor; desc pages newest first with before. before implies desc; order=asc with before is refused. |
| before | query | optional | Pages newest first, strictly older than this position: the next_cursor of a newest-first page, with the same filters. Opaque. |
| limit | query | optional | JSON page size. Refused with CSV. |
| format | query | optional | json (default), csv, xlsx or pdf. Omitted, an Accept header naming text/csv but not application/json selects csv. xlsx and pdf write the first 50000 rows of the same list. |
Request template and responses
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/playback/plays'Responses
| Status | Meaning | Body and headers |
|---|---|---|
| 200 | A page of plays, or the CSV stream. | PlaybackPlayList (application/json), PlaybackPlayCsv (text/csv); headers: Cache-Control, Vary, 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) |
| 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 Playback Totals
Play totals of the calling project over inclusive UTC days, read from the daily rollups: by=day returns one row per day with plays (screen_id or media_id narrows it to one screen or media), by=screen and by=media rank the busiest screens or media (top, at most 100), and by=screen_day returns the day series of the top screens (top at most 10). day_to defaults to today (UTC) and day_from to 29 days before it.
A day series spans at most 366 days (92 when narrowed to a screen or media); a ranking at most 92. Counts include every start the project has recorded, including those stored before play rollups existed.
Rollups follow ingestion by up to about 21 minutes. truncated is true when a ranking was built from slices of a window too large for one read: it covers the best keys of each slice. Not rate limited. One metered API request.
A caller limited to screens (docs/screen-scope.md) must send screen_id and it must be a screen inside its scope (outside_screen_scope otherwise); the CSV forms follow the same rule.
Parameters
| Name | Send in | Required? | Description |
|---|---|---|---|
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| format | query | optional | json (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). |
| by | query | optional | day: plays per day; screen, media: the busiest keys; screen_day: the day series of the top screens. |
| day_from | query | optional | First UTC day, inclusive. Defaults to 29 days before day_to. A day series spans at most 366 days (92 when narrowed to a screen or media), a ranking at most 92. |
| day_to | query | optional | Last UTC day, inclusive. Defaults to today (UTC). |
| screen_id | query | optional | |
| media_id | query | optional | |
| top | query | optional | How many screens or media a ranking returns (at most 10 for by=screen_day). Refused with by=day. |
Request template and responses
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/playback/totals'Responses
| Status | Meaning | Body and headers |
|---|---|---|
| 200 | Totals of the requested grouping. | PlaybackTotals (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 Playback Completeness
How many of the plays the screens made reached the backend, and where the missing ones were. Players number their media starts, so a start that never arrived leaves a hole in the numbering, for example when a screen stays offline past its 24 hour report queue or the queue drops reports.
Over the inclusive UTC days day_from to day_to (day_to defaults to today, UTC, and day_from to 29 days before it; the window spans at most 92 days) the answer holds measured_plays, the numbered plays that arrived; missing_plays, the numbers the Players skipped; completeness, measured_plays over their sum, null when both are 0; days, the same three figures for each day that has any, oldest first, a hole counted on the UTC day of the play after it; and gaps, the holes newest first, each with its screen_id, its day, from and to (the start times of the plays on either side of it) and missing_plays. screen_id narrows days and gaps to one screen; limit (default 100, at most 500) caps gaps, and truncated is true when more exist.
A switched-off screen makes no plays and leaves no gap. Plays without a number (older Players, starts stored before play numbers) are not measured: they are in play_count of GET /api/playback/totals and in none of these figures. Not rate limited. One metered API request.
A caller limited to screens (docs/screen-scope.md) must send screen_id and it must be a screen inside its scope (outside_screen_scope otherwise); the CSV forms follow the same rule.
Parameters
| Name | Send in | Required? | Description |
|---|---|---|---|
| ScreenRig-Project | header | optional | Deprecated for one release. Must be consistent with the JWT projects grants; adds Deprecation and Warning headers. No token exchange. |
| format | query | optional | json (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_from | query | optional | First UTC day, inclusive. Defaults to 29 days before day_to. With day_to spans at most 92 days. |
| day_to | query | optional | Last UTC day, inclusive. Defaults to today (UTC). |
| screen_id | query | optional | |
| limit | query | optional | The most gaps to list, newest first. |
Request template and responses
curl --request GET --header 'Authorization: Bearer [SCREENRIG_TOKEN]' --cookie cookies.txt --cookie-jar cookies.txt 'https://screenrig.ai/api/playback/completeness'Responses
| Status | Meaning | Body and headers |
|---|---|---|
| 200 | The completeness of the window and its gaps. | PlaybackCompleteness (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) |