Reference
View as MarkdownStatus pages API
10 operations. Every call needs a session cookie or an Authorization: Bearer nct_… token unless marked Public. Conventions, errors and scopes
/status-pagesList status pages
The workspace's public status pages with their components. Component service, environment and project names are empty for tokens restricted to other projects.
Response 200 · OK · application/json
- StatusPageView[] | nullrequired
401Unauthorized403Forbidden500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pagesCreate a status page
Creates an unpublished page. Add components with PUT /status-pages/{pageId}/components (or start from a project's production services with fromProjectId), point the hostname's DNS at the control-plane server (GET /status-pages/{pageId}/dns; with a connected Cloudflare zone NebulaCtrl manages the records itself, see GET /status-pages/{pageId}/cloudflare), then publish with PATCH. 409 hostname_reserved for the dashboard's own host, hostname_conflict for a hostname another page or a service domain uses, slug_conflict for a slug in use. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Client-chosen key (<=255 chars). A retry with the same key replays the original response for 24 hours. |
Request body · application/json · required
- descriptionstring
- footerstringPlain text shown under the public page; line breaks kept
- fromProjectIdstringStart from a project: the page gets that project's production-environment services that have at least one public domain as components (display name = service name, no group, in name order). Editable afterwards. 422 unknown_project when the project is not in the workspace
- hostnamestringThe public DNS name the page is served on, e.g. status.example.com. Lowercased; unique; not the dashboard's host or a service domain
- showUptimebooleanShow availability percentages (default true)
- slugstringUnique in the workspace: lowercase letters, digits and hyphens. Default: derived from the title
- themeenum: auto | light | darkDefault auto: the visitor's preference
- titlestringrequiredShown as the page's heading
Response 201 · Created · application/json
- StatusPageComponentView[] | nullrequiredIn page order
- createdAtstring (date-time)required
- descriptionstringrequired
- footerstringrequiredPlain text shown under the page
- hostnamestring | nullrequiredThe public hostname; null until one is set
- idstringrequired
- publishedbooleanrequiredServed on the hostname (needs a hostname and at least one component)
- showUptimebooleanrequiredShow availability percentages next to the day bars
- slugstringrequired
- themeenum: auto | light | darkrequired
- titlestringrequired
- updatedAtstring (date-time)required
401Unauthorized403Forbidden409Conflicthostname_reserved422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}Get a status page
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Response 200 · OK · application/json
- StatusPageComponentView[] | nullrequiredIn page order
- createdAtstring (date-time)required
- descriptionstringrequired
- footerstringrequiredPlain text shown under the page
- hostnamestring | nullrequiredThe public hostname; null until one is set
- idstringrequired
- publishedbooleanrequiredServed on the hostname (needs a hostname and at least one component)
- showUptimebooleanrequiredShow availability percentages next to the day bars
- slugstringrequired
- themeenum: auto | light | darkrequired
- titlestringrequired
- updatedAtstring (date-time)required
401Unauthorized403Forbidden422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}Update a status page
Omitted fields stay as they are. published: true needs a hostname and at least one component (422 publish_needs_hostname, publish_needs_components). Changing the hostname of a published page, or publishing or unpublishing it, re-sends the control-plane server's routes: the page is served (or withdrawn) within moments. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Request body · application/json · required
- descriptionstring
- footerstringPlain text shown under the public page; line breaks kept
- hostnamestringEmpty removes the hostname (the page must not be published)
- publishedbooleantrue serves the page on its hostname; needs a hostname and at least one component
- showUptimeboolean
- slugstring
- themeenum: auto | light | dark
- titlestring
Response 200 · OK · application/json
- StatusPageComponentView[] | nullrequiredIn page order
- createdAtstring (date-time)required
- descriptionstringrequired
- footerstringrequiredPlain text shown under the page
- hostnamestring | nullrequiredThe public hostname; null until one is set
- idstringrequired
- publishedbooleanrequiredServed on the hostname (needs a hostname and at least one component)
- showUptimebooleanrequiredShow availability percentages next to the day bars
- slugstringrequired
- themeenum: auto | light | darkrequired
- titlestringrequired
- updatedAtstring (date-time)required
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entitypublish_needs_hostname500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}Delete a status page
Deletes the page and withdraws its route. Incidents and maintenance windows posted to it stay. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Response 204 · No Content
No body.
401Unauthorized403Forbidden422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}/cloudflareLive Cloudflare DNS status of a status page's hostname
Reads the records of the hostname from Cloudflare and classifies them like GET /domains/{domainId}/dns does: managed, present, wrong_target, missing or not_in_zone. The wanted records are the control-plane server's public addresses (desiredRecords). originLock says whether the page is locked to Cloudflare. Changes nothing. 422 no_hostname while the page has no hostname.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Response 200 · OK · application/json
- checkedAtstring (date-time) | nullrequired
- configuredbooleanrequiredThe team has a Cloudflare connection
- conflictstringrequiredWhy adopting is impossible (for example a CNAME next to an A record)
- RecordViewrequired
- RecordView[] | nullrequired
- effectiveProxiedbooleanrequired
- errorstringrequiredThe last failed sync, empty when the last sync worked
- managebooleanrequiredNebulaCtrl keeps this hostname's records in sync
- messagestringrequired
- needsAdoptbooleanrequired
- OriginLockViewrequired
- proxiedbooleanrequiredThe proxy setting of the hostname (orange cloud)
- RecordView[] | nullrequiredA, AAAA and CNAME records of the hostname
- sslModeenum: | off | flexible | full | strictrequiredThe zone's SSL/TLS mode; empty when unknown
- statusenum: | managed | present | wrong_target | missing | not_in_zonerequired
- tunnelbooleanrequiredThe server is behind a Cloudflare Tunnel: the record is a proxied CNAME to it (never for a status page)
- warningsstring[] | nullrequired
- zoneIdstringrequired
- zoneNamestringrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entityno_hostname500Internal Server Error502Bad Gateway
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}/cloudflareChange the Cloudflare settings of a status page's hostname
Sets the proxy toggle, whether NebulaCtrl manages the page's records and the origin lock opt-in, then syncs. A proxied, published page is locked to Cloudflare. A failed sync is reported as error in the status and retried in the background. Audited as status_page.dns.update. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Request body · application/json · required
- managebooleanLet NebulaCtrl keep the page's DNS records in sync
- originLockbooleanLock the control-plane server's route of the page to Cloudflare while it is proxied (default true). False opts out: anyone who finds the server's IP can bypass Cloudflare. Audited.
- proxiedbooleanProxy through Cloudflare (orange cloud). A proxied page is locked to Cloudflare while it is published.
Response 200 · OK · application/json
- checkedAtstring (date-time) | nullrequired
- configuredbooleanrequiredThe team has a Cloudflare connection
- conflictstringrequiredWhy adopting is impossible (for example a CNAME next to an A record)
- RecordViewrequired
- RecordView[] | nullrequired
- effectiveProxiedbooleanrequired
- errorstringrequiredThe last failed sync, empty when the last sync worked
- managebooleanrequiredNebulaCtrl keeps this hostname's records in sync
- messagestringrequired
- needsAdoptbooleanrequired
- OriginLockViewrequired
- proxiedbooleanrequiredThe proxy setting of the hostname (orange cloud)
- RecordView[] | nullrequiredA, AAAA and CNAME records of the hostname
- sslModeenum: | off | flexible | full | strictrequiredThe zone's SSL/TLS mode; empty when unknown
- statusenum: | managed | present | wrong_target | missing | not_in_zonerequired
- tunnelbooleanrequiredThe server is behind a Cloudflare Tunnel: the record is a proxied CNAME to it (never for a status page)
- warningsstring[] | nullrequired
- zoneIdstringrequired
- zoneNamestringrequired
401Unauthorized403Forbidden404Not Found422Unprocessable Entity500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}/cloudflare/fixFix a status page's DNS records
Creates or corrects the records so the hostname points at the control-plane server. A record NebulaCtrl did not create is never modified unless adopt is true (409 adoption_required; 409 dns_conflict when adopting is impossible). 422 not_configured / not_in_zone / no_hostname; 502 when Cloudflare fails. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Request body · application/json · required
- adoptbooleanTake over the existing record NebulaCtrl did not create: it is marked as managed and pointed at the control-plane server
Response 200 · OK · application/json
- checkedAtstring (date-time) | nullrequired
- configuredbooleanrequiredThe team has a Cloudflare connection
- conflictstringrequiredWhy adopting is impossible (for example a CNAME next to an A record)
- RecordViewrequired
- RecordView[] | nullrequired
- effectiveProxiedbooleanrequired
- errorstringrequiredThe last failed sync, empty when the last sync worked
- managebooleanrequiredNebulaCtrl keeps this hostname's records in sync
- messagestringrequired
- needsAdoptbooleanrequired
- OriginLockViewrequired
- proxiedbooleanrequiredThe proxy setting of the hostname (orange cloud)
- RecordView[] | nullrequiredA, AAAA and CNAME records of the hostname
- sslModeenum: | off | flexible | full | strictrequiredThe zone's SSL/TLS mode; empty when unknown
- statusenum: | managed | present | wrong_target | missing | not_in_zonerequired
- tunnelbooleanrequiredThe server is behind a Cloudflare Tunnel: the record is a proxied CNAME to it (never for a status page)
- warningsstring[] | nullrequired
- zoneIdstringrequired
- zoneNamestringrequired
401Unauthorized403Forbidden404Not Found409Conflictadoption_requireddns_conflict422Unprocessable Entitynot_configured500Internal Server Error502Bad Gateway
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}/componentsSet the components of a status page
Replaces the page's components with the ordered list: the services it shows, each under a public display name (default: the service's name, at most 60 characters) and an optional group. Every service must belong to the workspace (422 unknown_service). A published page needs at least one component. Requires the admin scope.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Request body · application/json · required
- ComponentBody[] | nullrequiredThe full ordered list: it replaces the page's components
Response 200 · OK · application/json
- StatusPageComponentView[] | nullrequiredIn page order
- createdAtstring (date-time)required
- descriptionstringrequired
- footerstringrequiredPlain text shown under the page
- hostnamestring | nullrequiredThe public hostname; null until one is set
- idstringrequired
- publishedbooleanrequiredServed on the hostname (needs a hostname and at least one component)
- showUptimebooleanrequiredShow availability percentages next to the day bars
- slugstringrequired
- themeenum: auto | light | darkrequired
- titlestringrequired
- updatedAtstring (date-time)required
401Unauthorized403Forbidden404Not Found409Conflict422Unprocessable Entityunknown_service500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.
/status-pages/{pageId}/dnsCheck the DNS of a status page's hostname
The A and AAAA records the hostname needs (the control-plane server's public addresses) and whether the hostname resolves to them right now. A page whose Cloudflare record is proxied is ok when the hostname resolves to Cloudflare's addresses (proxied: true), not mismatch. 422 no_hostname while the page has no hostname.
| Parameter | In | Type | Description |
|---|---|---|---|
pageIdrequired | path | string |
Response 200 · OK · application/json
- hostnamestringrequired
- messagestringrequired
- proxiedbooleanrequiredThe page's Cloudflare record is proxied and the hostname resolves to Cloudflare's addresses: status is ok then
- StatusPageDNSRecord[] | nullrequiredThe records to create: the control-plane server's public addresses
- resolvedstring[] | nullrequiredWhat the hostname resolves to right now
- statusenum: ok | mismatch | missing | unknownrequired
401Unauthorized403Forbidden422Unprocessable Entityno_hostname500Internal Server Error
Errors are RFC 9457 application/problem+json with a stable code field.