Folder and tag rollups
fleet_health, uptime, publishing and alerts roll the fleet up by folder, screen or tag over inclusive UTC days. A folder row counts every screen in it and in every folder inside it, and the first row is the whole project. Tags are the second grouping: a screen counts in each tag it carries.
| Report | What a row says |
|---|---|
fleet_health | Screens, online now, availability, open alerts, alerts begun in the period, hot, display disconnected, crashing, and how many screens run their current content |
uptime | Online and offline hours, availability and recorded coverage |
publishing | Screens with current content, updating content, content that needs attention and no content |
alerts | Alerts open now and begun in the period, by condition |
alert_log | One row per alert that began in the period: the screen, the condition, when it began and ended, and who acknowledged it |
proof_of_play | Plays of a sponsor's or advertiser's direct campaigns per campaign, media and screen, with totals |
GET /api/reports/{kind} builds a report. from and to are UTC days (default: the last 30 days); group_by is folder (default), screen or tag; folder_id limits the report to a folder and everything inside it, and with direct=true to the folder and its child folders, or, grouped by screen, to the screens directly in it; tag keeps screens carrying that tag. A folder row carries id, parent_id and depth, so a client draws the outline from the rows. Availability is online time over recorded time, and recorded coverage says how much of the period the screens reported a state.
The dashboard's Health page lays these rollups out as the screen folders: each folder opens to its subfolders and its screens, and each screen to its Health tab.
CSV, XLSX and PDF
Every report route takes format=csv, xlsx or pdf and answers with an attachment of the same rows: the new reports, GET /api/uptime/daily, GET /api/screens/{id}/uptime, GET /api/screens/{id}/health/history, GET /api/health/trend, GET /api/alerts, GET /api/playback, GET /api/playback/plays, GET /api/playback/totals, GET /api/playback/completeness, the advertising delivery, fill and spend reports and a direct campaign's report. A paged report is written whole, up to 50,000 rows; truncated says when it holds only the first rows.
The XLSX file is one sheet with the title and period above a frozen header, numbers as numbers and the totals in bold. The PDF is a plain statement with the screenRIG name, the project it is for, the title and period, a table whose header repeats on every page, the totals and page numbers, ready to send. The CSV starts with the column labels and neutralizes a text cell that a spreadsheet would run as a formula.
screenrig reports show fleet_health --group-by folder --format pdf --output fleet-health.pdf
screenrig reports show proof_of_play --advertiser "Acme Corp" --from 2026-10-01 --to 2026-10-31 --format pdf --output acme.pdf
screenrig project uptime --format xlsx --output uptime.xlsx
screenrig alerts list --state all --format csv --output alerts.csv
Proof of play for a sponsor or an advertiser
proof_of_play totals the plays of the project's direct campaigns. A play counts when the screen reports the media completed on glass. Name one campaign with campaign_id, or every campaign of a sponsor or advertiser with advertiser (its exact name, any case). Each row is a campaign, a media file and a screen with its plays, played hours, first and last day and, when the screen carries an audience estimate, estimated impressions. The PDF is the statement to send.
Email schedules
A report subscription names a report kind and its filters, a cadence, a file format and the project members it goes to. POST /api/report-subscriptions creates one; a project has at most 50 (report_subscription_limit_reached).
| Member | Meaning |
|---|---|
kind | fleet_health, uptime, publishing, alerts, alert_log or proof_of_play |
filters | The report's filters other than the days: group_by, folder_id, direct, tag, campaign_id, advertiser |
schedule | cadence daily, weekly (weekday) or monthly (day_of_month, 1 to 28), hour 0 to 23 and an IANA timezone |
format | pdf, xlsx or csv, attached to the email |
recipients | Project members, by user_id or by the email address of the member |
Each run covers the period before it in UTC days: the day before a daily run, the seven days before a weekly run and the whole month before a monthly run, counted on the calendar of the schedule's time zone. Recipients are members of the project, checked again at every send: anyone else is refused when the subscription is written, and a member who leaves, or whose address is not verified, stops receiving it. The attachment is at most 8 MiB.
A failed run is retried after 15 minutes, 1 hour and 4 hours and then waits for the next occurrence. The subscription shows last_status (delivered or failed), last_error, the days the last run covered and next_run_at. POST /api/report-subscriptions/{id}/send sends it now for the period a run now would cover, without moving its schedule, and answers with the subscription and this send's outcome.
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_ID
screenrig reports subscriptions list
screenrig reports subscriptions send rsub_ID
The dashboard's Reports page has the same schedules under Email schedules.
Export a whole project
screenrig project export DIR writes a complete copy of the project to a directory in open formats, so a project can leave with everything it owns.
| Path | Holds |
|---|---|
export.json | The format (screenrig.export/v1), when it was made, every section's outcome and every file with its size and SHA-256 |
project.json, tags.json | The project and its tags with their screens |
screens/ | screens.json, folders.json and schedules.json (each screen's levels, takeover and display schedule) |
playlists/ | Each playlist and every revision, as JSON |
campaigns.json, advertising/direct-campaigns.json | Campaigns and direct campaigns |
cards/, sources.json, applications.json, triggers.json | Cards with their data, data source configuration, applications and alert triggers |
notifications.json, webhooks.json, alert-mutes.json, report-subscriptions.json | Notifications, webhooks, mutes and schedules |
media/files/ and media/manifest.json | The original media files, and each file's id, name, type, size and SHA-256 |
data/ | CSV for plays, playback totals, daily uptime, uptime by screen and alerts |
log/events.jsonl | The project event log, one JSON event per line |
log/audit.jsonl, log/audit-head.json | The audit log, one JSON entry per line, and its chain head |
Credentials are never in the copy: a webhook's signing secret and receiver address, a notification's chat or pager credential and a data source's secrets are left out (the file keeps the receiver's origin and the names of the secrets). A rerun is safe: JSON files are rewritten whole, a media file that is already complete is kept, and a partly downloaded one continues from the bytes it has. Each media file is checked against the SHA-256 the project holds before it is kept. --no-media skips the media files and --since DAY starts the CSV data and the event log on a day. Every request is a billed API request, and media downloads are egress.