Documentation

Reports CLI commands

Build reports and schedule them by email, read and verify the audit log, and query playback evidence: plays, totals and completeness.

Every command here runs as described in the CLI reference: global flags, JSON output, exit codes, revisions and retries.

Reports

reports show KIND builds a report (fleet_health, uptime, publishing, alerts, alert_log or proof_of_play) and, with --format csv, xlsx or pdf and --output FILE, writes it as a file; reports subscriptions emails a report to project members on a schedule; project export DIR writes project data with each section's outcome. Reports and exports describes each of them.

reports list#

List the report kinds and the filters each takes.

reports list

No parameters.

screenrig reports list

Returns data.items, each with the report kind, title, description and the filters it takes (params), and the file formats.

reports show#

Build one report as rows, or write it as a CSV, XLSX or PDF file.

reports show <kind> [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--group-by folder|screen|tag]
    [--folder-id ID [--direct]] [--tag TAG] [--campaign-id ID] [--advertiser NAME]
    [--format json|csv|xlsx|pdf] [--output FILE]
ParameterTypeRequiredDefaultNotes
<kind>stringyesnonefleet_health, uptime, publishing, alerts, alert_log or proof_of_play.
--fromstringno29 days before --toFirst UTC day, inclusive, as YYYY-MM-DD.
--tostringnotodayLast UTC day, inclusive; at most 366 days after --from.
--group-bystringnofolderWhat a row is: folder, screen or tag.
--folder-idstringnononeOnly this screen folder and everything inside it.
--directbooleannooffWith --folder-id: only the screens directly in the folder (--group-by screen), or the folder and its child folders.
--tagstringnononeOnly screens carrying this tag.
--campaign-idstringnononeproof_of_play: one direct campaign.
--advertiserstringnononeproof_of_play: the campaigns of this advertiser or sponsor, by exact name in any case.
--formatstringnojsonjson, csv, xlsx or pdf.
--outputpathno./KIND.FORMATFile to write with --format csv, xlsx or pdf. The default writes the kind with dashes, such as ./fleet-health.pdf, and adds the --to day when given, such as ./fleet-health-2026-10-28.pdf.
screenrig reports show fleet_health --group-by screen --from 2026-10-01 --to 2026-10-28
screenrig reports show proof_of_play --advertiser "Acme Corp" --format pdf --output acme-proof-of-play.pdf

JSON returns data.columns, data.rows, data.totals and data.notes; a folder report's rows carry id, parent_id and depth for the outline, and its first row is the whole project. A file answers with its path, bytes and SHA-256. A paged report is written whole, up to 50000 rows (data.truncated otherwise). proof_of_play needs a project that sells ad time on its own screens. Read only access with the reports capability is enough.

reports subscriptions#

Email a report to project members on a schedule.

reports subscriptions list
reports subscriptions show <id>
reports subscriptions create --name NAME --kind KIND --format pdf|xlsx|csv
    --recipients MEMBERS --cadence daily|weekly|monthly [--weekday DAY]
    [--day-of-month N] [--hour N] [--timezone ZONE] [--filter NAME=VALUE]
reports subscriptions update <id> [--name NAME] [--format pdf|xlsx|csv]
    [--recipients MEMBERS] [--filter NAME=VALUE] [--cadence daily|weekly|monthly]
    [--weekday DAY] [--day-of-month N] [--hour N] [--timezone ZONE]
    [--pause | --resume] [--expect-rev REVISION]
reports subscriptions delete <id>
reports subscriptions send <id>
ParameterTypeRequiredDefaultNotes
<id>stringyesnoneThe rsub_ ID of a subscription, from reports subscriptions list.
--namestringon createnoneAt most 100 characters.
--kindstringon createnoneA reports show kind: fleet_health, uptime, publishing, alerts, alert_log or proof_of_play. It never changes.
--formatstringon createnoneThe attachment: pdf, xlsx or csv.
--recipientsstringon createnoneUp to 25 project members, comma-separated: a user ID, a member's email address or owner. update replaces the recipients.
--filterstringnononeA report filter as NAME=VALUE, such as group_by=screen, folder_id=sfd_ID, tag=Lobby or advertiser=Acme; repeatable. update replaces the filters.
--cadencestringon createnonedaily, weekly or monthly.
--weekdaystringnomondayWeekly runs: monday to sunday.
--day-of-monthintegerno1Monthly runs: the day, 1 to 28.
--hourintegerno0Hour of the day in the time zone, 0 to 23.
--timezonestringnoUTCAn IANA time zone such as America/Los_Angeles.
--pausebooleannooffupdate only: send nothing until resumed. Not with --resume.
--resumebooleannooffupdate only: send again from the next occurrence.
--expect-revintegernononeupdate only: fail unless the subscription is at this revision.
screenrig reports subscriptions create --name "Monday fleet health" --kind fleet_health --cadence weekly --weekday monday --hour 7 --timezone America/Los_Angeles --format pdf --recipients ann@example.com,usr_01EXAMPLEPERSON0000
screenrig reports subscriptions update rsub_01EXAMPLESUB0000000000 --pause

