List PDF reports
GET
/sites/{siteId}/reports- Scope
sites:read
Latest PDF reports and weekly emails about the website Site summaries of this website and the monthly client reports of the client it belongs to, newest first, plus the weekly emails that cover it (weeklyEmails: name, on or off, next send, how many people get it). link opens the report in the app for a signed-in member.
Parameters
| Name | In | Details |
|---|---|---|
siteIdRequired | path | stringWebsite id, from GET /sites. |
limit | query | integerdefault 5, min 1, max 20Reports to return, 1 to 20. |
Response
200 · application/json
| Field | Details |
|---|---|
weeklyEmails | list of object · required |
weeklyEmails[].id | string · required; Weekly email id |
weeklyEmails[].name | string · required; Name of the weekly email |
weeklyEmails[].scope | portfolio | client | site · required; What it covers: every website, one client, or chosen websites |
weeklyEmails[].enabled | true or false · required; Switched on |
weeklyEmails[].recipients | integer · required; How many people receive it (their addresses are not listed) |
weeklyEmails[].nextSendAt | date (YYYY-MM-DD) or null · required; Day of the next send (Monday, in the workspace time zone); null when it is off or weekly emails are paused |
weeklyEmails[].lastSentAt | string or null · required; When it last went out; null when never |
weeklyEmails[].link | address (URL) · required; Reports screen in the app |
reports | list of object · required |
reports[].id | string · required; Report id |
reports[].kind | site_summary | client_summary · required; A website summary, or a monthly client report |
reports[].format | pdf | csv · required; File type |
reports[].title | string · required; Report title |
reports[].scope | string · required; What it covers |
reports[].period | object or null · required; Days covered; null when not tied to a period |
reports[].period.from | date (YYYY-MM-DD) · required |
reports[].period.to | date (YYYY-MM-DD) · required |
reports[].period.label | string · required; Readable period |
reports[].createdAt | string · required |
reports[].link | address (URL) · required; Opens the PDF in the app (sign-in needed) |
note | string · required; What is listed |
link | address (URL) · required; Reports screen in the app |
Errors
| Status | Meaning |
|---|---|
400 | Bad request. Codes: bad_limit. |
401 | Missing, unknown or revoked key. Codes: missing_key, invalid_key. |
403 | The key lacks the scope, covers another website, or its owner lost access. Codes: missing_scope, other_site, owner_left, no_owner, forbidden. |
404 | Not found. Codes: not_found. |
429 | Too many requests this hour for this key. Codes: rate_limited. |
Example request
curl \
-H "Authorization: Bearer mr_ws_…" \
"https://app.monoranks.com/api/v1/sites/SITE_ID/reports"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/reports", {
headers: { Authorization: "Bearer mr_ws_…" },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();import requests
res = requests.get(
"https://app.monoranks.com/api/v1/sites/SITE_ID/reports",
headers={"Authorization": "Bearer mr_ws_…"},
)
res.raise_for_status()
data = res.json()<?php
$ch = curl_init("https://app.monoranks.com/api/v1/sites/SITE_ID/reports");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer mr_ws_…"],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);import axios from "axios";
const { data } = await axios.get("https://app.monoranks.com/api/v1/sites/SITE_ID/reports", { headers: { Authorization: "Bearer mr_ws_…" } });Example response
{
"weeklyEmails": [
{
"id": "1c3e5a7c-9e1a-4c3e-8a5c-9e1a3c5e7a9c",
"name": "Acme Bikes",
"scope": "site",
"enabled": true,
"recipients": 1,
"nextSendAt": "2026-10-12",
"lastSentAt": "2026-10-05T08:00:00.000Z",
"link": "https://app.monoranks.com/settings/emails"
}
],
"reports": [
{
"id": "1c3e5a7c-9e1a-4c3e-8a5c-9e1a3c5e7a9c",
"kind": "site_summary",
"format": "pdf",
"title": "Acme Bikes: site summary",
"scope": "Acme Bikes",
"period": {
"from": "2026-09-01",
"to": "2026-09-30",
"label": "September 2026"
},
"createdAt": "2026-10-01T06:00:00.000Z",
"link": "https://app.monoranks.com/api/reports/1c3e5a7c-9e1a-4c3e-8a5c-9e1a3c5e7a9c"
}
],
"note": "Newest first: site summaries of this website and the monthly client reports of its client.",
"link": "https://app.monoranks.com/reports"
}{
"error": {
"code": "bad_limit",
"message": "limit must be a whole number from 1 to 20."
}
}{
"error": {
"code": "missing_key",
"message": "Send the key as Authorization: Bearer mr_site_…"
}
}{
"error": {
"code": "missing_scope",
"message": "This key does not have the scope this call needs."
}
}{
"error": {
"code": "not_found",
"message": "Website not found."
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}