Why proof-of-play matters
For DOOH networks and retail media, ad spend is released against verified delivery. Proof-of-play (PoP) shows when, where and how long each creative was displayed. To be auditor-ready, PoP must be complete, accurate and tamper-evident with a reproducible trail from device to invoice.
1) Data model
Use a compact, append-only record per creative display. The minimal fields below cover most audit requirements.
| device_id | Stable unique ID (hardware + app channel) |
| site_id | Location/store/screen grouping |
| screen_id | Physical screen within site |
| creative_id | Asset identifier (from CMS/ad server) |
| campaign_id | Optional linkage to booking/order |
| started_at | UTC ISO-8601 timestamp (s) |
| duration_s | Actual seconds on screen |
| play_mode | loop | schedule | ad-ops |
| app_version | Player version |
| fw_channel | Model/firmware cohort |
| hash | Row hash (see below) |
2) Device-side logging
- Write PoP events to a local append-only file (e.g. CSV/JSONL) with file rolling by day.
- Keep a monotonic clock source; sync via NTP, but continue logging if time jumps are detected.
- Include health events (boot, crash, version switch) for audit context.
- Persist a send queue with idempotency keys for reliable upload when back online.
// JSONL example (one line per play)
{"device_id":"TZ6-DEL-001","site_id":"DLF-MALL","screen_id":"P1","creative_id":"promo_8k","campaign_id":"SUMMER24","started_at":"2025-06-30T11:02:03Z","duration_s":30,"play_mode":"schedule","app_version":"1.7.3","fw_channel":"tizen6.5","hash":"<row_sha256>"}
3) Tamper-evidence: hashing & signing
- Row hash: SHA-256 over the canonicalised row (stable field order, trimmed, UTF-8).
- Chain hash: each row also includes SHA-256 of the previous row hash for append-only guarantees.
- File signature: sign each rolled file with the device private key (Ed25519). Upload public key during provisioning.
// canonical string for row hash
`${device_id}|${screen_id}|${creative_id}|${started_at}|${duration_s}|${app_version}`
// chain hash
row_hash = sha256(canonical)
chain_hash = sha256(prev_chain_hash + row_hash)
Why both row and chain hashes? Row hash catches field edits; chain hash makes deletions or re-ordering evident.
4) Secure transport & store-and-forward
- Upload over TLS with mutual auth (mTLS) or signed JWT per device.
- Store-and-forward: when offline, queue signed daily files; back off retries; pause uploads during playback to avoid jitter.
- Server verify: on ingest, verify file signature, chain continuity and row hashes; reject gaps.
5) Retention & privacy
- PII-free by design. Do not log personal data; use pseudonymous device/site IDs.
- Retention: raw PoP files ≥ 12 months (or per contract); aggregates ≥ 24 months.
- Access control: role-based; auditor accounts read-only with time-boxed access.
6) Reconciled reports auditors accept
Auditors expect a reproducible path from raw device logs to invoice totals. Provide both raw exports and human-readable summaries.
CSV export (per campaign)
device_id,site_id,screen_id,creative_id,started_at,duration_s,validated
TZ6-DEL-001,DLF-MALL,P1,promo_8k,2025-06-30T11:02:03Z,30,true
TZ6-DEL-002,DLF-MALL,P2,promo_8k,2025-06-30T11:02:33Z,30,true
...
Summary table
| Campaign | SUMMER24 |
| Creative | promo_8k |
| Total valid plays | 1,254,330 |
| Total seconds | 37,629,900 |
| Screens covered | 1,120 |
| Coverage window | 2025-06-01 → 2025-06-30 |
7) Audit process checklist
- Scope: share campaign IDs, sites, device cohorts and firmware channels.
- Access: create read-only auditor account; share public keys & signature policy.
- Sampling: provide raw daily files for a random device subset; show chain continuity.
- Reconciliation: run deterministic aggregation; totals must match invoice line items.
- Exceptions: document rejected/gap rows with reasons (time jump, invalid signature).
- Sign-off: final PDF + CSV exports, hash digests and a signed attestation.
FAQs & troubleshooting
Q: Device time drift breaks my reports.
A: Track both wall-clock and monotonic deltas; when NTP steps time, continue logging and mark the event — do not backdate rows.
Q: Some rows are missing after outages.
A: Use local queue + daily file roll; never delete until server confirmation; employ idempotency keys for retries.
Q: Auditor flagged altered files.
A: Validate signatures on ingest; if a file fails, quarantine and re-request from device; investigate any chain breaks.