Each run covers the period before it in UTC days: yesterday, the seven days before, or last month. Recipients must be members of the project, and a member who leaves stops receiving the report. update needs at least one change. send mails the report now for the period a run now would cover, without moving the schedule, and answers with the subscription including this send's last_status and last_error. A failed run is retried and shows as last_status failed with last_error; a PDF or XLSX attachment over 8 MiB is not mailed. An organization has at most 50 subscriptions across its projects. Reading needs the project capability and Read only access; creating, changing, deleting and sending need Manage access.

Audit log

audit list|show|head|verify|export reads the project's audit log: audit list searches the configuration changes by actor, source, resource, action and field, audit show prints one entry with each changed field's before and after, audit head prints the chain head to keep as an anchor, audit verify recomputes the chain (optionally against an anchor) and exits 13 when it does not verify, and audit export writes the filtered log as a CSV, XLSX or PDF file. Audit log describes each of them.

audit list#

List audit entries, newest first.

audit list [--actor ID] [--actor-kind KIND] [--source SOURCE] [--resource-type TYPE]
    [--resource-id ID] [--action CODE] [--field POINTER] [--since TIME] [--until TIME]
    [--limit N] [--after CURSOR]
ParameterTypeRequiredDefaultNotes
--actorstringnononeOnly changes made by this person, agent or service client, by its ID.
--actor-kindstringnononeperson, agent, service_client, staff or system.
--sourcestringnononeThe surface a change came through: dashboard, api, cli, device, webhook or system.
--resource-typestringnononeOnly changes to this kind of resource, such as screen, playlist, webhook or member.
--resource-idstringnononeOnly changes to this resource.
--actionstringnononeAn action code such as screen.update, or a prefix ending in * such as playlist.*.
--fieldstringnononeOnly changes that touched this member or one below it, as a JSON Pointer such as /label.
--sincestringnononeOnly changes at or after this RFC 3339 instant, such as 2026-10-01T00:00:00Z.
--untilstringnononeOnly changes before this RFC 3339 instant.
--limitintegerno50Entries per page, 1 to 200.
--afterstringnononeThe data.next_cursor of the previous page.
screenrig audit list --resource-type screen --resource-id scr_01EXAMPLESCREEN00000000
screenrig audit list --action 'playlist.*' --source cli --limit 20

Returns data.items newest first, each with actor (kind, id, name), source, action, resource (type, id, name) and changes, each a path (a JSON Pointer into the resource), before and after; a credential reads (redacted) on both sides. seq and hash appear once an entry is chained, within seconds. data.next_cursor is null on the last page. Read only access with the project capability is enough.

audit show#

Show one audit entry with every changed field's before and after.

audit show <id>
ParameterTypeRequiredDefaultNotes
<id>stringyesnoneThe aud_ ID of an entry, from audit list.
screenrig audit show aud_01EXAMPLEENTRY0000000000

Returns the entry with each changed field's path, before and after, who made the change and through which surface, and its place in the chain once chained.

audit head#

Show the audit chain head to keep as an anchor.

audit head

No parameters.

screenrig audit head

Prints the last chained entry as SEQ:HASH, the retention floor the chain starts from and how many entries are waiting to be chained. Keep the head: audit verify --anchor SEQ:HASH later proves that history was not rewritten or truncated.

audit verify#

Recompute the audit hash chain and report anything that does not match.

