> For the complete documentation index, see [llms.txt](https://docs.statuspal.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.statuspal.io/next/developers/api-reference/models.md).

# Models

## The StatusPage object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"StatusPage":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"subdomain":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"website_url":{"type":"string","format":"uri"},"current_status":{"readOnly":true,"type":"string","enum":["operational","degraded","unavailable"],"description":"Highest-severity status derived from active notices and services"},"require_authentication":{"type":"boolean","default":false},"notification_settings":{"$ref":"#/components/schemas/NotificationSettings"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}},"NotificationSettings":{"type":"object","properties":{"email_enabled":{"type":"boolean","default":true},"slack_enabled":{"type":"boolean","description":"Whether notices are posted to subscribed Slack channels. Also gates Slack's own feed reader from fetching the notices RSS feed.","default":true},"rss_feed_enabled":{"type":"boolean","default":true}}}}}}
```

## The StatusPageCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"StatusPageCreate":{"type":"object","required":["subdomain","name","timezone","website_url"],"properties":{"subdomain":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]*[a-z0-9]$"},"name":{"type":"string"},"timezone":{"type":"string"},"website_url":{"type":"string","format":"uri"},"require_authentication":{"type":"boolean","default":false},"notification_settings":{"$ref":"#/components/schemas/NotificationSettings"},"services":{"type":"array","description":"Optional list of services to create alongside the status page. Each entry\nuses the `ServiceCreate` shape (`name`, optional `slug`, optional\n`description`). If `slug` is omitted it is derived from `name` (collisions\nauto-suffixed as `-1`, `-2`, ...). Entries with a blank `name` are skipped\nand exact-duplicate entries deduped.\n\nA page can be created with Global Services, Container Services, or a mix of both. Each entry may set `containers` to the slugs it belongs to. Omitting it includes the service in every container defined in this request; an empty array creates a Global Service.\nAny container named in a service's `containers` must be defined in the `containers` list of this same request. Naming one that is not returns 422 identifying the offending slug — for example, `container \"us\" was not defined; define it under containers or remove it from service \"api\"`.\nNote: `container_statuses` is not honored in this nested form, since containers are still being created. Set statuses after creation, or with a notice update.\n","items":{"$ref":"#/components/schemas/ServiceCreate"}},"containers":{"type":"array","description":"Optional list of containers. Each entry uses the `ContainerCreate` shape (`name`, optional `slug`).\nIf omitted or empty, the status page is created with no containers, and every service in `services` is created as a Global Service. When containers are supplied, each service in `services` is created as a Container Service included in all of them, unless that service names its own `containers`.\nEntries with a blank `name` are skipped and exact-duplicate entries deduped.\n","items":{"$ref":"#/components/schemas/ContainerCreate"}}}},"NotificationSettings":{"type":"object","properties":{"email_enabled":{"type":"boolean","default":true},"slack_enabled":{"type":"boolean","description":"Whether notices are posted to subscribed Slack channels. Also gates Slack's own feed reader from fetching the notices RSS feed.","default":true},"rss_feed_enabled":{"type":"boolean","default":true}}},"ServiceCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","description":"Optional URL-safe identifier. If omitted, it is auto-generated from `name`.\nIf a non-unique value is provided, a numeric suffix is appended (e.g. `api-1`).\n"},"description":{"type":["string","null"]},"group":{"type":["string","null"],"description":"Slug of the service group to put this service in, or `null` for ungrouped. The group must already exist — create it with `POST /service_groups` first.\nIts `scope` must match the service's own, which `containers` determines in this same request: putting a Global Service in a container-scoped group, or the reverse, returns 422. An unknown slug returns 422.\n"},"containers":{"type":"array","items":{"type":"string"},"description":"The containers to include this service in, by slug. This is what determines the service scope: listing one or more containers creates a Container Service, while passing an explicit empty array creates a Global Service.\nOmitting the field defaults to every container on the status page, which keeps existing clients working unchanged. On a page with no containers that default is empty, so the service is Global. An unknown slug returns 422.\n"},"container_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ContainerStatusEntry"},"description":"Optional initial status per container, for a Container Service.\nEvery `container_slug` must be one this service is included in — otherwise 422. Included containers not listed default to `ok`. Ignored for a Global Service; use `status` there instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"Optional initial status for a Global Service. Defaults to `ok`.\nIgnored for a Container Service; use `container_statuses` there instead.\n"}}},"ContainerStatusEntry":{"type":"object","required":["container_slug","status"],"properties":{"container_slug":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}},"ContainerCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","description":"Optional URL-safe identifier. If omitted, it is auto-generated from `name`.\nIf a non-unique value is provided, a numeric suffix is appended (e.g. `eu-1`).\n"},"services":{"type":"array","items":{"type":"string"},"description":"Slugs of the services to include in this container.\nA container must contain at least one service — an empty array, or a default that would resolve to none, returns 422. An unknown slug returns 422.\nDefaults to every container-scoped service on the status page. Listing a Global Service converts it to a Container Service scoped to this container.\n"}},"description":"Service membership is explicit. It can be set here, or from the service side via `scope` and `containers` on the service resource.\nPer-container service status is not set here — it is updated via notice updates or the operational dashboard.\n"}}}}
```

## The StatusPageUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"StatusPageUpdate":{"type":"object","properties":{"name":{"type":"string"},"timezone":{"type":"string"},"website_url":{"type":"string","format":"uri"},"require_authentication":{"type":"boolean"},"notification_settings":{"$ref":"#/components/schemas/NotificationSettings"}}},"NotificationSettings":{"type":"object","properties":{"email_enabled":{"type":"boolean","default":true},"slack_enabled":{"type":"boolean","description":"Whether notices are posted to subscribed Slack channels. Also gates Slack's own feed reader from fetching the notices RSS feed.","default":true},"rss_feed_enabled":{"type":"boolean","default":true}}}}}}
```

