Monthly client reports
curl "https://api.siteqwality.com/monitors/report?month=2026-07" \ -H "Authorization: Bearer $SESSION_JWT" \ -H "X-SQ-Account: $CLIENT_ACCOUNT_ID" \ -o acme-july.htmlThe response is HTML, not JSON, styled for paper. Open it in a browser and print to PDF, and that PDF is the artifact you send. There is a print button on the page.
The header is what makes it a client’s report. Drop it and you get your own account’s.
Choosing the month
Section titled “Choosing the month”month | Result |
|---|---|
| omitted | The last complete month, which is what a monthly report normally covers |
2026-07 | That UTC calendar month |
| the current month | Allowed. The report says on its face that the month is not finished |
| a future month | 400 |
| more than 13 months ago | 400 |
Thirteen months is a data boundary rather than a policy. Per-check performance data is retained for a rolling year and the uptime rollup is rebuilt from it, so past that horizon the uptime table would render empty while the outage log kept filling in from a source that has no retention. A document that lists real outages beside a column of blanks is worse than a refusal.
What the report contains
Section titled “What the report contains”- Per-monitor uptime for the month, against the account’s monitors.
- An outage log: when each outage started, when it ended, how long it lasted.
- The month’s totals.
It also states its own boundaries, in the document, because the person receiving it will not have read this page:
-
HTTP monitors only. Heartbeat monitors and browser checks have no daily uptime figure behind them, so they are named and counted as excluded rather than silently dropped from the total.
-
Uptime is a daily rollup rebuilt at 03:00 UTC. A report for the month in progress is month-to-date. A report for a finished month pulled before 03:00 UTC on the 1st may be missing the last day, and says so.
-
The outage log is a different pipeline and is current to the minute. So the two sections can disagree slightly at a month edge. The report says that too.
Branding
Section titled “Branding”The report takes its logo, colours and title from status page branding, resolved in this order:
- The client’s own status page branding, if the client has a status page.
- Your branding, if they do not. This is the usual case for a managed client, and it is also the honest answer: the report is your deliverable under your care plan.
- Neither, in which case the report is plain and unbranded.
SiteQwality branding is never used as a fallback at any level. This page is handed to a third party, so it carries your identity or none.
A monitor paused during an outage
Section titled “A monitor paused during an outage”If a monitor was failing when it was paused, its outage is measured to its last actual check, not to now. Without that, a monitor paused mid-outage would accrue downtime forever and every future report would show the whole month as down.
This matters more than it sounds: monitors on accounts nobody signs into are paused automatically after a long enough dormancy, and those are exactly the clients whose reports you send rather than read.
Automating it
Section titled “Automating it”The endpoint is under the monitors scope family, so an M2M client with read:monitors can pull reports on a schedule. Combine it with GET /partner/accounts to generate a whole month’s worth:
# One report per client, for last month.for id in $(curl -s https://api.siteqwality.com/partner/accounts \ -H "Authorization: Bearer $SESSION_JWT" \ | jq -r '.data.clients[].account_id'); do curl -s "https://api.siteqwality.com/monitors/report" \ -H "Authorization: Bearer $SESSION_JWT" \ -H "X-SQ-Account: $id" \ -o "report-$id.html" sleep 1doneNote the two different credentials this needs in practice: listing clients requires an Admin session, while the report itself works with a session or a scoped M2M token. See roles and access.