audit verify [--from-seq N] [--limit N] [--anchor SEQ:HASH]
ParameterTypeRequiredDefaultNotes
--from-seqintegernooldest kept entryFirst chain position to check.
--limitintegerno5000Entries to check in this call, at most 5000.
--anchorstringnononeA chain head SEQ:HASH you kept: also proves the history up to it is unchanged.
screenrig audit verify --anchor 128:3f2c0b6e9a4d81c7f5e0a2b4c6d8e0f1a3b5c7d9e1f30415263748596a7b8c9d

Reports hash_mismatch, prev_mismatch, gap, head_mismatch, anchor_mismatch or floor_mismatch per entry in data.problems. Exits 13 with data.ok false when the chain does not verify; data.next_seq continues a longer chain.

audit export#

Write the filtered audit log as a CSV, XLSX or PDF file.

audit export --format csv|xlsx|pdf [--output FILE]
    [--actor ID] [--actor-kind KIND] [--source SOURCE] [--resource-type TYPE]
    [--resource-id ID] [--action CODE] [--field POINTER] [--since TIME] [--until TIME]
ParameterTypeRequiredDefaultNotes
--formatstringyesnonecsv, xlsx or pdf.
--outputpathno./audit-log.FORMATFile to write. With --until the default adds that day, such as ./audit-log-2026-10-01.csv.
--actor, --actor-kind, --source, --resource-type, --resource-id, --action, --field, --since, --untilstringnononeThe filters of audit list. Without --since the file covers the last 30 days.
screenrig audit export --format csv --output audit.csv
screenrig audit export --format pdf --resource-type playlist --output playlist-changes.pdf

Writes one row per changed field, oldest first, up to 50000 rows (data.truncated otherwise), with the chain head and retention floor in the file, and answers with its path, bytes and SHA-256.

Playback

Playback evidence comes in four shapes. playback plays reads one row per visible start of an image, video or application on a screen, oldest first by received_at: proof of play for a report or an advertiser. playback list reads daily totals, one row per screen, media object, and UTC day. playback totals reads play counts per UTC day, or ranks the busiest screens or media. playback completeness reads how many of the plays the Players numbered reached screenRIG, and where plays went missing.

Every playback command takes --format json|csv|xlsx|pdf and --output FILE, and the dashboard exports the same files. json, the default, is the command envelope and refuses --output; the other formats write a file. playback plays and playback list stream their own CSV, and --output - sends it to stdout instead of the envelope. Every other file is rendered on the server and saved to a file path. An xlsx or pdf holds at most 50,000 rows for playback plays and at most 200 for playback list. Each command names its default file.

Plays are kept for the plan's event retention, at least 30 days.

Problem codeExitMeaning
invalid_request8A plays range longer than 31 days, a daily range past the command's limit, or a malformed filter. The CLI refuses most of these before sending anything (exit 2).
rate_limited7The playback export budget of 30 requests a minute per organization is spent. Wait for retry_after_seconds.

Agent requests: each JSON page is one agent request, so --all makes one request per page. A CSV export is one request for its whole range. Every plays request (a JSON page, CSV, XLSX or PDF) and every playback list CSV export also spends the playback export budget. playback totals and playback completeness are one agent request each and spend none of that budget.

playback plays#

Read per-play records, one row per visible start.

playback plays [--from TIME] [--to TIME] [--screen-id ID] [--media-id ID] [--tag TAG] [--cursor CURSOR] [--limit N] [--all]
playback plays --format csv|xlsx|pdf [--output FILE] [--from TIME] [--to TIME] [--screen-id ID] [--media-id ID] [--tag TAG]
ParameterTypeRequiredDefaultNotes
--from TIMEstringno24 hours before --toInclusive bound on received_at: an RFC 3339 instant with seconds and an offset, now, or an age such as 7d, 12h, or 30m.
--to TIMEstringnonowExclusive bound, in the same forms. The range is at most 31 days.
--screen-id IDstringnoevery screenOne scr_ screen.
--media-id IDstringnoevery objectOne med_ media object.
--tag TAGstringnoevery screenA tag the screen carried when the play was received: 1 to 32 letters or digits.
--cursor CURSORstringnothe start of the rangeThe next_cursor of the previous page (pc_…), with the same filters.
--limit Nintegerno200Rows per JSON page, 1 to 1000. JSON only: --format csv refuses it.
--allbooleannooffFollow the cursor to the end of the range, 1000 rows per page unless --limit says otherwise, for at most 50 pages. JSON only: --format csv refuses it.
--format FORMATstringnojsonjson, csv, xlsx or pdf. csv streams the whole range; xlsx and pdf hold its first 50,000 rows.
--output FILEpathno./playback-plays.csv, ./plays.xlsx or ./plays.pdfThe file to write; it needs a file format. With --format csv, - writes the CSV to stdout instead of the envelope.
screenrig playback plays --from 7d --tag Lobby --all
screenrig playback plays --format csv --from 2026-09-01T00:00:00Z --to 2026-10-01T00:00:00Z --output september-plays.csv
screenrig playback plays --format xlsx --from 7d --tag Lobby --output lobby-plays.xlsx