## The NotificationSettings object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NotificationSettings":{"type":"object","properties":{"email_enabled":{"type":"boolean","default":true},"slack_enabled":{"type":"boolean","description":"Whether notices are posted to subscribed Slack channels. Also gates Slack's own feed reader from fetching the notices RSS feed.","default":true},"rss_feed_enabled":{"type":"boolean","default":true}}}}}}
```

## The Service object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"Service":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"slug":{"type":"string","description":"URL-safe identifier. May be supplied on create/update; if omitted, it is\nauto-generated from `name`. Uniqueness is enforced per status page.\n"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"When `scope` is `containers`, the worst-case status across the containers this service is included in. When `scope` is `global`, the service's own status.\nRead-only here; change it with a notice update, from the operational dashboard, or by writing `status` / `container_statuses` on update.\n","readOnly":true},"order":{"type":"integer","description":"Display position on the status page. For an ungrouped service it is the position in the page's one sequence of groups and ungrouped services, shared with `ServiceGroup.order`. For a grouped service it only ranks the service among its group's members, and the group's own `order` places the group. To rebuild the page, sort groups and ungrouped services together by `order`, then list each group's members by theirs. Sorting services alone does not give the grouped layout, because moving a service into a group keeps its `order`.\n"},"group":{"type":["string","null"],"readOnly":true,"description":"Slug of the service group this service belongs to, or `null` when it is ungrouped. A service belongs to at most one group, and the group's `scope` always matches the service's.\nRead-only here; write the same slug on create or update to change it. Fetch the group's name, order and rollup status from `/service_groups/{service_group_slug}`.\n"},"scope":{"type":"string","readOnly":true,"enum":["global","containers"],"description":"Whether this service applies status-page-wide (`global`) or is scoped to specific containers (`containers`).\nDerived, not stored: a service with at least one container is `containers`, and a service with none is `global`. It is computed per response and cannot be written directly — set `containers` on create or update instead.\n"},"containers":{"type":"array","readOnly":true,"items":{"type":"string"},"description":"Slugs of the containers this service is included in. Empty when `scope` is `global`. Containers on the status page that are absent from this list are ones the service is explicitly excluded from.\n"},"container_statuses":{"type":"array","readOnly":true,"items":{"$ref":"#/components/schemas/ContainerStatusEntry"},"description":"Live status for each container this service is included in. Empty when `scope` is `global`. Containers the service is excluded from produce no entry.\n"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}},"ContainerStatusEntry":{"type":"object","required":["container_slug","status"],"properties":{"container_slug":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ServiceCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","description":"Optional URL-safe identifier. If omitted, it is auto-generated from `name`.\nIf a non-unique value is provided, a numeric suffix is appended (e.g. `api-1`).\n"},"description":{"type":["string","null"]},"group":{"type":["string","null"],"description":"Slug of the service group to put this service in, or `null` for ungrouped. The group must already exist — create it with `POST /service_groups` first.\nIts `scope` must match the service's own, which `containers` determines in this same request: putting a Global Service in a container-scoped group, or the reverse, returns 422. An unknown slug returns 422.\n"},"containers":{"type":"array","items":{"type":"string"},"description":"The containers to include this service in, by slug. This is what determines the service scope: listing one or more containers creates a Container Service, while passing an explicit empty array creates a Global Service.\nOmitting the field defaults to every container on the status page, which keeps existing clients working unchanged. On a page with no containers that default is empty, so the service is Global. An unknown slug returns 422.\n"},"container_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ContainerStatusEntry"},"description":"Optional initial status per container, for a Container Service.\nEvery `container_slug` must be one this service is included in — otherwise 422. Included containers not listed default to `ok`. Ignored for a Global Service; use `status` there instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"Optional initial status for a Global Service. Defaults to `ok`.\nIgnored for a Container Service; use `container_statuses` there instead.\n"}}},"ContainerStatusEntry":{"type":"object","required":["container_slug","status"],"properties":{"container_slug":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ServiceUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceUpdate":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","description":"Optional. If provided, replaces the URL slug (with uniqueness suffixing if needed)."},"description":{"type":["string","null"]},"order":{"type":"integer","description":"Position in the display list (1-indexed). Other services shift accordingly."},"group":{"type":["string","null"],"description":"Slug of the service group to move this service into, or `null` to ungroup it. The group must already exist and its `scope` must match the service's — otherwise 422.\nChanging `containers` so the service's scope flips removes it from its current group automatically, unless this field names a group of the new scope in the same request.\nMoving a group's last service out leaves the group standing, empty. To move a whole group between scopes, write `containers` on the group rather than on each service.\n"},"containers":{"type":"array","items":{"type":"string"},"description":"Replaces the set of containers this service is included in, by slug, and with it the service scope. Passing an empty array makes the service Global; passing one or more containers makes it a Container Service. An unknown slug returns 422.\nStatus is preserved across a scope change, never reset. Switching Global to Container-scoped gives every newly-included container the service current status. Switching Container-scoped to Global discards the per-container configuration and keeps the worst-case of the discarded statuses — the status the public page was already showing.\n"},"container_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ContainerStatusEntry"},"description":"Sets the live status of this service in the named containers — the API equivalent of the operational dashboard.\nEvery `container_slug` must be one this service is included in — otherwise 422. Containers not listed keep their current status. Rejected with 422 for a Global Service; use `status` there instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"Sets the live status of a Global Service — the API equivalent of the operational dashboard.\nRejected with 422 for a Container Service; use `container_statuses` there instead.\nA status set this way does not notify subscribers and does not count toward uptime history, which is built from notices. To record an outage, post a notice or notice update with `service_statuses` instead.\n"}}},"ContainerStatusEntry":{"type":"object","required":["container_slug","status"],"properties":{"container_slug":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ServiceSummary object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceSummary":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ContainerStatusEntry object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ContainerStatusEntry":{"type":"object","required":["container_slug","status"],"properties":{"container_slug":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The Container object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"Container":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"slug":{"type":"string","readOnly":true},"name":{"type":"string"},"services":{"type":"array","readOnly":true,"items":{"$ref":"#/components/schemas/ServiceSummary"},"description":"Services included in this container, ordered by display order. Global Services never appear here — they have no container dimension.\n"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}},"ServiceSummary":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ContainerCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ContainerCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string","description":"Optional URL-safe identifier. If omitted, it is auto-generated from `name`.\nIf a non-unique value is provided, a numeric suffix is appended (e.g. `eu-1`).\n"},"services":{"type":"array","items":{"type":"string"},"description":"Slugs of the services to include in this container.\nA container must contain at least one service — an empty array, or a default that would resolve to none, returns 422. An unknown slug returns 422.\nDefaults to every container-scoped service on the status page. Listing a Global Service converts it to a Container Service scoped to this container.\n"}},"description":"Service membership is explicit. It can be set here, or from the service side via `scope` and `containers` on the service resource.\nPer-container service status is not set here — it is updated via notice updates or the operational dashboard.\n"}}}}
```

