Reports API
PDF generation per vertical
Reports turn a period of measurements into a signed PDF an inspector will accept. There is one endpoint, three core templates, and a few template-specific options.
Endpoint
POST /v1/reports
{
"site_id": "site_4f3c",
"template": "haccp_monthly",
"period": { "from": "2026-04-01T00:00:00+02:00", "to": "2026-04-30T23:59:59+02:00" },
"language": "en"
}
Response is asynchronous because rendering a 30-day report can take 30–60 s:
{
"id": "rpt_4f3c",
"state": "queued",
"poll": "/v1/reports/rpt_4f3c"
}
Poll until state = "ready", then GET /v1/reports/rpt_4f3c/file to
download the PDF.
Templates
| Template | Vertical | Period typical | Pages |
|---|---|---|---|
haccp_monthly | HACCP | 1 month | 8–14 |
haccp_annual | HACCP | 12 months | 30+ |
legionella_quarterly | Legionella | 1 quarter | 6–10 |
server_room_uptime | Server room | any | 4–8 |
climate_monthly | Climate | 1 month | 6–10 |
energy_monthly | Energy | 1 month | 6–10 |
Custom templates are an Enterprise-tier conversation. The built-in templates accept some options (logo upload, signature lines, additional notes section), set per-site in the dashboard, not per-report.
Period semantics
fromis inclusive,tois inclusive (we differ from the measurements endpoint here — reports rendertoas "end of the day" by default).- Timezone is taken from the explicit offset in the timestamps, or from the site's timezone if no offset is given.
- Cross-DST periods are handled correctly: a report for
April 2026 in Europe/Bratislavarenders as 30 calendar days, regardless of the DST shift.
Language
language is one of en, sk, de, cs. Only en is currently
complete; other languages render with English fallbacks where strings
are missing. The PDF marks fallback fields with a thin grey margin
note [en] so the auditor knows.
Embedded charts
The PDF includes static SVG charts (no JavaScript). For each device the report renders:
- One full-period overview chart (downsampled to fit the page).
- One zoomed chart per excursion event (a 2-h window around the excursion, raw resolution).
The chart's OK / WARN / ALARM bands are rendered with their actual
threshold colours and the threshold values printed in the legend.
Signatures
The cover page includes signature blocks for:
- The operator (free-text name + date line).
- The auditor / inspector (free-text name + date line + space for a stamp).
The PDF is not cryptographically signed by us. The audit trail is the hash-chained evidence (see audit trail); the PDF cites the audit trail. If a digitally-signed PDF is required (rare in HACCP, expected in pharma), the workflow is to print the PDF, get it signed in ink, and re-scan — or use the Enterprise-tier digital-signature flow.
Errors
| HTTP | code | When |
|---|---|---|
| 422 | period_empty | The period contains no measurements |
| 422 | unknown_template | Template name not in the supported set |
| 422 | period_too_long | > 13 months — beyond raw retention |
| 429 | report_rate_limit | 4 reports / min / account |
Caching
We cache rendered PDFs for 24 h. A second request for the same
(site, template, period, language) returns the cached file. Cache is
invalidated when an event for the period changes (e.g. acknowledged
late) — the next request re-renders.