The CLI normalizes both bounds to UTC and sends them on every request; data.from and data.to echo them. The newest 5 seconds are held back until they settle, so a play appears about 5 seconds after it is received, and data.to reports that effective end. An application play carries release_id and an empty media_id. JSON returns one page in data.items with data.next_cursor, and data.next.argv is the exact command for the next page. --all stops early, with data.next and a warning, at the page cap (playback_plays_truncated) or when the export budget is spent (playback_export_rate_limited), rather than spending requests into a refusal.

The CSV is RFC 4180 with the fixed header row screen_id,playlist_id,page_id,primitive_id,media_id,primitive,started_at,received_at,manifest_revision,playlist_revision, times in RFC 3339 UTC. primitive_id and started_at are empty unless the Player reported them. A cell that begins with =, +, -, @, tab, or carriage return carries a leading ' so spreadsheets do not evaluate it. The CLI writes through a private temporary file in the same directory and replaces an existing file only after the stream ends cleanly. --timeout is the no-progress limit for the stream, 60000 ms without a byte by default, not a limit on its total duration. The envelope reports path, bytes, rows, sha256, content_type, from, to and last_received_at; the CSV never enters the envelope. With --output - the CSV goes to stdout and no envelope is printed.

If a stream fails partway, the command exits non-zero and never writes the target file. The complete rows already received stay in FILE.partial (FILE.partial-2 and so on when that exists), and error.next exports the rest of the range from the last received_at into an unused FILE-rest.csv. Rows received at that exact instant appear in both, so drop the repeats when joining them. With --output - the incomplete CSV stays on stdout, and the error and the next command go to stderr.

xlsx and pdf are rendered on the server and saved the same way, through a private temporary file. The envelope reports path, bytes, sha256, content_type and format, and the file holds the first 50,000 rows of the range.

playback list#

Read daily playback totals for this project, newest days first.

playback list [--screen-id ID] [--media-id ID] [--day YYYY-MM-DD | --day-from YYYY-MM-DD --day-to YYYY-MM-DD]
              [--format json|csv|xlsx|pdf] [--output FILE]
ParameterTypeRequiredDefaultNotes
--screen-id IDstringnoevery screenMust start with scr_.
--media-id IDstringnoevery objectMust start with med_.
--day YYYY-MM-DDstringnoevery dayOne UTC calendar day. Not with --day-from or --day-to.
--day-from YYYY-MM-DDstringnononeFirst day of an inclusive UTC day range. With --day-to the range is at most 366 days. A CSV defaults it to 30 days before --day-to. Not with --day.
--day-to YYYY-MM-DDstringnononeLast day of that range. A CSV defaults it to today. Not with --day.
--format FORMATstringnojsonjson, csv, xlsx or pdf. csv streams every matching row, with no range the 31 days up to today. xlsx and pdf hold the same rows as the JSON list.
--output FILEpathno./playback-aggregates.csv, ./play-aggregates.xlsx or ./play-aggregates.pdfThe file to write; it needs a file format. With --format csv, - writes the CSV to stdout instead of the envelope.
screenrig playback list --screen-id scr_01EXAMPLESCREEN00000000 --day 2026-08-14
screenrig playback list --format csv --day-from 2026-09-01 --day-to 2026-09-30
screenrig playback list --format pdf --day-from 2026-09-01 --day-to 2026-09-30 --output september.pdf

One row per screen, media object, and UTC day. The filters select the caller's own rows. JSON returns at most 200 rows in data.items, newest day first; the daily totals refresh about every 10 minutes, and playback plays shows newer starts. The CSV header row is screen_id,media_id,filename,primitive,day,play_count,last_page_id,last_manifest_revision,first_started_at,last_started_at. The CSV is one request written like a plays CSV, and its envelope reports path, bytes, rows, sha256 and content_type; an xlsx or pdf envelope reports path, bytes, sha256, content_type and format. A failed daily export keeps nothing; rerun it.