## The ContainerUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ContainerUpdate":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"services":{"type":"array","items":{"type":"string"},"description":"Replaces the container's entire service membership. Services omitted from the list are excluded from this container.\nA container must keep at least one service — an empty array returns 422. Delete the container instead. An unknown slug returns 422.\nA Container Service left in zero containers as a result automatically becomes a Global Service (`scope: global`). Listing a Global Service converts it to a Container Service scoped to this container.\n"}}}}}}
```

## The ServiceGroup object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceGroup":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"slug":{"type":"string","readOnly":true},"name":{"type":"string"},"scope":{"type":"string","readOnly":true,"enum":["global","containers"],"description":"Which kind of service this group holds. Every member shares it: a group never mixes Global and Container Services.\nRead from the group's members while it has any. An empty group reports the kind it was created for, and a service moved into it on its own has to be of that kind. Move a whole group between scopes by writing `containers` on the group, which re-scopes every member at once.\n"},"order":{"type":["integer","null"],"description":"Display position on the status page. Groups and ungrouped services share one sequence, so a group and a service never need to be compared across two scales — sort both by `order`. `null` when the group was created without one; it then follows every positioned group and service, by name.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"readOnly":true,"description":"Worst-case status across the group's current members, for rendering a collapsed group. Derived per response and never stored: a group has no status of its own. `ok` when the group is empty.\n"},"services":{"type":"array","readOnly":true,"items":{"type":"string"},"description":"Slugs of the services in this group, in display order. Empty for a group that has no services yet.\n"},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}}}}}
```

## The ServiceGroupCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceGroupCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255,"description":"Unique within the status page, case-insensitively."},"slug":{"type":"string","description":"Optional URL-safe identifier. If omitted, it is auto-generated from `name`. If a non-unique value is provided, a numeric suffix is appended (e.g. `it-services-1`).\n"},"services":{"type":"array","items":{"type":"string"},"description":"The services to put in this group, by slug. Optional: omit it, or send an empty array, to create an empty group, which holds Container Services when the page has containers and Global Services otherwise. An unknown slug returns 422.\nEvery listed service must share one scope: all Global or all Container-scoped. Mixing them returns 422. The group's own `scope` is read back from them. A service already in another group is moved into this one.\n"},"order":{"type":"integer","description":"Optional display position. Omitted groups sort after positioned ones.\n"}}}}}}
```

## The ServiceGroupUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceGroupUpdate":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"slug":{"type":"string"},"order":{"type":"integer"},"services":{"type":"array","items":{"type":"string"},"description":"Replaces the group's entire membership. Services omitted from the list become ungrouped.\nA group may be left with no services — an empty array empties it without deleting it. An unknown slug returns 422, as does a list mixing Global and Container-scoped services.\n"},"containers":{"type":"array","items":{"type":"string"},"description":"Re-scopes every service in the group at once, by slug, exactly as writing `containers` on each member would. Passing an empty array makes the whole group Global; passing one or more containers makes it a Container Group. An unknown slug returns 422.\nThis is how a group moves between scopes — the equivalent of dragging it from one section to the other. Member statuses are preserved across the change under the same rules as a single service: a Global-to-Container switch seeds every newly-included container with the service's current status, and the reverse keeps the worst-case of the discarded per-container statuses.\n"}}}}}}
```

