Account
Status Pages API
The Status Pages API is at https://api.scaledpapers.com. Authenticate with the same key you use for the Checks API: Authorization: Bearer sp_…. An agent can call the same pages from MCP. Creating and revoking keys still happens in API Keys. The key acts as the workspace where it was created (see API keys in a team). If an admin is later changed to member, existing keys keep working until revoked.
Every request acts as the account that owns the key — you can only see and change your own status pages.
Create a status page
curl https://api.scaledpapers.com/v1/sites \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme",
"slug": "acme",
"url": "https://acme.com"
}'
nameandslugare required. Slug is lowercase letters, numbers, and hyphens (2-40 chars) and cannot change later.urlis optional — it creates a website component for the page.visibilityis optional (publicdefault, orinternalfor a private page). Private requires Pro and apasswordof at least 8 characters.custom_domainis optional on create (Pro). Subdomain only, such asstatus.acme.com. The page stays on{slug}.status.scaledpapers.comuntil DNS is verified.- The page is live at
https://acme.status.scaledpapers.com. - A taken slug returns
409with{"detail":"That slug is taken"}. - A Free workspace that sends
visibility: "internal"or a custom domain gets403.
Create a private page (visibility stays internal on the wire):
curl https://api.scaledpapers.com/v1/sites \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Internal",
"slug": "acme-internal",
"visibility": "internal",
"password": "at-least-8-chars"
}'
List and read pages
curl https://api.scaledpapers.com/v1/sites \
-H "Authorization: Bearer sp_…"
Each row includes slug, name, and the worst open incident status. GET /v1/sites/{slug} returns the full bundle: components, groups, incidents, uptime payload, and Slack connection state. Site objects include visibility (public or internal), has_password (never the password itself), publicUrl, and custom-domain fields (custom_domain, custom_domain_status).
Update page info
PATCH /v1/sites/{slug} updates page identity. Send visibility as public or internal. Private pages require Pro and a password of at least 8 characters (omit password to keep the current one). Switching to public clears the password. A Free workspace that tries to set Private gets 403.
Send custom_domain as a hostname such as status.acme.com, or null to remove it. Apex hosts and *.scaledpapers.com are rejected. Custom domains require Pro (403 on Free). After DNS is in place, POST /v1/sites/{slug}/custom-domain/verify checks the CNAME to cname.scaledpapers.com and the TXT challenge. publicUrl becomes https://{custom_domain} only when the domain is active.
Visitors unlock a private page with POST /sites/{slug}/unlock on the monitor (or /unlock on the status page host). That is not part of the authenticated Status Pages API.
Delete a page
DELETE /v1/sites/{slug} removes the public page, its components, incidents, and the owner Slack connection. This cannot be undone.
Add a component
curl https://api.scaledpapers.com/v1/sites/acme/components \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{"name": "Payments API", "url": "https://api.acme.com"}'
Components are the services shown on the public page — they are not checks. Rename with PATCH /v1/sites/{slug}/components/{id}; delete with DELETE.
Link a check to a component
Use the Checks API: send site_id, site_slug, and component_id together on PATCH /v1/endpoints/{id}. alert_incident_enabled opens one incident for a flapping period, not a new incident on every recovery. See Incidents. display_metrics shows latency on the public page. A component can be linked to only one check.
Create an incident
curl https://api.scaledpapers.com/v1/sites/acme/incidents \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{
"title": "Payments API errors",
"body": "We are looking into the issue.",
"status": "investigating",
"impact": "major",
"component_ids": ["m3vnq6ytahvq"]
}'
titleandbodyare required.component_idsis optional: it takes component public ids — the same 12-character ids as in console component URLs (/app/{slug}/components/{id}) — internal integer ids also work. Omit it for a site-wide incident with no affected components.status: investigating, identified, monitoring, resolved.impact: minor, major, critical.- Backfill a past incident with
opened_at+resolved_at(status is forced toresolved). - Email subscribers and Slack notifications fire exactly as they do from the console. A site-wide incident notifies only visitors subscribed to all components; a component incident also notifies subscribers watching that component.
Post an update
curl https://api.scaledpapers.com/v1/sites/acme/incidents/{public_id}/updates \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{
"status": "identified",
"body": "Root cause found, deploying a fix."
}'
{public_id} is the 12-character id from the incident (incidents/{id} on the public page). Status resolved closes the incident. Resolving from the Checks API (a linked check recovering) posts the same update shape.
The response is 201 with the full incident: status is the new current status, updates lists all updates newest-first (the first entry is the one you just posted), and resolved_at stays null until a resolved update sets it. Subscribers and Slack are notified before the response returns.
Component groups
curl https://api.scaledpapers.com/v1/sites/acme/component-groups \
-H "Authorization: Bearer sp_…" \
-H "Content-Type: application/json" \
-d '{"name": "APIs"}'
POST /v1/sites/{slug}/component-groups adds a group. PATCH /v1/sites/{slug}/component-groups/{id} renames it (name) or sets position. DELETE /v1/sites/{slug}/component-groups/{id} removes it. The id is the integer from the create response.
Slack
POST /v1/sites/{slug}/integrations/slack/start returns a URL. Open it to finish connecting Slack. POST /v1/sites/{slug}/integrations/slack/disconnect removes the connection. GET /v1/sites/{slug} includes whether Slack is connected.
What is not on the API yet
Visitor subscriber management stays console-only for now.