playback totals#

Read play counts per UTC day, or rank the busiest screens or media.

playback totals [--by day|screen|media|screen_day] [--day-from YYYY-MM-DD] [--day-to YYYY-MM-DD]
                [--screen-id ID | --media-id ID] [--top N] [--format json|csv|xlsx|pdf] [--output FILE]
ParameterTypeRequiredDefaultNotes
--by GROUPINGstringnodayday answers one row per UTC day. screen or media ranks the busiest. screen_day answers the day series of the top screens.
--day-from YYYY-MM-DDstringno29 days before --day-toFirst UTC day, inclusive.
--day-to YYYY-MM-DDstringnotodayLast UTC day, inclusive.
--screen-id IDstringnoevery screenWith --by day, count only this screen. Not with --media-id.
--media-id IDstringnoevery objectWith --by day, count only this media object. Not with --screen-id.
--top Nintegerno10Rows of a ranking, 1 to 100; 1 to 10 with --by screen_day. Requires --by; it does not apply to --by day.
--format FORMATstringnojsonjson, csv, xlsx or pdf. The other three write the same rows as a file.
--output FILEpathno./play-totals.csv, ./play-totals.xlsx or ./play-totals.pdfThe file to write with --format csv, xlsx or pdf. A file path only: - is refused.
screenrig playback totals
screenrig playback totals --day-from 2026-09-01 --day-to 2026-09-30 --screen-id scr_01EXAMPLESCREEN00000000
screenrig playback totals --by screen --top 5
screenrig playback totals --by media --day-from 2026-09-01 --day-to 2026-09-30
screenrig playback totals --by screen_day --top 3
screenrig playback totals --by screen --top 10 --format xlsx --output busiest-screens.xlsx

Counts come from the daily rollups, which follow ingestion by up to about 21 minutes; playback plays shows newer starts. day answers data.days, screen and media answer data.screens and data.media, and screen_day answers data.screen_days. A day series spans at most 366 days (92 with --screen-id or --media-id) and a ranking at most 92. data.truncated is true when a ranking over a window too large for one read kept only the best keys of each slice. A file format writes the server's file to --output, and its envelope reports path, bytes, sha256, content_type and format.

playback completeness#

Read how many of the plays the Players numbered reached screenRIG per UTC day, and the gaps where plays went missing.

playback completeness [--day-from YYYY-MM-DD] [--day-to YYYY-MM-DD] [--screen-id ID] [--limit N]
                      [--format json|csv|xlsx|pdf] [--output FILE]
ParameterTypeRequiredDefaultNotes
--day-from YYYY-MM-DDstringno29 days before --day-toFirst UTC day, inclusive. The window spans at most 92 days.
--day-to YYYY-MM-DDstringnotodayLast UTC day, inclusive.
--screen-id IDstringnoevery screenOnly this screen. Must start with scr_.
--limit Nintegerno100Gaps to list, newest first, 1 to 500.
--format FORMATstringnojsonjson, csv, xlsx or pdf. The other three write the same rows as a file.
--output FILEpathno./play-completeness.csv, ./play-completeness.xlsx or ./play-completeness.pdfThe file to write with --format csv, xlsx or pdf. A file path only: - is refused.
screenrig playback completeness
screenrig playback completeness --day-from 2026-09-01 --day-to 2026-09-30
screenrig playback completeness --screen-id scr_01EXAMPLESCREEN00000000 --limit 20
screenrig playback completeness --format pdf --output completeness.pdf

Each media start carries a number, so a play a screen made and never delivered, such as one made offline past its 24-hour report queue, leaves a gap. data.completeness is data.measured_plays over data.measured_plays plus data.missing_plays for the window, from 0 to 1, and null when neither was measured: plays without numbers, from Players that do not number their plays or before they did, are not measured. data.days gives the same three figures for each UTC day that has any, oldest first, with a gap counted on the day of the play after it. data.gaps lists each gap newest first with screen_id, day, from and to (the start times of the plays on either side) and missing_plays; --limit caps it, and data.truncated is true when more exist. A switched-off screen makes no plays and leaves no gap. The rollup refreshes every 10 minutes. One metered API request; the playback export budget does not apply. A file format writes the server's file to --output, and its envelope reports path, bytes, sha256, content_type and format.

Other command groups