## The Notice object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"Notice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"notice_type":{"type":"string","enum":["incident","maintenance","info"]},"title":{"type":"string"},"status":{"type":"string","description":"Valid values by `notice_type`:\n- **incident**: `investigating` · `identified` · `monitoring` · `resolved`\n- **maintenance**: `scheduled` · `in_progress` · `verifying` · `completed`\n- **info**: `info`\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"lifecycle":{"type":"string","enum":["pending","active","completed"],"readOnly":true},"published":{"type":["boolean","null"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"},"latest_update":{"allOf":[{"$ref":"#/components/schemas/NoticeUpdateObject"}]},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}},"NoticeUpdateObject":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"status":{"type":"string","description":"The notice status at the time of this update"},"body":{"type":"string","description":"HTML content of the update"},"posted_at":{"type":"string","format":"date-time"},"service_statuses":{"type":"array","description":"The service statuses that were set as part of this timeline entry.","items":{"type":"object","properties":{"service_slug":{"type":"string"},"service_name":{"type":"string"},"container_slug":{"type":["string","null"],"description":"Null for a Global Service."},"container_name":{"type":["string","null"],"description":"Null for a Global Service."},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}}}}
```

## The NoticeDetail object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeDetail":{"allOf":[{"$ref":"#/components/schemas/Notice"},{"type":"object","properties":{"updates":{"type":"array","items":{"$ref":"#/components/schemas/NoticeUpdateObject"},"description":"Full timeline, ordered newest-first"}}}]},"Notice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"notice_type":{"type":"string","enum":["incident","maintenance","info"]},"title":{"type":"string"},"status":{"type":"string","description":"Valid values by `notice_type`:\n- **incident**: `investigating` · `identified` · `monitoring` · `resolved`\n- **maintenance**: `scheduled` · `in_progress` · `verifying` · `completed`\n- **info**: `info`\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"lifecycle":{"type":"string","enum":["pending","active","completed"],"readOnly":true},"published":{"type":["boolean","null"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"},"latest_update":{"allOf":[{"$ref":"#/components/schemas/NoticeUpdateObject"}]},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}},"NoticeUpdateObject":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"status":{"type":"string","description":"The notice status at the time of this update"},"body":{"type":"string","description":"HTML content of the update"},"posted_at":{"type":"string","format":"date-time"},"service_statuses":{"type":"array","description":"The service statuses that were set as part of this timeline entry.","items":{"type":"object","properties":{"service_slug":{"type":"string"},"service_name":{"type":"string"},"container_slug":{"type":["string","null"],"description":"Null for a Global Service."},"container_name":{"type":["string","null"],"description":"Null for a Global Service."},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}}}}
```

