---
title: "Status Pages — API v1 and MCP | Nodea Documentation"
description: "Reference for the Status Pages module: API v1 CRUD endpoints for public status pages, monitoring:* scopes, owner-only access (404 on foreign resources), MCP tools and curl / JSON-RPC examples."
url: "https://nodea.io/en/api-docs/status-pages"
lang: "en"
updated: "2026-07-16"
---

# Status Pages — API v1 and MCP | Nodea Documentation

> Status Pages module reference — public status pages: API v1 CRUD endpoints, monitoring:read/write/delete scopes, owner-only access (404 on foreign resources), MCP tools and examples.

The **Status Pages** module handles public status pages: a public view of the state of selected monitored websites at /status/{slug}. API v1 provides full CRUD over status-page definitions. The public renderer (/status/{slug}) is a separate, unauthenticated web route and is **not** part of this API.

## Authentication, scopes and flag

Passport Bearer token. Scopes: monitoring:read (index, show), monitoring:write (create, update), monitoring:delete (delete). The module is gated by the features:websites flag (status pages ride the same flag as websites).

## Ownership — no policy

StatusPage has no policy class. Access is owner-only — every row is scoped to user\_id = token user. A foreign or unknown id **consistently yields 404** (never confirming another tenant's resource exists). Additionally, websites attached to a status page must be **owned** by the user (OWNER pivot) — a FOREIGN share does not qualify, because a status page exposes the website publicly. A foreign website\_id → 422 (the API raises an error instead of silently dropping it).

## API v1 — endpoints

MethodPathScopeDescriptionGET/api/v1/status-pagesmonitoring:readList of the user's status pages (with a website count), paginated. GET/api/v1/status-pages/{statusPage}monitoring:readDetail with the list of attached websites. POST/api/v1/status-pagesmonitoring:writeCreate a status page. Returns 201. PUT/PATCH/api/v1/status-pages/{statusPage}monitoring:writeUpdate (partial) + website sync when selectedWebsiteIds is provided. DELETE/api/v1/status-pages/{statusPage}monitoring:deletePermanent delete. Returns 204.

### GET /status-pages — query parameters

- per\_page (int 1–100, default 20), page.

### POST/PATCH — body parameters

- title (string, required, max 120).
- slug (string, required, max 80, regex ^\[a-z0-9-\]+$, unique; on update the page's own slug is exempt).
- description (string, optional, max 1000).
- accent\_color (required, regex ^#\[0-9A-Fa-f\]{6}$).
- logo\_url (url, optional, max 500).
- is\_public (boolean; on a partial PATCH, omitting it leaves visibility unchanged).
- selectedWebsiteIds\[\] — ids of websites **owned** by the user (OWNER pivot); list order = display order (display\_order).

### Response shape (StatusPageResource)

Fields: id, slug, title, description, accent\_color, logo\_url, is\_public, public\_url (always resolvable — a private page simply 404s for visitors), website\_ids\[\], websites\[\] ({id,name}, only when the relation is loaded), websites\_count, created\_at, updated\_at.

### Error codes

- 401 — missing/invalid token; 403 — missing scope or inactive flag; 404 — unknown or foreign id; 422 — validation (non-unique slug, bad color, foreign/unowned website\_id).

## Examples — API

### Create a status page

curl -s -X POST https://app.nodea.io/api/v1/status-pages \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Content-Type: application/json" \\ -d '{ "title": "Service status", "slug": "service-status", "accent\_color": "#50CD89", "is\_public": true, "selectedWebsiteIds": \["9b1f...uuid", "7c22...uuid"\] }'

### Publish an existing page (PATCH)

curl -s -X PATCH https://app.nodea.io/api/v1/status-pages/{id} \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Content-Type: application/json" \\ -d '{ "title": "Service status", "slug": "service-status", "accent\_color": "#50CD89", "is\_public": true }'

## MCP — tools

Same auth/scope model as API v1 and the features:websites flag. Resolution by id is owner-scoped (no policy); a missing and a foreign id raise the same error. Unlike the web (which silently drops foreign ids), the MCP tools **reject** any website\_id the user does not own, so a forged list can never expose another tenant's website publicly.

ToolScopeTypeDescriptionstatus-pages-listmonitoring:readread-onlyList of status pages (newest first); page, per\_page (max 50). status-page-getmonitoring:readread-onlyDetail with the ordered list of websites. Param: id. status-page-createmonitoring:writewritetitle, slug, description, accent\_color (default #50CD89), logo\_url, is\_public (default false), website\_ids\[\] (owned only). status-page-updatemonitoring:writeidempotentPartial update; website\_ids\[\] replaces the full list (owned only). status-page-deletemonitoring:deletedestructivePermanent delete; requires confirm: true.

Output (status-page-\*): id, slug, title, description, accent\_color, logo\_url, is\_public, public\_url, websites\_count (when counted), websites\[\] ({id,name,url,display\_order,visible}, when loaded), created\_at, updated\_at.

### Example — MCP (JSON-RPC)

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "status-page-create", "arguments": { "title": "Service status", "slug": "service-status", "is\_public": true, "website\_ids": \["9b1f...uuid", "7c22...uuid"\] } } } { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "status-page-delete", "arguments": { "id": "5d40...uuid", "confirm": true } } }

## Related

- [Websites — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/websites)
- [Heartbeats — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/heartbeats)
- [Reports (SSL / WHOIS) — API v1 and MCP | Nodea Documentation](https://nodea.io/en/api-docs/reports)

---

Languages: [pl](https://nodea.pl/pl/dokumentacja-api/status-pages.md)  
Site index: [llms.txt](https://nodea.io/en/llms.txt)
