API Reference
API: REST resources
Everything you can do in the dashboard for a workspace — pages, components, monitors, incidents, maintenance, subscribers and webhooks — is available over the REST API with the same plan limits. The machine-readable contract is the OpenAPI 3.1 document:
https://usebeacon.pro/api/v1/openapi.json
Conventions
- Authenticate with a workspace token (see Authentication). GET needs the read scope; everything else needs write.
- Resources live under the status page slug. A slug or id from another workspace is always 404.
- Single objects come back as
{"data": {…}}. Lists add links and meta.
- PATCH accepts any subset of fields; omitted fields keep their values. Deletes return 204.
- Errors are JSON with a stable code. Plan limits return 402 plan_limit_reached. See Errors & Rate Limits.
- The older ingest endpoints (POST pages/{slug}/incidents, PATCH incidents/{id}, …) still work unchanged and keep their flat response shape.
Lists return up to per_page items (default 25, max 100). Pass meta.next_cursor back as cursor until it is null.
curl "https://usebeacon.pro/api/v1/status-pages/acme/incidents?per_page=50&state=open" \
-H "Authorization: Bearer bchk_..."
{
"data": [ { "id": 42, "title": "Elevated errors", "state": "investigating", "updates": [ … ], … } ],
"links": { "next": "…?cursor=eyJpZCI6NDIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0" , … },
"meta": { "per_page": 50, "next_cursor": "eyJpZCI6NDIsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0", "prev_cursor": null, … }
}
Status pages
GET |
/api/v1/status-pages |
List pages |
POST |
/api/v1/status-pages |
Create (name required; slug derived if omitted). Counts against max_status_pages. |
GET |
/api/v1/status-pages/{pageSlug} |
Get one page |
PATCH |
/api/v1/status-pages/{pageSlug} |
Update name, slug, description, timezone, is_public, theme, incident_notifications_enabled |
DELETE |
/api/v1/status-pages/{pageSlug} |
Delete the page and everything on it |
Components
GET |
/api/v1/status-pages/{pageSlug}/components |
List in display order |
POST |
/api/v1/status-pages/{pageSlug}/components |
Create (name; status defaults to operational; appended to the end) |
PATCH |
/api/v1/status-pages/{pageSlug}/components/{componentId} |
Update name, description, status, position. A status change fires component webhooks and dependency cascades. |
DELETE |
/api/v1/status-pages/{pageSlug}/components/{componentId} |
Delete (auto-created monitors go with it) |
POST |
/api/v1/status-pages/{pageSlug}/components/reorder |
Body {"ids": [...]} with every component id in the new order |
Monitors
GET |
/api/v1/status-pages/{pageSlug}/monitors |
List with live state, last check and uptime |
POST |
/api/v1/status-pages/{pageSlug}/monitors |
Create: name, type (http|heartbeat|tcp|ping|dns), url, host, port, dns_record_type, dns_expected_value, http_method, expected_status_code, keyword, keyword_match_type, interval_minutes, timeout_seconds, consecutive_threshold, confirm_from_locations, confirmation_quorum, expiry_alerts_enabled, expiry_alert_days, allow_cold_start, cold_start_timeout_seconds, check_window_start/end (HH:MM), status_component_id, enabled |
PATCH |
/api/v1/status-pages/{pageSlug}/monitors/{monitorId} |
Update any subset (type is create-only) |
DELETE |
/api/v1/status-pages/{pageSlug}/monitors/{monitorId} |
Delete |
Incidents
GET |
/api/v1/status-pages/{pageSlug}/incidents?state=open |
List newest first, with updates and component_ids. state takes comma-separated states or "open". |
POST |
/api/v1/status-pages/{pageSlug}/incidents |
Open: title, impact, state, message, component_ids, started_at. Notifies like the dashboard. |
PATCH |
/api/v1/status-pages/{pageSlug}/incidents/{incidentId} |
Update title, impact, state, component_ids; a message also posts a timeline update. |
DELETE |
/api/v1/status-pages/{pageSlug}/incidents/{incidentId} |
Delete |
GET |
/api/v1/status-pages/{pageSlug}/incidents/{incidentId}/updates |
Timeline, oldest first |
POST |
/api/v1/status-pages/{pageSlug}/incidents/{incidentId}/updates |
Post a timeline update (message) |
Scheduled maintenances
GET |
/api/v1/status-pages/{pageSlug}/maintenances?state=scheduled |
List |
POST |
/api/v1/status-pages/{pageSlug}/maintenances |
Create: title, description, starts_at, ends_at, state, component_ids |
PATCH |
/api/v1/status-pages/{pageSlug}/maintenances/{maintenanceId} |
Update any subset |
DELETE |
/api/v1/status-pages/{pageSlug}/maintenances/{maintenanceId} |
Delete |
Subscribers
GET |
/api/v1/status-pages/{pageSlug}/subscribers?confirmed=true |
List, optionally by confirmation |
POST |
/api/v1/status-pages/{pageSlug}/subscribers |
Add: email, component_ids, confirmed (see below) |
PATCH |
/api/v1/status-pages/{pageSlug}/subscribers/{subscriberId} |
Change component_ids (empty = all components) |
DELETE |
/api/v1/status-pages/{pageSlug}/subscribers/{subscriberId} |
Remove |
Webhooks
GET |
/api/v1/status-pages/{pageSlug}/webhooks |
List (secrets are never returned) |
POST |
/api/v1/status-pages/{pageSlug}/webhooks |
Create: url, enabled, status_component_id, secret (optional) |
PATCH |
/api/v1/status-pages/{pageSlug}/webhooks/{webhookId} |
Update; send secret to rotate it |
DELETE |
/api/v1/status-pages/{pageSlug}/webhooks/{webhookId} |
Delete |
Statuspage imports
POST |
/api/v1/status-pages/{pageSlug}/imports |
Start an Atlassian Statuspage import (202). Body: source=api with api_key + page_id, or source=public with url; include_subscribers, subscribers_consent. |
GET |
/api/v1/status-pages/{pageSlug}/imports |
List imports for the page |
GET |
/api/v1/status-pages/{pageSlug}/imports/{importId} |
Progress: state (queued, running, completed, stopped, failed), stage, counts, message |
Subscriber consent
A subscriber added over the API is unconfirmed and receives the same confirmation email as the public subscribe form; they get incident emails only after clicking it. This needs a public page (otherwise 422 page_not_public).
If you already hold consent (for example, migrating an existing list), send "confirmed": true with a token that has the subscribers:confirm scope. No email is sent. Without that scope the request is rejected with 403 insufficient_scope.
Importing from Atlassian Statuspage
Owners can also start an import from Settings → Import from Statuspage. Components are imported flat (a group’s name is kept in each component’s description) with their current status, plus incidents with every update and original timestamps, and scheduled maintenance. Imported history notifies no one.
- API key + page id reads everything through the Statuspage Manage API, and is the only way to bring subscribers. The key is passed encrypted to the import job and discarded afterwards; it is never stored.
- A public page URL (https) reads /api/v2/summary.json, incidents.json and scheduled-maintenances.json: components, the most recent incidents and maintenance. No key needed.
- Imported subscribers are unconfirmed and get a confirmation email, unless subscribers_consent is true (needs the subscribers:confirm scope via the API, or the owner’s explicit confirmation in Settings).
- Re-running is safe: rows are matched by their Statuspage id and updated, not duplicated. When a plan limit is hit the import stops with state stopped and a message; upgrade and run it again to continue.
Webhook secrets
Secrets are write-only. Send your own (16+ characters) or omit it on create and Beacon generates one, returned once as a top-level "secret" field in the 201 response. Rotate it with PATCH; it is never shown again.
{
"data": { "id": 7, "url": "https://hooks.example.com/beacon", "enabled": true, "status_component_id": null, … },
"secret": "q3V…32 chars"
}