## The NoticeCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeCreate":{"type":"object","required":["notice_type","title"],"properties":{"notice_type":{"type":"string","enum":["incident","maintenance","info"]},"title":{"type":"string","maxLength":255},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean","default":false},"starts_at":{"type":"string","format":"date-time","description":"Required for `incident` and `maintenance` types."},"ends_at":{"type":["string","null"],"format":"date-time"},"initial_update":{"description":"Optional first timeline entry created atomically with the notice.\nRecommended for incidents and maintenance windows.\n","allOf":[{"$ref":"#/components/schemas/NoticeUpdateCreate"}]}}},"NoticeUpdateCreate":{"type":"object","required":["body"],"properties":{"status":{"type":"string","description":"Transitions the notice to this status. Defaults to the current notice status\n(i.e. adds an update without changing status).\n"},"body":{"type":"string","description":"HTML or plain-text content for the update.","maxLength":10000},"posted_at":{"type":"string","format":"date-time","description":"Defaults to current time."},"notify":{"type":"boolean","default":true,"description":"Whether to send email/Slack notifications for this update."},"service_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ServiceStatus"},"description":"Sets the live status of one or more services on the status page. Omit to leave\nall service statuses unchanged.\n"}}},"ServiceStatus":{"type":"object","required":["service_slug","status"],"description":"Sets the status of a service. Scoped to a container for a Container Service; unscoped for a Global Service.\n","properties":{"service_slug":{"type":"string"},"container_slug":{"type":"string","description":"Which container to target.\nOmit for a Global Service — it has a single status and no container dimension. Supplying it for a Global Service returns 422.\nFor a Container Service, name the container to target. Supplying a container the service is excluded from, or an unknown slug, returns 422.\n**Deprecated fallback:** omitting it for a Container Service resolves to that service's first container. Retained for backwards compatibility; name the container explicitly instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The NoticePatch object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticePatch":{"type":"object","description":"Edits notice metadata only. Use the Notice Updates resource to change status.","properties":{"title":{"type":"string","maxLength":255},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The NoticeUpdateObject object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdateObject":{"type":"object","properties":{"id":{"type":"string","format":"uuid","readOnly":true},"status":{"type":"string","description":"The notice status at the time of this update"},"body":{"type":"string","description":"HTML content of the update"},"posted_at":{"type":"string","format":"date-time"},"service_statuses":{"type":"array","description":"The service statuses that were set as part of this timeline entry.","items":{"type":"object","properties":{"service_slug":{"type":"string"},"service_name":{"type":"string"},"container_slug":{"type":["string","null"],"description":"Null for a Global Service."},"container_name":{"type":["string","null"],"description":"Null for a Global Service."},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}}}}
```

## The ServiceStatus object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceStatus":{"type":"object","required":["service_slug","status"],"description":"Sets the status of a service. Scoped to a container for a Container Service; unscoped for a Global Service.\n","properties":{"service_slug":{"type":"string"},"container_slug":{"type":"string","description":"Which container to target.\nOmit for a Global Service — it has a single status and no container dimension. Supplying it for a Global Service returns 422.\nFor a Container Service, name the container to target. Supplying a container the service is excluded from, or an unknown slug, returns 422.\n**Deprecated fallback:** omitting it for a Container Service resolves to that service's first container. Retained for backwards compatibility; name the container explicitly instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The NoticeUpdateCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdateCreate":{"type":"object","required":["body"],"properties":{"status":{"type":"string","description":"Transitions the notice to this status. Defaults to the current notice status\n(i.e. adds an update without changing status).\n"},"body":{"type":"string","description":"HTML or plain-text content for the update.","maxLength":10000},"posted_at":{"type":"string","format":"date-time","description":"Defaults to current time."},"notify":{"type":"boolean","default":true,"description":"Whether to send email/Slack notifications for this update."},"service_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ServiceStatus"},"description":"Sets the live status of one or more services on the status page. Omit to leave\nall service statuses unchanged.\n"}}},"ServiceStatus":{"type":"object","required":["service_slug","status"],"description":"Sets the status of a service. Scoped to a container for a Container Service; unscoped for a Global Service.\n","properties":{"service_slug":{"type":"string"},"container_slug":{"type":"string","description":"Which container to target.\nOmit for a Global Service — it has a single status and no container dimension. Supplying it for a Global Service returns 422.\nFor a Container Service, name the container to target. Supplying a container the service is excluded from, or an unknown slug, returns 422.\n**Deprecated fallback:** omitting it for a Container Service resolves to that service's first container. Retained for backwards compatibility; name the container explicitly instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The NoticeUpdateEdit object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdateEdit":{"type":"object","properties":{"status":{"type":"string"},"body":{"type":"string","maxLength":10000},"posted_at":{"type":"string","format":"date-time"},"notify":{"type":"boolean"},"service_statuses":{"type":"array","items":{"$ref":"#/components/schemas/ServiceStatus"},"description":"Replaces the service statuses recorded for this timeline entry."}}},"ServiceStatus":{"type":"object","required":["service_slug","status"],"description":"Sets the status of a service. Scoped to a container for a Container Service; unscoped for a Global Service.\n","properties":{"service_slug":{"type":"string"},"container_slug":{"type":"string","description":"Which container to target.\nOmit for a Global Service — it has a single status and no container dimension. Supplying it for a Global Service returns 422.\nFor a Container Service, name the container to target. Supplying a container the service is excluded from, or an unknown slug, returns 422.\n**Deprecated fallback:** omitting it for a Container Service resolves to that service's first container. Retained for backwards compatibility; name the container explicitly instead.\n"},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The OutgoingWebhook object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"OutgoingWebhook":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"description":"TypeID-prefixed identifier (e.g. `wbk_01h2x...`)"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"HTTPS URL that will receive `POST` deliveries."},"events":{"type":"array","items":{"type":"string","enum":["service.status_changed","notice.created","notice.update_posted","notice.updated"]}},"enabled":{"type":"boolean","default":true},"all_status_pages":{"type":"boolean","default":true,"description":"When `true`, the webhook fires for events on every status page in\nthe organization, including pages created later. When `false`, only\nevents on pages listed in `status_page_subdomains` fire.\n"},"status_page_subdomains":{"type":"array","items":{"type":"string"},"description":"Only present when `all_status_pages` is `false`. Subdomains of the\nspecific status pages this webhook is scoped to.\n"},"last_triggered_at":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp of the most recent **successful** delivery."},"last_attempted_at":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp of the most recent delivery attempt (success or failure)."},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}}}}}
```

## The OutgoingWebhookWithSecret object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"OutgoingWebhookWithSecret":{"allOf":[{"$ref":"#/components/schemas/OutgoingWebhook"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","description":"Plaintext signing secret (`whs_…`). Returned **only** in responses\nto create and regenerate_secret. Store it immediately — it is not\nretrievable later.\n"}}}]},"OutgoingWebhook":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"description":"TypeID-prefixed identifier (e.g. `wbk_01h2x...`)"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"HTTPS URL that will receive `POST` deliveries."},"events":{"type":"array","items":{"type":"string","enum":["service.status_changed","notice.created","notice.update_posted","notice.updated"]}},"enabled":{"type":"boolean","default":true},"all_status_pages":{"type":"boolean","default":true,"description":"When `true`, the webhook fires for events on every status page in\nthe organization, including pages created later. When `false`, only\nevents on pages listed in `status_page_subdomains` fire.\n"},"status_page_subdomains":{"type":"array","items":{"type":"string"},"description":"Only present when `all_status_pages` is `false`. Subdomains of the\nspecific status pages this webhook is scoped to.\n"},"last_triggered_at":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp of the most recent **successful** delivery."},"last_attempted_at":{"type":["string","null"],"format":"date-time","readOnly":true,"description":"Timestamp of the most recent delivery attempt (success or failure)."},"created_at":{"type":"string","format":"date-time","readOnly":true},"updated_at":{"type":"string","format":"date-time","readOnly":true}}}}}}
```

## The OutgoingWebhookCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"OutgoingWebhookCreate":{"type":"object","required":["name","url","events"],"properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["service.status_changed","notice.created","notice.update_posted","notice.updated"]}},"enabled":{"type":"boolean","default":true},"all_status_pages":{"type":"boolean","default":true},"status_page_subdomains":{"type":"array","description":"Required when `all_status_pages` is `false`. Subdomains of the\nstatus pages this webhook should fire for. Unknown subdomains\ncause a `422`.\n","items":{"type":"string"}}}}}}}
```

