Documentation

Reports and exports

Reports read the project's aggregates: uptime rollups, alert history, screen state and direct campaign delivery. They never scan raw events. Every report is one table that writes as JSON, CSV, XLSX or PDF, and any report can be emailed on a schedule.

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.

ReportWhat a row says
fleet_healthScreens, online now, availability, open alerts, alerts begun in the period, hot, display disconnected, crashing, and how many screens run their current content
uptimeOnline and offline hours, availability and recorded coverage
publishingScreens with current content, updating content, content that needs attention and no content
alertsAlerts open now and begun in the period, by condition
alert_logOne row per alert that began in the period: the screen, the condition, when it began and ended, and who acknowledged it
proof_of_playPlays 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).

MemberMeaning
kindfleet_health, uptime, publishing, alerts, alert_log or proof_of_play
filtersThe report's filters other than the days: group_by, folder_id, direct, tag, campaign_id, advertiser
schedulecadence daily, weekly (weekday) or monthly (day_of_month, 1 to 28), hour 0 to 23 and an IANA timezone
formatpdf, xlsx or csv, attached to the email
recipientsProject 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.

PathHolds
export.jsonThe format (screenrig.export/v1), when it was made, every section's outcome and every file with its size and SHA-256
project.json, tags.jsonThe 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.jsonCampaigns and direct campaigns
cards/, sources.json, applications.json, triggers.jsonCards with their data, data source configuration, applications and alert triggers
notifications.json, webhooks.json, alert-mutes.json, report-subscriptions.jsonNotifications, webhooks, mutes and schedules
media/files/ and media/manifest.jsonThe 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.jsonlThe project event log, one JSON event per line
log/audit.jsonl, log/audit-head.jsonThe 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.