API reference
Read your sites' boards, uptime, client errors, and broken links from scripts, CI, or an AI assistant, and create or delete sites. JSON over HTTPS, one key per use.
Keys and authentication
Create a key on your account page. It looks like phk_ followed by 32 characters and is shown once: PageHum keeps only a hash. Send it with every request:
curl https://pagehum.com/api/v1/sites \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
- Read keys can call every
GET. Tick write when creating a key to let it create and delete sites too. - A key sees only its own account’s sites. Another account’s site answers 404, the same as one that doesn’t exist.
- Revoke a key on the account page and it stops working at once. An account can have 10 keys.
- Keep keys on servers. The API sends no CORS headers, so browsers can’t call it from a page.
Rate limits
| Plan | Calls per key per hour |
|---|---|
| Free | 60 |
| Starter | 600 |
| Pro | 3,000 |
Hours are UTC clock hours. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (seconds since the epoch). Past the limit you get 429 with Retry-After in seconds.
Responses and errors
Success is { "ok": true, "data": … }. Failure is { "ok": false, "code": …, "error": … }, where error is a sentence you can show and code is one of:
| Code | Status | Means |
|---|---|---|
unauthorized | 401 | No key, or not sent as a Bearer token. |
invalid_key | 401 | The key doesn't exist or was revoked. |
insufficient_scope | 403 | The call needs a write key. |
plan_limit | 403 | The plan has no room, e.g. for another site. |
not_found | 404 | No site with that key on this account. |
bad_request | 400 | A parameter or body is wrong. |
rate_limited | 429 | The key used this hour's calls. |
internal | 500 | Something failed on our side. Retry with backoff. |
Every example on this page runs against a real test site in CI, so what it shows is what the API returns. Times are milliseconds since the Unix epoch (createdAt, lastAt), days are UTC dates (2026-10-07), and rates and uptime are fractions from 0 to 1. range is 7, 14, 30, 90, or 365 days, held to what your plan shows; responses say which range they used.
Lists
/sites returns every site at once (10 at most). /errors and /broken return the most frequent first, up to limit (50 by default, 200 at most); other counts what didn’t fit. The board’s own lists, like top pages, are capped the way the board caps them.
Sites
GET /sites
Every site with its last 7 days: visitors, sessions, pageviews, p75 load, reachability, uptime, error rate, and the one problem if there is one. Sort with sort (created, name, visitors, pageviews, load, uptime, problem) and dir (asc or desc). Empty readings sort last.
Request
curl "https://pagehum.com/api/v1/sites?sort=visitors&dir=desc" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
POST /sites (write)
Creates a site, if the plan has room, and returns its key and tag. name is optional, up to 80 characters.
Request
curl -X POST "https://pagehum.com/api/v1/sites" \
-H "Authorization: Bearer $PAGEHUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Harbor Supply"}'GET /sites/{key}
One site, shaped like an item of the list.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/snippet
The script tag, whether beacons are arriving yet, and the AI setup prompt that installs it, or checks an install that already reports.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/snippet" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
DELETE /sites/{key} (write)
Deletes the site with its counts, checks, incidents, and history. It can’t be undone.
Request
curl -X DELETE "https://pagehum.com/api/v1/sites/s_ab12cd34ef56" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
Readings
GET /sites/{key}/insights
The board itself for range days: usage, performance with load buckets, Web Vitals and INP, speed per device and page, the funnel, the signals and which one is the problem, week over week, a daily or weekly series, top pages and sources, devices, broken paths, failing requests, rage clicks, and pages checked. The same data the dashboard draws; the response below is trimmed. compare=previous adds compare: the same number of days before the range, with its series lined up point for point and its pages, sources, and devices, or { available: false, reason } when the plan doesn’t keep that far back.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/insights?range=30&compare=previous" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/status
What the public status page shows: level, headline, 24-hour and 7-day uptime, incidents, the last check, and chosen pages.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/status" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/errors
Client errors, most frequent first, each with its page, message, count, status (new, back, ongoing, one-off, quiet), first and last seen, the last 14 days, the page’s pageviews, other pages with the same message, the browsers that threw it (family and major version), and a note when it is a known pattern. include=prompt adds each one’s ready-made AI prompt to fix it. Errors you ignored on the board are left out.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/errors?range=7&limit=20&include=prompt" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/broken
Paths visitors hit that returned 404 or 410, or same-site assets that failed to load, with the same history fields, and from: the pages on your site that led there, so you know which link to fix.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/broken?range=7" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/requests
Calls from your pages to your own host (fetch and XHR) that got a 5xx, or no response at all (status: 0), most first, with the same history fields. Only the method, path, and status are kept: no bodies, headers, or visitors.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/requests?range=7" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/issues
Every reading in watch or problem over the last 7 days, the board’s one Problem first. Each has its why, a status for counted readings, 14 days of history in trend, and the rows the board shows for it: errors, paths, requests, slowPages and slowDevices, certificate notes, or failed checks. Readings you cleared or snoozed come last, with suppressed set.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/issues" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/speed
p75 load, LCP, INP, and TTFB per day (per week past 30 days), for every load and per device class, with the lines between good, needs improvement, and poor. A point drawn from fewer than minSamples is null. slowerSince marks where a reading moved into a worse band and stayed there. metric=lcp keeps one reading.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/speed?range=7&metric=lcp" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/pages/{path}
Everything about one page: /pages/pricing/annual for /pricing/annual, and /pages for the home page. Its views and share of traffic, p75 load, LCP, and INP beside the whole site’s, its client errors, missing when the page itself 404s (with the pages that link to it), brokenLinks reached from it, failing calls it made, rage clicks, its page check, and a prompt for an AI assistant scoped to the page.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/pages/cart?range=7" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/export.csv
The range’s daily aggregates as CSV, one row per UTC day, for spreadsheets and your own records. It isn’t wrapped in the JSON envelope; errors still are. p75s are estimated within PageHum’s timing buckets and left blank on a day with too few samples; uptime is the share of homepage checks that passed.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/export.csv?range=7" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/checks
Pages checked besides the homepage, with each one’s last result, failure streak, uptime, and the plan’s limit.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/checks" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
GET /sites/{key}/landingboost
LandingBoost scores for the site’s pages, the latest scan with its First Edit, and the followed page’s history, if the account linked LandingBoost.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/landingboost" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
Deploys and notes
Markers put a line on the board’s charts for each deploy or change, and an issue first seen that day or the next says it started after one. Mark deploys from CI with a write key, or skip the key and use the site’s deploy hook from the board.
POST /sites/{key}/markers (write)
Only text is needed, up to 140 characters. kind is deploy (the default) or note, and at is when it happened, default now. Each plan keeps a number of markers per site (30, 300, or 1,000); past it the oldest drop off, so a CI step never fails on the limit.
Request
curl -X POST "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/markers" \
-H "Authorization: Bearer $PAGEHUM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"v1.4.2: new checkout","kind":"deploy"}'# In CI, after a successful deploy (jq builds the JSON, so quotes in the message are safe):
curl -s -X POST "https://pagehum.com/api/v1/sites/$PAGEHUM_SITE/markers" \
-H "Authorization: Bearer $PAGEHUM_KEY" -H "Content-Type: application/json" \
-d "$(jq -n --arg text "$(git log -1 --pretty=%s)" '{text: $text}')"GET /sites/{key}/markers
Markers in the range, oldest first, with where each came from: board, api, or hook.
Request
curl "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/markers?range=30" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
DELETE /sites/{key}/markers/{id} (write)
Removes one marker.
Request
curl -X DELETE "https://pagehum.com/api/v1/sites/s_ab12cd34ef56/markers/6f0e2c8a-4b1d-4e7a-9c35-2d8f1a7b9e40" \ -H "Authorization: Bearer $PAGEHUM_API_KEY"
OpenAPI and versions
The full description is at /api/v1/openapi.json (OpenAPI 3.1), for code generators and API clients. Version 1 only grows: new fields and endpoints can appear, so ignore fields you don’t know. Anything that would break a client goes into /api/v2, with /api/v1 kept for at least six months after.