## The OutgoingWebhookUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"OutgoingWebhookUpdate":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["service.status_changed","notice.created","notice.update_posted","notice.updated"]}},"enabled":{"type":"boolean"},"all_status_pages":{"type":"boolean"},"status_page_subdomains":{"type":"array","items":{"type":"string"}}}}}}}
```

## The WebhookEventStatusPage object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}}}}}
```

## The WebhookEnvelope object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookEnvelope":{"type":"object","description":"Shared envelope for every outbound webhook event. Concrete events extend this via `allOf` and pin `event` / `data` to their specific shapes.","required":["event","occurred_at","status_page","data"],"properties":{"event":{"type":"string","description":"The event name. Always matches the `X-StatusPal-Event` header."},"occurred_at":{"type":"string","format":"date-time","description":"ISO-8601 timestamp of when the event was emitted (not when it was delivered)."},"status_page":{"$ref":"#/components/schemas/WebhookEventStatusPage"},"data":{"type":"object","description":"Event-specific payload — see per-event schemas."}}},"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}}}}}
```

## The ServiceStatusChangedData object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceStatusChangedData":{"type":"object","required":["service","container","old_status","new_status"],"properties":{"service":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","description":"Unique slug for the service within its status page."},"name":{"type":"string"}}},"container":{"type":["object","null"],"description":"The container whose status changed. Null for a Global Service, which has no container dimension. The key is always present.\n","required":["slug","name"],"properties":{"slug":{"type":"string","description":"Unique slug for the container within its status page."},"name":{"type":"string"}}},"old_status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]},"new_status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The ServiceStatusChangedEvent object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"ServiceStatusChangedEvent":{"description":"Emitted when a `ContainerService.status` transitions to a different value. Naturally rate-limited — same-value updates do not fire this event.","allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","required":["event","data"],"properties":{"event":{"type":"string","enum":["service.status_changed"]},"data":{"$ref":"#/components/schemas/ServiceStatusChangedData"}}}]},"WebhookEnvelope":{"type":"object","description":"Shared envelope for every outbound webhook event. Concrete events extend this via `allOf` and pin `event` / `data` to their specific shapes.","required":["event","occurred_at","status_page","data"],"properties":{"event":{"type":"string","description":"The event name. Always matches the `X-StatusPal-Event` header."},"occurred_at":{"type":"string","format":"date-time","description":"ISO-8601 timestamp of when the event was emitted (not when it was delivered)."},"status_page":{"$ref":"#/components/schemas/WebhookEventStatusPage"},"data":{"type":"object","description":"Event-specific payload — see per-event schemas."}}},"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}},"ServiceStatusChangedData":{"type":"object","required":["service","container","old_status","new_status"],"properties":{"service":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string","description":"Unique slug for the service within its status page."},"name":{"type":"string"}}},"container":{"type":["object","null"],"description":"The container whose status changed. Null for a Global Service, which has no container dimension. The key is always present.\n","required":["slug","name"],"properties":{"slug":{"type":"string","description":"Unique slug for the container within its status page."},"name":{"type":"string"}}},"old_status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]},"new_status":{"type":"string","enum":["ok","minor","major","critical","maintenance"]}}}}}}
```

## The WebhookNotice object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookNotice":{"type":"object","description":"Full notice shape, used in `notice.created` events.","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string","description":"One of the allowed statuses for the notice's type. Incidents:\n`investigating`, `identified`, `monitoring`, `resolved`. Planned\nmaintenance: `scheduled`, `in_progress`, `verifying`, `completed`.\nEssential maintenance: `in_progress`, `verifying`, `completed`.\nInfo notices: `info`.\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"retroactive":{"type":"boolean"},"lifecycle":{"type":["string","null"],"enum":["active","pending","completed"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The NoticeCreatedData object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeCreatedData":{"type":"object","required":["notice"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNotice"}}},"WebhookNotice":{"type":"object","description":"Full notice shape, used in `notice.created` events.","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string","description":"One of the allowed statuses for the notice's type. Incidents:\n`investigating`, `identified`, `monitoring`, `resolved`. Planned\nmaintenance: `scheduled`, `in_progress`, `verifying`, `completed`.\nEssential maintenance: `in_progress`, `verifying`, `completed`.\nInfo notices: `info`.\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"retroactive":{"type":"boolean"},"lifecycle":{"type":["string","null"],"enum":["active","pending","completed"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The NoticeCreatedEvent object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeCreatedEvent":{"description":"Emitted whenever a new notice is created — including draft, scheduled, and retroactive notices. Filter on `data.notice.published` / `retroactive` / `type` if you only want a subset.","allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","required":["event","data"],"properties":{"event":{"type":"string","enum":["notice.created"]},"data":{"$ref":"#/components/schemas/NoticeCreatedData"}}}]},"WebhookEnvelope":{"type":"object","description":"Shared envelope for every outbound webhook event. Concrete events extend this via `allOf` and pin `event` / `data` to their specific shapes.","required":["event","occurred_at","status_page","data"],"properties":{"event":{"type":"string","description":"The event name. Always matches the `X-StatusPal-Event` header."},"occurred_at":{"type":"string","format":"date-time","description":"ISO-8601 timestamp of when the event was emitted (not when it was delivered)."},"status_page":{"$ref":"#/components/schemas/WebhookEventStatusPage"},"data":{"type":"object","description":"Event-specific payload — see per-event schemas."}}},"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}},"NoticeCreatedData":{"type":"object","required":["notice"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNotice"}}},"WebhookNotice":{"type":"object","description":"Full notice shape, used in `notice.created` events.","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string","description":"One of the allowed statuses for the notice's type. Incidents:\n`investigating`, `identified`, `monitoring`, `resolved`. Planned\nmaintenance: `scheduled`, `in_progress`, `verifying`, `completed`.\nEssential maintenance: `in_progress`, `verifying`, `completed`.\nInfo notices: `info`.\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"retroactive":{"type":"boolean"},"lifecycle":{"type":["string","null"],"enum":["active","pending","completed"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The WebhookNoticeSummary object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookNoticeSummary":{"type":"object","description":"Trimmed notice shape used inside `notice.update_posted` events (only the fields needed to identify the parent notice).","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string"}}}}}}
```

## The WebhookNoticeUpdate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookNoticeUpdate":{"type":"object","required":["id","body","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `upd_`"},"body":{"type":"string","description":"HTML body of the update. Receivers should sanitize before rendering. Plaintext is **not** included."},"status":{"type":"string","description":"Same enum semantics as `WebhookNotice.status`, plus `update` (a comment-only update that does not change the parent notice's status)."},"posted_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The WebhookNoticeUpdateServiceStatus object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"WebhookNoticeUpdateServiceStatus":{"type":"object","description":"One container-service status change carried by a `notice.update_posted` event.","required":["service","container","status"],"properties":{"service":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"container":{"type":["object","null"],"description":"The container whose status was set. Null for a Global Service. The key is always present.\n","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"The new status the service was set to as part of this update."}}}}}}
```

