[{"data":1,"prerenderedAt":456},["ShallowReactive",2],{"doc-\u002Fapi\u002Freports":3},{"id":4,"title":5,"body":6,"description":446,"edit":447,"extension":448,"meta":449,"navigation":450,"path":451,"seo":452,"stem":453,"vertical":447,"weight":454,"__hash__":455},"content\u002Fapi\u002Freports.md","Reports API",{"type":7,"value":8,"toc":436},"minimark",[9,13,18,29,32,97,108,112,229,232,236,270,274,299,303,306,314,321,325,328,336,349,353,421,425,432],[10,11,12],"p",{},"Reports turn a period of measurements into a signed PDF an inspector\nwill accept. There is one endpoint, three core templates, and a few\ntemplate-specific options.",[14,15,17],"h2",{"id":16},"endpoint","Endpoint",[19,20,25],"pre",{"className":21,"code":23,"language":24},[22],"language-text","POST \u002Fv1\u002Freports\n{\n  \"site_id\":  \"site_4f3c\",\n  \"template\": \"haccp_monthly\",\n  \"period\":   { \"from\": \"2026-04-01T00:00:00+02:00\", \"to\": \"2026-04-30T23:59:59+02:00\" },\n  \"language\": \"en\"\n}\n","text",[26,27,23],"code",{"__ignoreMap":28},"",[10,30,31],{},"Response is asynchronous because rendering a 30-day report can take\n30–60 s:",[19,33,37],{"className":34,"code":35,"language":36,"meta":28,"style":28},"language-json shiki shiki-themes github-dark github-dark","{\n  \"id\":    \"rpt_4f3c\",\n  \"state\": \"queued\",\n  \"poll\":  \"\u002Fv1\u002Freports\u002Frpt_4f3c\"\n}\n","json",[26,38,39,48,65,79,91],{"__ignoreMap":28},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"suv1-","{\n",[40,49,51,55,58,62],{"class":42,"line":50},2,[40,52,54],{"class":53},"s8ozJ","  \"id\"",[40,56,57],{"class":46},":    ",[40,59,61],{"class":60},"s4wv1","\"rpt_4f3c\"",[40,63,64],{"class":46},",\n",[40,66,68,71,74,77],{"class":42,"line":67},3,[40,69,70],{"class":53},"  \"state\"",[40,72,73],{"class":46},": ",[40,75,76],{"class":60},"\"queued\"",[40,78,64],{"class":46},[40,80,82,85,88],{"class":42,"line":81},4,[40,83,84],{"class":53},"  \"poll\"",[40,86,87],{"class":46},":  ",[40,89,90],{"class":60},"\"\u002Fv1\u002Freports\u002Frpt_4f3c\"\n",[40,92,94],{"class":42,"line":93},5,[40,95,96],{"class":46},"}\n",[10,98,99,100,103,104,107],{},"Poll until ",[26,101,102],{},"state = \"ready\"",", then ",[26,105,106],{},"GET \u002Fv1\u002Freports\u002Frpt_4f3c\u002Ffile"," to\ndownload the PDF.",[14,109,111],{"id":110},"templates","Templates",[113,114,115,134],"table",{},[116,117,118],"thead",{},[119,120,121,125,128,131],"tr",{},[122,123,124],"th",{},"Template",[122,126,127],{},"Vertical",[122,129,130],{},"Period typical",[122,132,133],{},"Pages",[135,136,137,154,169,185,201,215],"tbody",{},[119,138,139,145,148,151],{},[140,141,142],"td",{},[26,143,144],{},"haccp_monthly",[140,146,147],{},"HACCP",[140,149,150],{},"1 month",[140,152,153],{},"8–14",[119,155,156,161,163,166],{},[140,157,158],{},[26,159,160],{},"haccp_annual",[140,162,147],{},[140,164,165],{},"12 months",[140,167,168],{},"30+",[119,170,171,176,179,182],{},[140,172,173],{},[26,174,175],{},"legionella_quarterly",[140,177,178],{},"Legionella",[140,180,181],{},"1 quarter",[140,183,184],{},"6–10",[119,186,187,192,195,198],{},[140,188,189],{},[26,190,191],{},"server_room_uptime",[140,193,194],{},"Server room",[140,196,197],{},"any",[140,199,200],{},"4–8",[119,202,203,208,211,213],{},[140,204,205],{},[26,206,207],{},"climate_monthly",[140,209,210],{},"Climate",[140,212,150],{},[140,214,184],{},[119,216,217,222,225,227],{},[140,218,219],{},[26,220,221],{},"energy_monthly",[140,223,224],{},"Energy",[140,226,150],{},[140,228,184],{},[10,230,231],{},"Custom templates are an Enterprise-tier conversation. The built-in\ntemplates accept some options (logo upload, signature lines, additional\nnotes section), set per-site in the dashboard, not per-report.",[14,233,235],{"id":234},"period-semantics","Period semantics",[237,238,239,260,263],"ul",{},[240,241,242,245,246,250,251,245,254,256,257,259],"li",{},[26,243,244],{},"from"," is ",[247,248,249],"strong",{},"inclusive",", ",[26,252,253],{},"to",[247,255,249],{}," (we differ from the\nmeasurements endpoint here — reports render ",[26,258,253],{}," as \"end of the day\"\nby default).",[240,261,262],{},"Timezone is taken from the explicit offset in the timestamps, or from\nthe site's timezone if no offset is given.",[240,264,265,266,269],{},"Cross-DST periods are handled correctly: a report for ",[26,267,268],{},"April 2026 in Europe\u002FBratislava"," renders as 30 calendar days, regardless of the\nDST shift.",[14,271,273],{"id":272},"language","Language",[10,275,276,278,279,250,282,250,285,250,288,291,292,294,295,298],{},[26,277,272],{}," is one of ",[26,280,281],{},"en",[26,283,284],{},"sk",[26,286,287],{},"de",[26,289,290],{},"cs",". Only ",[26,293,281],{}," is currently\ncomplete; other languages render with English fallbacks where strings\nare missing. The PDF marks fallback fields with a thin grey margin\nnote ",[26,296,297],{},"[en]"," so the auditor knows.",[14,300,302],{"id":301},"embedded-charts","Embedded charts",[10,304,305],{},"The PDF includes static SVG charts (no JavaScript). For each device\nthe report renders:",[237,307,308,311],{},[240,309,310],{},"One full-period overview chart (downsampled to fit the page).",[240,312,313],{},"One zoomed chart per excursion event (a 2-h window around the\nexcursion, raw resolution).",[10,315,316,317,320],{},"The chart's ",[26,318,319],{},"OK \u002F WARN \u002F ALARM"," bands are rendered with their actual\nthreshold colours and the threshold values printed in the legend.",[14,322,324],{"id":323},"signatures","Signatures",[10,326,327],{},"The cover page includes signature blocks for:",[237,329,330,333],{},[240,331,332],{},"The operator (free-text name + date line).",[240,334,335],{},"The auditor \u002F inspector (free-text name + date line + space for a\nstamp).",[10,337,338,339,342,343,348],{},"The PDF is ",[247,340,341],{},"not"," cryptographically signed by us. The audit trail is\nthe hash-chained evidence (see ",[344,345,347],"a",{"href":346},"\u002Fsecurity\u002Faudit-trail","audit trail",");\nthe PDF cites the audit trail. If a digitally-signed PDF is required\n(rare in HACCP, expected in pharma), the workflow is to print the\nPDF, get it signed in ink, and re-scan — or use the Enterprise-tier\ndigital-signature flow.",[14,350,352],{"id":351},"errors","Errors",[113,354,355,369],{},[116,356,357],{},[119,358,359,362,366],{},[122,360,361],{},"HTTP",[122,363,364],{},[26,365,26],{},[122,367,368],{},"When",[135,370,371,384,396,408],{},[119,372,373,376,381],{},[140,374,375],{},"422",[140,377,378],{},[26,379,380],{},"period_empty",[140,382,383],{},"The period contains no measurements",[119,385,386,388,393],{},[140,387,375],{},[140,389,390],{},[26,391,392],{},"unknown_template",[140,394,395],{},"Template name not in the supported set",[119,397,398,400,405],{},[140,399,375],{},[140,401,402],{},[26,403,404],{},"period_too_long",[140,406,407],{},"> 13 months — beyond raw retention",[119,409,410,413,418],{},[140,411,412],{},"429",[140,414,415],{},[26,416,417],{},"report_rate_limit",[140,419,420],{},"4 reports \u002F min \u002F account",[14,422,424],{"id":423},"caching","Caching",[10,426,427,428,431],{},"We cache rendered PDFs for 24 h. A second request for the same\n",[26,429,430],{},"(site, template, period, language)"," returns the cached file. Cache is\ninvalidated when an event for the period changes (e.g. acknowledged\nlate) — the next request re-renders.",[433,434,435],"style",{},"html pre.shiki code .suv1-, html code.shiki .suv1-{--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .s8ozJ, html code.shiki .s8ozJ{--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .s4wv1, html code.shiki .s4wv1{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":28,"searchDepth":67,"depth":67,"links":437},[438,439,440,441,442,443,444,445],{"id":16,"depth":50,"text":17},{"id":110,"depth":50,"text":111},{"id":234,"depth":50,"text":235},{"id":272,"depth":50,"text":273},{"id":301,"depth":50,"text":302},{"id":323,"depth":50,"text":324},{"id":351,"depth":50,"text":352},{"id":423,"depth":50,"text":424},"PDF generation per vertical",null,"md",{},true,"\u002Fapi\u002Freports",{"title":5,"description":446},"api\u002Freports",295,"J68I10AbxCy9M_fra6f83csWlyacO28MEAPoCP_pVbU",1779022954234]