Skip to main content
GET
List reports

Authorizations

Authorization
string
header
required

An agent key (rpk_...) created in Settings → API & MCP, sent as Authorization: Bearer rpk_.... Bearer only: a cookie session can never drive this API. An OAuth 2.1 access token obtained from the same host works identically and lands on the same ceiling.

Headers

X-Workspace-Id
string

Which workspace to read. Omit it and you get the account’s home workspace, which on an agency account is often not where the live businesses are. A workspace this credential cannot read is refused with 403 rather than quietly answered from the default.

Query Parameters

q
string

JSON filter object, for example {"needs_response":true}.

sort_by
string

Field to sort on.

limit
integer

Maximum rows to return.

skip
integer

Rows to skip, for paging.

Response

Matching reports.

id
string

Unique id.

workspace_id
string
template
string

Which template to render. PR-9 ships only 'monthly_reputation_report'; PR-13 adds 'competitor_comparison'. Stored as a string (not enum) so adding new templates doesn't require a migration.

period_start
string
period_end
string
status
string

queued | rendering | completed | failed

pdf_url
string

Relative path under /uploads/reports/<workspace_id>/.pdf. Public — filename includes a UUID so URLs are unguessable.

error_message
string

Truncated render-failure reason. Surfaced to the user inline on the failed row.

started_at
string
completed_at
string
render_token
string

Short-lived JWT (~5min) the worker mints for the requested_by user so Puppeteer can authenticate against the SPA preview route. Cleared on completion.

report_data
object

Aggregated data the report renders from. Populated by the worker (server/lib/reportData.js) BEFORE Puppeteer launches, then never touched again — reports are immutable historical artifacts. Top-level keys are namespaced so future PRs extend cleanly: report_data.workspace, .agency, .period, .previousPeriod, .reputationScore, .reviews, .mentions, .responses are PR-10. PR-11 adds .business_location and .insights ({ topThemes, notableReviews, notableMentions, recommendations } — any of which may be null when its LLM call failed). PR-13's competitor template will add .competitors. Treat unknown keys as forward-compat; never assume the full shape.

business_location_id
string

BusinessLocation this report scopes its Reviews data to. PR-11+ requires this for new reports (enforced at the route, not the schema, so existing PR-10 rows with null values stay valid). Reports without it are labelled 'Workspace Rollup (Historical)' in the UI and cannot be shared.

source
string
scheduled_report_id
string

When source='scheduled', points at the ScheduledReport that triggered this run. Lets the UI link back to the schedule's settings + retry buttons.

period_label
string

PR-14: human-readable period label, computed once at create time via server/lib/periodLabel.js. 'April 2026' for full calendar months, 'Q1 2026' for full calendar quarters, 'Mar 15 – Apr 28, 2026' otherwise. Stored on the row so the Reports list can render without recomputing per row. Older rows (pre-PR-14) have null and the UI falls back to computing from period_start/end on read.

public_share_id
string

Unguessable URL-safe token (12 chars, ~10²¹ search space). Generated when the agency owner enables sharing; cleared on disable; regenerated on re-enable so old URLs stay 404. Null when not currently shared.

is_public
boolean

Per-report public-share toggle. Independent of public_share_id presence — a report can have an old share_id with is_public=false (revoked); the public route requires both.

share_view_count
integer

Incremented on each public-page render. Async write — never blocks the response. No IP tracking in PR-11.

share_created_at
string