## The NoticeUpdatePostedData object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdatePostedData":{"type":"object","required":["notice","update","service_statuses"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNoticeSummary"},"update":{"$ref":"#/components/schemas/WebhookNoticeUpdate"},"service_statuses":{"type":"array","description":"Container-service status changes that were carried by this notice update. Empty when\nthe update was status-only / a comment / a maintenance update that left services as\n\"operational\". Receivers wanting old→new status pairs can correlate with parallel\n`service.status_changed` events sharing the same `occurred_at`.\n","items":{"$ref":"#/components/schemas/WebhookNoticeUpdateServiceStatus"}}}},"WebhookNoticeSummary":{"type":"object","description":"Trimmed notice shape used inside `notice.update_posted` events (only the fields needed to identify the parent notice).","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string"}}},"WebhookNoticeUpdate":{"type":"object","required":["id","body","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `upd_`"},"body":{"type":"string","description":"HTML body of the update. Receivers should sanitize before rendering. Plaintext is **not** included."},"status":{"type":"string","description":"Same enum semantics as `WebhookNotice.status`, plus `update` (a comment-only update that does not change the parent notice's status)."},"posted_at":{"type":["string","null"],"format":"date-time"}}},"WebhookNoticeUpdateServiceStatus":{"type":"object","description":"One container-service status change carried by a `notice.update_posted` event.","required":["service","container","status"],"properties":{"service":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"container":{"type":["object","null"],"description":"The container whose status was set. Null for a Global Service. The key is always present.\n","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"The new status the service was set to as part of this update."}}}}}}
```

## The NoticeUpdatePostedEvent object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdatePostedEvent":{"description":"Emitted when a new timeline entry is posted to an existing notice.","allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","required":["event","data"],"properties":{"event":{"type":"string","enum":["notice.update_posted"]},"data":{"$ref":"#/components/schemas/NoticeUpdatePostedData"}}}]},"WebhookEnvelope":{"type":"object","description":"Shared envelope for every outbound webhook event. Concrete events extend this via `allOf` and pin `event` / `data` to their specific shapes.","required":["event","occurred_at","status_page","data"],"properties":{"event":{"type":"string","description":"The event name. Always matches the `X-StatusPal-Event` header."},"occurred_at":{"type":"string","format":"date-time","description":"ISO-8601 timestamp of when the event was emitted (not when it was delivered)."},"status_page":{"$ref":"#/components/schemas/WebhookEventStatusPage"},"data":{"type":"object","description":"Event-specific payload — see per-event schemas."}}},"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}},"NoticeUpdatePostedData":{"type":"object","required":["notice","update","service_statuses"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNoticeSummary"},"update":{"$ref":"#/components/schemas/WebhookNoticeUpdate"},"service_statuses":{"type":"array","description":"Container-service status changes that were carried by this notice update. Empty when\nthe update was status-only / a comment / a maintenance update that left services as\n\"operational\". Receivers wanting old→new status pairs can correlate with parallel\n`service.status_changed` events sharing the same `occurred_at`.\n","items":{"$ref":"#/components/schemas/WebhookNoticeUpdateServiceStatus"}}}},"WebhookNoticeSummary":{"type":"object","description":"Trimmed notice shape used inside `notice.update_posted` events (only the fields needed to identify the parent notice).","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string"}}},"WebhookNoticeUpdate":{"type":"object","required":["id","body","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `upd_`"},"body":{"type":"string","description":"HTML body of the update. Receivers should sanitize before rendering. Plaintext is **not** included."},"status":{"type":"string","description":"Same enum semantics as `WebhookNotice.status`, plus `update` (a comment-only update that does not change the parent notice's status)."},"posted_at":{"type":["string","null"],"format":"date-time"}}},"WebhookNoticeUpdateServiceStatus":{"type":"object","description":"One container-service status change carried by a `notice.update_posted` event.","required":["service","container","status"],"properties":{"service":{"type":"object","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"container":{"type":["object","null"],"description":"The container whose status was set. Null for a Global Service. The key is always present.\n","required":["slug","name"],"properties":{"slug":{"type":"string"},"name":{"type":"string"}}},"status":{"type":"string","enum":["ok","minor","major","critical","maintenance"],"description":"The new status the service was set to as part of this update."}}}}}}
```

