Authentication
| Method | Path | Auth | Notes |
| POST | /api/auth/signup | none | Body: { agencyName, email, password }. Returns a session token. |
| POST | /api/auth/login | none | Body: { email, password }. Returns a session token. |
| POST | /api/auth/forgot-password | none | Body: { email }. Always returns the same generic response. |
| POST | /api/auth/reset-password | none | Body: { token, newPassword }. Token is single-use, expires in 1 hour. |
Sites
| Method | Path | Auth | Notes |
| GET | /api/sites | Bearer token | Lists every site for your agency, with open finding counts. |
| POST | /api/sites | Bearer token | Body: { url, label? }. Free tier capped at 2 sites. Rate-limited. |
| GET | /api/sites/:id | Bearer token | Single site detail. |
| POST | /api/sites/:id/scan | Bearer token | Triggers an on-demand passive scan. Rate-limited. |
| GET | /api/sites/:id/findings | Bearer token | Open findings by default; ?status=all for full history. |
Advisories, benchmarks, trends, incidents, stats
| Method | Path | Auth | Notes |
| GET | /api/advisories | Bearer token | Recent advisories from the ingested Drupal.org feed. |
| GET | /api/benchmarks/:siteId | Monitored + Connector | Cross-site percentile. Null until enough sites exist in the comparison set. |
| GET | /api/trends/:siteId | Bearer token | Daily open-finding snapshots. |
| GET | /api/incidents | Bearer token | Open findings grouped by advisory across your whole portfolio. |
| GET | /api/stats/mean-time-to-patch | Bearer token | Optional ?siteId= to scope to one site. |
Reports & billing
| Method | Path | Auth | Notes |
| GET | /api/reports/:siteId.pdf | Monitored + Connector | White-label PDF report, streamed directly. |
| GET | /api/billing/config | Bearer token | Paddle client token + price IDs, for opening checkout. |
Account
| Method | Path | Auth | Notes |
| GET | /api/agencies/me/export | Bearer token | Full data export — every site, finding, scan, and alert rule. |
| DELETE | /api/agencies/me | Bearer token | Body: { confirmName } (exact agency name). Permanent, cascades to all data. |
Not for direct use
These exist for the connector module and Paddle specifically, and require a valid HMAC/webhook signature rather than a Bearer token:
| POST | /api/connector/report/:siteId | HMAC signature | Used by the connector module — see the install guide. |
| POST | /api/billing/webhook | Paddle signature | Paddle subscription lifecycle events. |
| POST | /api/newsletter/subscribe | CORS-restricted | Used by the marketing site's footer signup — not intended for other callers. |
Rate limits
A general limit applies across the whole API (300 requests / 15 min by default). Site creation and scan triggers share a stricter limit (30 / hour by default). Both return 429 with standard RateLimit-* headers when exceeded.