## The NoticeUpdatedData object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdatedData":{"type":"object","required":["notice","changes"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNotice"},"changes":{"type":"object","description":"Map of changed field name → `[old_value, new_value]`. Only fields in the server-side\ntracked-fields list appear here. Datetime fields are ISO-8601 strings; other fields\nkeep their native JSON type.\n","additionalProperties":{"type":"array","minItems":2,"maxItems":2,"items":{}}}}},"WebhookNotice":{"type":"object","description":"Full notice shape, used in `notice.created` events.","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string","description":"One of the allowed statuses for the notice's type. Incidents:\n`investigating`, `identified`, `monitoring`, `resolved`. Planned\nmaintenance: `scheduled`, `in_progress`, `verifying`, `completed`.\nEssential maintenance: `in_progress`, `verifying`, `completed`.\nInfo notices: `info`.\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"retroactive":{"type":"boolean"},"lifecycle":{"type":["string","null"],"enum":["active","pending","completed"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The NoticeUpdatedEvent object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"NoticeUpdatedEvent":{"description":"Emitted when an existing notice's tracked fields change (status, title, severity, etc.) —\neither directly via the management API or as a side-effect of a timeline update flipping\nthe parent notice's status. In the latter case, both `notice.update_posted` and\n`notice.updated` fire.\n","allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","required":["event","data"],"properties":{"event":{"type":"string","enum":["notice.updated"]},"data":{"$ref":"#/components/schemas/NoticeUpdatedData"}}}]},"WebhookEnvelope":{"type":"object","description":"Shared envelope for every outbound webhook event. Concrete events extend this via `allOf` and pin `event` / `data` to their specific shapes.","required":["event","occurred_at","status_page","data"],"properties":{"event":{"type":"string","description":"The event name. Always matches the `X-StatusPal-Event` header."},"occurred_at":{"type":"string","format":"date-time","description":"ISO-8601 timestamp of when the event was emitted (not when it was delivered)."},"status_page":{"$ref":"#/components/schemas/WebhookEventStatusPage"},"data":{"type":"object","description":"Event-specific payload — see per-event schemas."}}},"WebhookEventStatusPage":{"type":"object","description":"The status page on which the event occurred (embedded in every event envelope). The\n`subdomain` is the public identifier — use it to look up the page via the management API.\n","required":["subdomain","name","url"],"properties":{"subdomain":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri","description":"Canonical public URL of the status page (custom domain when configured, otherwise the `*.statuspal.io` subdomain)."}}},"NoticeUpdatedData":{"type":"object","required":["notice","changes"],"properties":{"notice":{"$ref":"#/components/schemas/WebhookNotice"},"changes":{"type":"object","description":"Map of changed field name → `[old_value, new_value]`. Only fields in the server-side\ntracked-fields list appear here. Datetime fields are ISO-8601 strings; other fields\nkeep their native JSON type.\n","additionalProperties":{"type":"array","minItems":2,"maxItems":2,"items":{}}}}},"WebhookNotice":{"type":"object","description":"Full notice shape, used in `notice.created` events.","required":["id","title","type","status"],"properties":{"id":{"type":"string","description":"TypeID, prefix `ntc_`"},"title":{"type":"string"},"type":{"type":"string","enum":["incident","maintenance","info"]},"status":{"type":"string","description":"One of the allowed statuses for the notice's type. Incidents:\n`investigating`, `identified`, `monitoring`, `resolved`. Planned\nmaintenance: `scheduled`, `in_progress`, `verifying`, `completed`.\nEssential maintenance: `in_progress`, `verifying`, `completed`.\nInfo notices: `info`.\n"},"severity":{"type":["string","null"],"enum":["major","minor"]},"published":{"type":"boolean"},"retroactive":{"type":"boolean"},"lifecycle":{"type":["string","null"],"enum":["active","pending","completed"]},"starts_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time"}}}}}}
```

## The PaginationMeta object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"PaginationMeta":{"type":"object","properties":{"current_page":{"type":"integer"},"per_page":{"type":"integer"},"total_count":{"type":"integer"},"total_pages":{"type":"integer"}}}}}}
```

## The Error object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}}}}}
```

## The SignupCreate object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"SignupCreate":{"type":"object","required":["email","org_name","first_name","last_name"],"properties":{"email":{"type":"string","format":"email","description":"Admin user's email. Must be a custom-domain address — free providers (gmail.com, yahoo.com, outlook.com, …) are rejected."},"org_name":{"type":"string","description":"Name of the organization to create."},"first_name":{"type":"string"},"last_name":{"type":"string"}}}}}}
```

## The Signup object

```json
{"openapi":"3.1.0","info":{"title":"StatusPal Public API","version":"1"},"components":{"schemas":{"Signup":{"type":"object","properties":{"status":{"type":"string","enum":["pending_activation","active"],"description":"`pending_activation` until an administrator activates the account; the `api_key` only works once the account is active."},"api_key":{"type":"string","description":"Bearer token for the new organization. Returned once — store it securely."},"organization":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}}}}
```
