openapi: 3.1.0
info:
  title: StatusPal Public API
  description: >
    Programmatically manage your StatusPal status pages, notices, services, and
    containers.


    ## Authentication


    Every request must include an organization API key in the `Authorization`
    header:


    ```

    Authorization: Bearer {your_api_key}

    ```


    API keys are scoped to an organization and are currently issued via the
    Rails console (management UI coming soon).

    All resources returned are automatically scoped to the key's organization.
  version: '1'
  contact:
    email: support@statuspal.io
  x-gitbook-description-document:
    object: document
    data:
      schemaVersion: 9
    nodes:
      - object: block
        type: paragraph
        isVoid: false
        data: {}
        nodes:
          - object: text
            leaves:
              - object: leaf
                text: >-
                  Programmatically manage your StatusPal status pages, notices,
                  services, and containers.
                marks: []
            key: 5lTUcigQGDkp
        key: yY8ssi3gJoN7
      - object: block
        type: heading-2
        isVoid: false
        data: {}
        nodes:
          - object: text
            leaves:
              - object: leaf
                text: Authentication
                marks: []
            key: zRdlMdA3F0hA
        key: BxD3wlLusyWt
      - object: block
        type: paragraph
        isVoid: false
        data: {}
        nodes:
          - object: text
            leaves:
              - object: leaf
                text: 'Every request must include an organization API key in the '
                marks: []
              - object: leaf
                text: Authorization
                marks:
                  - object: mark
                    type: code
                    data: {}
              - object: leaf
                text: ' header:'
                marks: []
            key: ZmizQnH5CzIX
        key: jGwzqs5hq2sc
      - object: block
        type: code
        isVoid: false
        data: {}
        nodes:
          - object: block
            type: code-line
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: 'Authorization: Bearer {your_api_key}'
                    marks: []
                key: sLxdzetOheXt
            key: 3g5yirJyEIV6
        key: V1cyRVSuSbK6
      - object: block
        type: paragraph
        isVoid: false
        data: {}
        nodes:
          - object: text
            leaves:
              - object: leaf
                text: >-
                  API keys are scoped to an organization and are currently
                  issued via the Rails console (management UI coming soon). All
                  resources returned are automatically scoped to the key's
                  organization.
                marks: []
            key: aTYet6mCcUn6
        key: uIT0CodtnYmj
    key: 5QSRNtgC8wzu
  x-gitbook-description-html: >-
    <p>Programmatically manage your StatusPal status pages, notices, services,
    and containers.</p><h2>Authentication</h2><p>Every request must include an
    organization API key in the <code>Authorization</code>
    header:</p><pre><code>Authorization: Bearer {your_api_key}

    </code></pre><p>API keys are scoped to an organization and are currently
    issued via the Rails console (management UI coming soon). All resources
    returned are automatically scoped to the key's organization.</p>
servers:
  - url: https://next.statuspal.io/api/v1
    description: Production
    x-gitbook-description-html: <p>Production</p>
  - url: http://spage.test:7070/api/v1
    description: Local development
    x-gitbook-description-html: <p>Local development</p>
tags:
  - name: Signup
    description: Create a new account and obtain an API key (public, no key required)
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: >-
                    Create a new account and obtain an API key (public, no key
                    required)
                  marks: []
              key: dtao2aUzx9i4
          key: NK48YtaVvqii
      key: JYjIonI0RNeU
    x-gitbook-description-html: >-
      <p>Create a new account and obtain an API key (public, no key
      required)</p>
  - name: Status Pages
    description: Manage status pages within your organization
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Manage status pages within your organization
                  marks: []
              key: pefdUOQntDkL
          key: CWTfFX4LRcgb
      key: nAZomeIQ4yt4
    x-gitbook-description-html: <p>Manage status pages within your organization</p>
  - name: Services
    description: Manage services displayed on a status page
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Manage services displayed on a status page
                  marks: []
              key: hIWBkKaPpMRs
          key: t7swWAUMetQm
      key: 7stsE7Xsh4nl
    x-gitbook-description-html: <p>Manage services displayed on a status page</p>
  - name: Containers
    description: Manage service groups (containers) on a status page
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Manage service groups (containers) on a status page
                  marks: []
              key: gQ3d7M6CcSfM
          key: 60JeBmy9kCbw
      key: UH50p11FcJtz
    x-gitbook-description-html: <p>Manage service groups (containers) on a status page</p>
  - name: Notices
    description: Manage incidents, maintenance events, and info notices
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Manage incidents, maintenance events, and info notices
                  marks: []
              key: mUHoUqZ5MqYz
          key: e2KdqPslyxXh
      key: JSpFZ9AZw0IG
    x-gitbook-description-html: <p>Manage incidents, maintenance events, and info notices</p>
  - name: Notice Updates
    description: Manage timeline entries for a notice
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Manage timeline entries for a notice
                  marks: []
              key: wYGtm8CxWXaG
          key: bAjehLTrSv0Z
      key: DrCVeIvDMJyD
    x-gitbook-description-html: <p>Manage timeline entries for a notice</p>
  - name: Outgoing Webhooks
    description: >
      Manage outgoing webhook subscriptions for organization events.


      ## Webhook signing


      When an event fires, StatusPal POSTs a JSON payload to your configured
      `outgoing_webhook.url`. Every

      delivery carries the following headers:


      | Header | Value |

      |---|---|

      | `Content-Type` | `application/json` |

      | `User-Agent` | `StatusPal-Webhooks/1.0` |

      | `X-StatusPal-Event` | The event name (`service.status_changed`,
      `notice.created`, or `notice.updated`) |

      | `X-StatusPal-Delivery` | A per-attempt UUID, use it to dedupe retried
      deliveries |

      | `X-StatusPal-Signature` | Stripe-style signature:
      `t=<unix_ts>,v1=<hex_hmac>` |


      The signature covers `"#{t}.#{raw_body}"`, signed with HMAC-SHA256 using
      the webhook's plaintext

      signing secret (the `whs_…` value returned **once** when the webhook was
      created or its secret

      was rotated). Verify it like this:


      ```

      parsed = parse_header("X-StatusPal-Signature")  # → { t: <int>, v1: <hex>
      }

      signed = `${parsed.t}.${raw_body}`

      digest = HMAC_SHA256(secret, signed)

      if (Date.now() / 1000 - parsed.t > 300) reject  # 5-minute tolerance
      recommended

      if (!constant_time_eq(digest, parsed.v1)) reject

      ```


      ## Delivery retries


      Each event is delivered up to **3 times** with exponential backoff: **1s,
      2s, 4s** between attempts.

      Any 2xx response is treated as success; any other status, a timeout (5s
      open / 10s read), or a network

      error triggers the next retry. After the third failure the delivery is
      dropped.
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: >-
                    Manage outgoing webhook subscriptions for organization
                    events.
                  marks: []
              key: fYNWfxd9S565
          key: Pwu7wao5i28X
        - object: block
          type: heading-2
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Webhook signing
                  marks: []
              key: ghMCt9d11vDV
          key: wk4HNBW7U0zU
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: >-
                    When an event fires, StatusPal POSTs a JSON payload to your
                    configured
                  marks: []
                - object: leaf
                  text: outgoing_webhook.url
                  marks:
                    - object: mark
                      type: code
                      data: {}
                - object: leaf
                  text: '. Every delivery carries the following headers:'
                  marks: []
              key: 1HoN9fqsFsUQ
          key: jgPPqJFlH7eT
        - object: block
          type: table
          isVoid: true
          data:
            records:
              wjbsbf5H4lHc:
                orderIndex: '0|hzzzmv:'
                values:
                  PD0R18JanLmw: QTvgqW1xWmqe
                  dOn8Z44DqdnK: 6dqPdh8CtuvJ
              4TiU3H5gWW6U:
                orderIndex: '0|hzzzyf:'
                values:
                  PD0R18JanLmw: fcoRxo7UCCkl
                  dOn8Z44DqdnK: wvsNev1OrmxU
              WPjIcz9WtQAG:
                orderIndex: '0|i0002f:'
                values:
                  PD0R18JanLmw: nRtcMN7yrqj5
                  dOn8Z44DqdnK: IYvxv4TwZQFP
              zbhVF6ssMUIW:
                orderIndex: '0|i000kn:'
                values:
                  PD0R18JanLmw: W3fPK2rCpSFa
                  dOn8Z44DqdnK: CbskjA4B2Sp5
              EMtJZcjewjS4:
                orderIndex: '0|i000lb:'
                values:
                  PD0R18JanLmw: OU5vouJXFwbw
                  dOn8Z44DqdnK: SkJ9JvWDVYIe
            definition:
              PD0R18JanLmw:
                id: PD0R18JanLmw
                title: Header
                type: text
                textAlignment: left
              dOn8Z44DqdnK:
                id: dOn8Z44DqdnK
                title: Value
                type: text
                textAlignment: left
            view:
              type: grid
              columns:
                - PD0R18JanLmw
                - dOn8Z44DqdnK
              useNewSizing: true
              hideHeader: false
              stickyHeader: false
              columnWidths: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: ''
                  marks: []
              key: g6C1Kg28riaM
          key: Y6eUizfmFnin
          fragments:
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: Content-Type
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: Rku1JB4tXmCZ
                  key: hlEGZbPas8HC
              key: V7eQWf6H39Qc
              fragment: QTvgqW1xWmqe
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: application/json
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: piv3BDVak0Rz
                  key: xTRHmTukzdQy
              key: 65MpAlmGl4bF
              fragment: 6dqPdh8CtuvJ
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: User-Agent
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: F8k3cewmWMGB
                  key: 9jpwmJujGwrB
              key: mxrTS3Mkiom3
              fragment: fcoRxo7UCCkl
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: StatusPal-Webhooks/1.0
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: IZgD1jwv0YQX
                  key: fTUTOdoaoApq
              key: FZQgXxIGtYbi
              fragment: wvsNev1OrmxU
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: X-StatusPal-Event
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: jNf60p73netm
                  key: ZNGkd3xPPQ7E
              key: G0yAVJaiDJmL
              fragment: nRtcMN7yrqj5
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: The event name (
                          marks: []
                        - object: leaf
                          text: service.status_changed
                          marks:
                            - object: mark
                              type: code
                              data: {}
                        - object: leaf
                          text: ', '
                          marks: []
                        - object: leaf
                          text: notice.created
                          marks:
                            - object: mark
                              type: code
                              data: {}
                        - object: leaf
                          text: ', or '
                          marks: []
                        - object: leaf
                          text: notice.updated
                          marks:
                            - object: mark
                              type: code
                              data: {}
                        - object: leaf
                          text: )
                          marks: []
                      key: 6N5EuDjqNpGo
                  key: uAcqMTmcy0FG
              key: 6lO3VdPd2GOP
              fragment: IYvxv4TwZQFP
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: X-StatusPal-Delivery
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: yN6qKosHAcOQ
                  key: 9YITa4yoYxZX
              key: 9Apzh2Bq8Xcz
              fragment: W3fPK2rCpSFa
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: >-
                            A per-attempt UUID, use it to dedupe retried
                            deliveries
                          marks: []
                      key: neT016jTCtJ0
                  key: N8kb9mFEIxUC
              key: I9TGgGZECGd5
              fragment: CbskjA4B2Sp5
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: X-StatusPal-Signature
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: AmeZ5CIh7rbg
                  key: 6dVGmWd5VM3K
              key: xfBtdqMA2FUE
              fragment: OU5vouJXFwbw
              type: table-cell
            - object: fragment
              nodes:
                - object: block
                  type: paragraph
                  isVoid: false
                  data: {}
                  nodes:
                    - object: text
                      leaves:
                        - object: leaf
                          text: 'Stripe-style signature: '
                          marks: []
                        - object: leaf
                          text: t=<unix_ts>,v1=<hex_hmac>
                          marks:
                            - object: mark
                              type: code
                              data: {}
                      key: fcLiS2fABdJS
                  key: 1N4ViTczWxO1
              key: IifkLcraNfjt
              fragment: SkJ9JvWDVYIe
              type: table-cell
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: 'The signature covers '
                  marks: []
                - object: leaf
                  text: '"#{t}.#{raw_body}"'
                  marks:
                    - object: mark
                      type: code
                      data: {}
                - object: leaf
                  text: >-
                    , signed with HMAC-SHA256 using the webhook's plaintext
                    signing secret (the
                  marks: []
                - object: leaf
                  text: whs_…
                  marks:
                    - object: mark
                      type: code
                      data: {}
                - object: leaf
                  text: ' value returned '
                  marks: []
                - object: leaf
                  text: once
                  marks:
                    - object: mark
                      type: bold
                      data: {}
                - object: leaf
                  text: ' when the webhook was created or its secret was rotated). Verify it like this:'
                  marks: []
              key: Cgxv77LmyKY1
          key: 6T3wvu4vAIrQ
        - object: block
          type: code
          isVoid: false
          data: {}
          nodes:
            - object: block
              type: code-line
              isVoid: false
              data: {}
              nodes:
                - object: text
                  leaves:
                    - object: leaf
                      text: >-
                        parsed = parse_header("X-StatusPal-Signature")  # → { t:
                        <int>, v1: <hex> }
                      marks: []
                  key: Uei0HlhZtiyI
              key: cnV9jmAMg2TG
            - object: block
              type: code-line
              isVoid: false
              data: {}
              nodes:
                - object: text
                  leaves:
                    - object: leaf
                      text: signed = `${parsed.t}.${raw_body}`
                      marks: []
                  key: Od3CJPchaeIx
              key: ckOVG0VR9v7s
            - object: block
              type: code-line
              isVoid: false
              data: {}
              nodes:
                - object: text
                  leaves:
                    - object: leaf
                      text: digest = HMAC_SHA256(secret, signed)
                      marks: []
                  key: JfC1JU2AL22V
              key: 1lMlSyTQ2Nyf
            - object: block
              type: code-line
              isVoid: false
              data: {}
              nodes:
                - object: text
                  leaves:
                    - object: leaf
                      text: >-
                        if (Date.now() / 1000 - parsed.t > 300) reject  #
                        5-minute tolerance recommended
                      marks: []
                  key: jyyessLhz4SS
              key: T5qY2zcbZchK
            - object: block
              type: code-line
              isVoid: false
              data: {}
              nodes:
                - object: text
                  leaves:
                    - object: leaf
                      text: if (!constant_time_eq(digest, parsed.v1)) reject
                      marks: []
                  key: 47omq9cqH6T0
              key: HU5NmV4e7Jjh
          key: BPNzBThy2ZCD
        - object: block
          type: heading-2
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: Delivery retries
                  marks: []
              key: 4H32d7WmhLR8
          key: VhmcwP8o9wpm
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: 'Each event is delivered up to '
                  marks: []
                - object: leaf
                  text: 3 times
                  marks:
                    - object: mark
                      type: bold
                      data: {}
                - object: leaf
                  text: ' with exponential backoff: '
                  marks: []
                - object: leaf
                  text: 1s, 2s, 4s
                  marks:
                    - object: mark
                      type: bold
                      data: {}
                - object: leaf
                  text: ' between attempts. Any 2xx response is treated as success; any other status, a timeout (5s open / 10s read), or a network error triggers the next retry. After the third failure the delivery is dropped.'
                  marks: []
              key: 5unx4AQVGSor
          key: xP193BEDF5I3
      key: ZablF1DvGuR2
    x-gitbook-description-html: >-
      <p>Manage outgoing webhook subscriptions for organization
      events.</p><h2>Webhook signing</h2><p>When an event fires, StatusPal POSTs
      a JSON payload to your configured <code>outgoing_webhook.url</code>. Every
      delivery carries the following
      headers:</p><table><thead><tr><th>Header</th><th>Value</th></tr></thead><tbody><tr><td><code>Content-Type</code></td><td><code>application/json</code></td></tr><tr><td><code>User-Agent</code></td><td><code>StatusPal-Webhooks/1.0</code></td></tr><tr><td><code>X-StatusPal-Event</code></td><td>The
      event name (<code>service.status_changed</code>,
      <code>notice.created</code>, or
      <code>notice.updated</code>)</td></tr><tr><td><code>X-StatusPal-Delivery</code></td><td>A
      per-attempt UUID, use it to dedupe retried
      deliveries</td></tr><tr><td><code>X-StatusPal-Signature</code></td><td>Stripe-style
      signature:
      <code>t=&#x3C;unix_ts>,v1=&#x3C;hex_hmac></code></td></tr></tbody></table><p>The
      signature covers <code>"#{t}.#{raw_body}"</code>, signed with HMAC-SHA256
      using the webhook's plaintext signing secret (the <code>whs_…</code> value
      returned <strong>once</strong> when the webhook was created or its secret
      was rotated). Verify it like this:</p><pre><code>parsed =
      parse_header("X-StatusPal-Signature")  # → { t: &#x3C;int>, v1: &#x3C;hex>
      }

      signed = `${parsed.t}.${raw_body}`

      digest = HMAC_SHA256(secret, signed)

      if (Date.now() / 1000 - parsed.t > 300) reject  # 5-minute tolerance
      recommended

      if (!constant_time_eq(digest, parsed.v1)) reject

      </code></pre><h2>Delivery retries</h2><p>Each event is delivered up to
      <strong>3 times</strong> with exponential backoff: <strong>1s, 2s,
      4s</strong> between attempts. Any 2xx response is treated as success; any
      other status, a timeout (5s open / 10s read), or a network error triggers
      the next retry. After the third failure the delivery is dropped.</p>
  - name: Webhook Events
    description: >-
      Outbound events StatusPal POSTs to your `outgoing_webhook.url` when
      configured events fire
    x-gitbook-description-document:
      object: document
      data:
        schemaVersion: 9
      nodes:
        - object: block
          type: paragraph
          isVoid: false
          data: {}
          nodes:
            - object: text
              leaves:
                - object: leaf
                  text: 'Outbound events StatusPal POSTs to your '
                  marks: []
                - object: leaf
                  text: outgoing_webhook.url
                  marks:
                    - object: mark
                      type: code
                      data: {}
                - object: leaf
                  text: ' when configured events fire'
                  marks: []
              key: Y7QvsPfrleUp
          key: XWvlUiAbpxpd
      key: 3Bx5eih3VE6s
    x-gitbook-description-html: >-
      <p>Outbound events StatusPal POSTs to your
      <code>outgoing_webhook.url</code> when configured events fire</p>
paths:
  /signup:
    post:
      summary: Sign up for a new account
      description: >
        Create a new organization and its first admin user, and receive an API
        key in return.

        This endpoint is **public** — it does not require an API key — so AI
        agents can onboard

        without visiting the web dashboard.


        The returned API key is **pending activation**: an administrator must
        activate the new

        account before it can be used. Until then, every other endpoint returns

        `403` with error `account_pending_activation`. No email confirmation is
        required.
      operationId: signup
      tags:
        - Signup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupCreate'
      responses:
        '201':
          description: >-
            Account created. The API key is returned once and cannot be
            retrieved again.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Signup'
          x-gitbook-description-html: >-
            <p>Account created. The API key is returned once and cannot be
            retrieved again.</p>
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: >-
                      Create a new organization and its first admin user, and
                      receive an API key in return. This endpoint is
                    marks: []
                  - object: leaf
                    text: public
                    marks:
                      - object: mark
                        type: bold
                        data: {}
                  - object: leaf
                    text: ' — it does not require an API key — so AI agents can onboard without visiting the web dashboard.'
                    marks: []
                key: ExOuVwVn4T5c
            key: Zfu3MutvkWw7
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: 'The returned API key is '
                    marks: []
                  - object: leaf
                    text: pending activation
                    marks:
                      - object: mark
                        type: bold
                        data: {}
                  - object: leaf
                    text: >-
                      : an administrator must activate the new account before it
                      can be used. Until then, every other endpoint returns
                    marks: []
                  - object: leaf
                    text: '403'
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' with error '
                    marks: []
                  - object: leaf
                    text: account_pending_activation
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: . No email confirmation is required.
                    marks: []
                key: p87edqGKhGLh
            key: OxwH9C0yI8S2
        key: Heh5HXMygLXM
      x-gitbook-description-html: >-
        <p>Create a new organization and its first admin user, and receive an
        API key in return. This endpoint is <strong>public</strong> — it does
        not require an API key — so AI agents can onboard without visiting the
        web dashboard.</p><p>The returned API key is <strong>pending
        activation</strong>: an administrator must activate the new account
        before it can be used. Until then, every other endpoint returns
        <code>403</code> with error <code>account_pending_activation</code>. No
        email confirmation is required.</p>
  /status_pages:
    get:
      summary: List status pages
      operationId: listStatusPages
      tags:
        - Status Pages
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/StatusPage'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
    post:
      summary: Create a status page
      operationId: createStatusPage
      tags:
        - Status Pages
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StatusPageCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/StatusPage'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /status_pages/{subdomain}:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
    get:
      summary: Get a status page
      operationId: getStatusPage
      tags:
        - Status Pages
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/StatusPage'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Update a status page
      operationId: updateStatusPage
      tags:
        - Status Pages
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StatusPageUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/StatusPage'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      summary: Delete a status page
      operationId: deleteStatusPage
      tags:
        - Status Pages
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /status_pages/{subdomain}/services:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
    get:
      summary: List services
      operationId: listServices
      tags:
        - Services
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Service'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    post:
      summary: Create a service
      operationId: createService
      tags:
        - Services
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Service'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /status_pages/{subdomain}/services/{service_slug}:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
      - $ref: '#/components/parameters/ServiceSlug'
    get:
      summary: Get a service
      operationId: getService
      tags:
        - Services
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Service'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Update a service
      operationId: updateService
      tags:
        - Services
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Service'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      summary: Delete a service
      operationId: deleteService
      tags:
        - Services
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /status_pages/{subdomain}/containers:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
    get:
      summary: List containers
      operationId: listContainers
      tags:
        - Containers
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Container'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    post:
      summary: Create a container
      operationId: createContainer
      tags:
        - Containers
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContainerCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Container'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
  /status_pages/{subdomain}/containers/{container_slug}:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
      - $ref: '#/components/parameters/ContainerSlug'
    get:
      summary: Get a container
      operationId: getContainer
      tags:
        - Containers
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Container'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Update a container
      operationId: updateContainer
      tags:
        - Containers
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContainerUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Container'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      summary: Delete a container
      operationId: deleteContainer
      tags:
        - Containers
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /status_pages/{subdomain}/notices:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
    get:
      summary: List notices
      operationId: listNotices
      tags:
        - Notices
      security:
        - bearerAuth: []
      parameters:
        - in: query
          name: notice_type
          schema:
            type: string
            enum:
              - incident
              - maintenance
              - info
          description: Filter by notice type
          x-gitbook-description-html: <p>Filter by notice type</p>
        - in: query
          name: status
          schema:
            type: string
          description: Filter by status (e.g. `investigating`, `resolved`, `scheduled`)
          x-gitbook-description-html: >-
            <p>Filter by status (e.g. <code>investigating</code>,
            <code>resolved</code>, <code>scheduled</code>)</p>
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Notice'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    post:
      summary: Create a notice
      operationId: createNotice
      tags:
        - Notices
      security:
        - bearerAuth: []
      description: >
        Creates a notice. Optionally include `initial_update` to attach the
        first timeline

        entry in the same request — this is the recommended approach for opening
        an incident

        or scheduling a maintenance window.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeCreate'
            examples:
              incident:
                summary: Open an incident with an initial update
                value:
                  notice_type: incident
                  title: API Latency Degradation
                  severity: major
                  starts_at: '2030-01-15T14:00:00Z'
                  initial_update:
                    status: investigating
                    body: We are investigating elevated API response times.
                    service_statuses:
                      - service_slug: api
                        container_slug: eu-region
                        status: major
                      - service_slug: api
                        container_slug: us-region
                        status: minor
              maintenance:
                summary: Schedule a maintenance window
                value:
                  notice_type: maintenance
                  title: Database migration
                  starts_at: '2030-01-15T02:00:00Z'
                  ends_at: '2030-01-15T04:00:00Z'
                  initial_update:
                    status: scheduled
                    body: We will perform a scheduled database migration.
                    service_statuses:
                      - service_slug: database
                        container_slug: default
                        status: maintenance
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/NoticeDetail'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: 'Creates a notice. Optionally include '
                    marks: []
                  - object: leaf
                    text: initial_update
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' to attach the first timeline entry in the same request — this is the recommended approach for opening an incident or scheduling a maintenance window.'
                    marks: []
                key: XDv5skqrMU24
            key: GBfC8m8E5HnT
        key: lX4IMRoriNJ3
      x-gitbook-description-html: >-
        <p>Creates a notice. Optionally include <code>initial_update</code> to
        attach the first timeline entry in the same request — this is the
        recommended approach for opening an incident or scheduling a maintenance
        window.</p>
  /status_pages/{subdomain}/notices/{notice_id}:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
      - $ref: '#/components/parameters/NoticeId'
    get:
      summary: Get a notice
      operationId: getNotice
      tags:
        - Notices
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/NoticeDetail'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Update a notice
      operationId: updateNotice
      tags:
        - Notices
      security:
        - bearerAuth: []
      description: >
        Updates notice metadata (title, severity, scheduled times, published
        flag).

        To move the status forward and add a timeline entry, use the Notice
        Updates resource.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticePatch'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/NoticeDetail'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: >-
                      Updates notice metadata (title, severity, scheduled times,
                      published flag). To move the status forward and add a
                      timeline entry, use the Notice Updates resource.
                    marks: []
                key: 2z65RO3lf3jw
            key: XQDMOVEwkC1p
        key: jXuPs209SO12
      x-gitbook-description-html: >-
        <p>Updates notice metadata (title, severity, scheduled times, published
        flag). To move the status forward and add a timeline entry, use the
        Notice Updates resource.</p>
    delete:
      summary: Delete a notice
      operationId: deleteNotice
      tags:
        - Notices
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /status_pages/{subdomain}/notices/{notice_id}/updates:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
      - $ref: '#/components/parameters/NoticeId'
    post:
      summary: Add an update to a notice
      operationId: createNoticeUpdate
      tags:
        - Notice Updates
      security:
        - bearerAuth: []
      description: >
        Appends a timeline entry. Optionally transitions the notice to a new
        `status`

        in the same request (e.g., `investigating` → `identified` → `resolved`).

        A `notify: true` update (the default) triggers email/Slack
        notifications.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeUpdateCreate'
            examples:
              resolve:
                summary: Resolve an incident
                value:
                  status: resolved
                  body: The issue has been resolved. All systems are operational.
                  notify: true
                  service_statuses:
                    - service_slug: api
                      container_slug: eu-region
                      status: ok
                    - service_slug: api
                      container_slug: us-region
                      status: ok
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/NoticeUpdateObject'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: >-
                      Appends a timeline entry. Optionally transitions the
                      notice to a new
                    marks: []
                  - object: leaf
                    text: status
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' in the same request (e.g., '
                    marks: []
                  - object: leaf
                    text: investigating
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' → '
                    marks: []
                  - object: leaf
                    text: identified
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' → '
                    marks: []
                  - object: leaf
                    text: resolved
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: '). A '
                    marks: []
                  - object: leaf
                    text: 'notify: true'
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' update (the default) triggers email/Slack notifications.'
                    marks: []
                key: Vlq5kG7mUwEk
            key: 0a9CSExvLvJW
        key: oGeJqK7fr86I
      x-gitbook-description-html: >-
        <p>Appends a timeline entry. Optionally transitions the notice to a new
        <code>status</code> in the same request (e.g.,
        <code>investigating</code> → <code>identified</code> →
        <code>resolved</code>). A <code>notify: true</code> update (the default)
        triggers email/Slack notifications.</p>
  /status_pages/{subdomain}/notices/{notice_id}/updates/{update_id}:
    parameters:
      - $ref: '#/components/parameters/Subdomain'
      - $ref: '#/components/parameters/NoticeId'
      - $ref: '#/components/parameters/UpdateId'
    patch:
      summary: Edit a notice update
      operationId: updateNoticeUpdate
      tags:
        - Notice Updates
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeUpdateEdit'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/NoticeUpdateObject'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      summary: Delete a notice update
      operationId: deleteNoticeUpdate
      tags:
        - Notice Updates
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /outgoing_webhooks:
    get:
      summary: List outgoing webhooks
      operationId: listOutgoingWebhooks
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      parameters:
        - $ref: '#/components/parameters/Page'
        - $ref: '#/components/parameters/PerPage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/OutgoingWebhook'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
    post:
      summary: Create an outgoing webhook
      description: |
        Creates a new outgoing webhook. The response includes the plaintext
        signing `secret` exactly **once** — store it immediately, it cannot be
        retrieved later. Use `POST /outgoing_webhooks/{id}/regenerate_secret`
        to rotate.
      operationId: createOutgoingWebhook
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OutgoingWebhookCreate'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/OutgoingWebhookWithSecret'
          x-gitbook-description-html: <p>Created</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: >-
                      Creates a new outgoing webhook. The response includes the
                      plaintext signing
                    marks: []
                  - object: leaf
                    text: secret
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' exactly '
                    marks: []
                  - object: leaf
                    text: once
                    marks:
                      - object: mark
                        type: bold
                        data: {}
                  - object: leaf
                    text: ' — store it immediately, it cannot be retrieved later. Use '
                    marks: []
                  - object: leaf
                    text: POST /outgoing_webhooks/{id}/regenerate_secret
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' to rotate.'
                    marks: []
                key: EtBiBmvc7vzM
            key: n09QdvsnWUBn
        key: QNN5nZvlXuy4
      x-gitbook-description-html: >-
        <p>Creates a new outgoing webhook. The response includes the plaintext
        signing <code>secret</code> exactly <strong>once</strong> — store it
        immediately, it cannot be retrieved later. Use <code>POST
        /outgoing_webhooks/{id}/regenerate_secret</code> to rotate.</p>
  /outgoing_webhooks/{id}:
    parameters:
      - $ref: '#/components/parameters/OutgoingWebhookId'
    get:
      summary: Get an outgoing webhook
      operationId: getOutgoingWebhook
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/OutgoingWebhook'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      summary: Update an outgoing webhook
      operationId: updateOutgoingWebhook
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OutgoingWebhookUpdate'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/OutgoingWebhook'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
    delete:
      summary: Delete an outgoing webhook
      operationId: deleteOutgoingWebhook
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      responses:
        '204':
          description: Deleted
          x-gitbook-description-html: <p>Deleted</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
  /outgoing_webhooks/{id}/regenerate_secret:
    parameters:
      - $ref: '#/components/parameters/OutgoingWebhookId'
    post:
      summary: Rotate the signing secret
      description: |
        Replaces the webhook's signing secret with a freshly generated value.
        The new plaintext `secret` is returned in this response **only** — it
        is not stored in cleartext and cannot be retrieved later.
      operationId: regenerateOutgoingWebhookSecret
      tags:
        - Outgoing Webhooks
      security:
        - bearerAuth: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/OutgoingWebhookWithSecret'
          x-gitbook-description-html: <p>OK</p>
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/AccountPendingActivation'
        '404':
          $ref: '#/components/responses/NotFound'
      x-gitbook-description-document:
        object: document
        data:
          schemaVersion: 9
        nodes:
          - object: block
            type: paragraph
            isVoid: false
            data: {}
            nodes:
              - object: text
                leaves:
                  - object: leaf
                    text: >-
                      Replaces the webhook's signing secret with a freshly
                      generated value. The new plaintext
                    marks: []
                  - object: leaf
                    text: secret
                    marks:
                      - object: mark
                        type: code
                        data: {}
                  - object: leaf
                    text: ' is returned in this response '
                    marks: []
                  - object: leaf
                    text: only
                    marks:
                      - object: mark
                        type: bold
                        data: {}
                  - object: leaf
                    text: ' — it is not stored in cleartext and cannot be retrieved later.'
                    marks: []
                key: OIeYRS4lFO9n
            key: ptH6PvRFt7ku
        key: sdSqgQurtUwU
      x-gitbook-description-html: >-
        <p>Replaces the webhook's signing secret with a freshly generated value.
        The new plaintext <code>secret</code> is returned in this response
        <strong>only</strong> — it is not stored in cleartext and cannot be
        retrieved later.</p>
webhooks:
  serviceStatusChanged:
    post:
      summary: Service status changed
      operationId: webhookServiceStatusChanged
      tags:
        - Webhook Events
      description: >
        Fired when a container service transitions to a different status.
        Emitted **per ContainerService**,

        not per Service — a service that appears in multiple containers
        (regions) emits one event per

        affected container.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceStatusChangedEvent'
      responses:
        2XX:
          description: Receiver acknowledged the event. Any 2xx is treated as success.
          x-gitbook-description-html: >-
            <p>Receiver acknowledged the event. Any 2xx is treated as
            success.</p>
        default:
          description: Any non-2xx response causes a retry (up to 3 attempts).
          x-gitbook-description-html: <p>Any non-2xx response causes a retry (up to 3 attempts).</p>
      x-gitbook-description-html: >-
        <p>Fired when a container service transitions to a different status.
        Emitted <strong>per ContainerService</strong>,

        not per Service — a service that appears in multiple containers
        (regions) emits one event per

        affected container.</p>
  noticeCreated:
    post:
      summary: Notice created
      operationId: webhookNoticeCreated
      tags:
        - Webhook Events
      description: >
        Fired when a new notice (incident, maintenance, or info) is created.
        Emitted for every notice

        regardless of `published` / `retroactive` / scheduled state — filter on
        `data.notice.type`,

        `data.notice.status`, `data.notice.published`, and
        `data.notice.retroactive` if you only care

        about a subset.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeCreatedEvent'
      responses:
        2XX:
          description: Receiver acknowledged the event. Any 2xx is treated as success.
          x-gitbook-description-html: >-
            <p>Receiver acknowledged the event. Any 2xx is treated as
            success.</p>
        default:
          description: Any non-2xx response causes a retry (up to 3 attempts).
          x-gitbook-description-html: <p>Any non-2xx response causes a retry (up to 3 attempts).</p>
      x-gitbook-description-html: >-
        <p>Fired when a new notice (incident, maintenance, or info) is created.
        Emitted for every notice

        regardless of <code>published</code> / <code>retroactive</code> /
        scheduled state — filter on <code>data.notice.type</code>,

        <code>data.notice.status</code>, <code>data.notice.published</code>, and
        <code>data.notice.retroactive</code> if you only care

        about a subset.</p>
  noticeUpdatePosted:
    post:
      summary: Notice update posted
      operationId: webhookNoticeUpdatePosted
      tags:
        - Webhook Events
      description: >
        Fired when a new timeline entry (update) is posted to an existing
        notice. The payload also

        includes a `service_statuses` array listing any container-service
        statuses changed by this

        update. Note `data.notice` is a trimmed summary — use the management API
        if you need the

        full notice.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeUpdatePostedEvent'
      responses:
        2XX:
          description: Receiver acknowledged the event. Any 2xx is treated as success.
          x-gitbook-description-html: >-
            <p>Receiver acknowledged the event. Any 2xx is treated as
            success.</p>
        default:
          description: Any non-2xx response causes a retry (up to 3 attempts).
          x-gitbook-description-html: <p>Any non-2xx response causes a retry (up to 3 attempts).</p>
      x-gitbook-description-html: >-
        <p>Fired when a new timeline entry (update) is posted to an existing
        notice. The payload also

        includes a <code>service_statuses</code> array listing any
        container-service statuses changed by this

        update. Note <code>data.notice</code> is a trimmed summary — use the
        management API if you need the

        full notice.</p>
  noticeUpdated:
    post:
      summary: Notice changed
      operationId: webhookNoticeUpdated
      tags:
        - Webhook Events
      description: >
        Fired when an existing notice's tracked fields change (status, title,
        severity, lifecycle,

        timestamps, etc.) — independently of timeline updates. A `data.changes`
        map lists each

        modified field's `[old, new]` values. Note: posting a timeline update
        that also flips the

        parent notice's status will fire **both** `notice.update_posted` and
        `notice.updated`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NoticeUpdatedEvent'
      responses:
        2XX:
          description: Receiver acknowledged the event. Any 2xx is treated as success.
          x-gitbook-description-html: >-
            <p>Receiver acknowledged the event. Any 2xx is treated as
            success.</p>
        default:
          description: Any non-2xx response causes a retry (up to 3 attempts).
          x-gitbook-description-html: <p>Any non-2xx response causes a retry (up to 3 attempts).</p>
      x-gitbook-description-html: >-
        <p>Fired when an existing notice's tracked fields change (status, title,
        severity, lifecycle,

        timestamps, etc.) — independently of timeline updates. A
        <code>data.changes</code> map lists each

        modified field's <code>[old, new]</code> values. Note: posting a
        timeline update that also flips the

        parent notice's status will fire <strong>both</strong>
        <code>notice.update_posted</code> and <code>notice.updated</code>.</p>
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Organization API key — issue one via the Rails console (management UI
        coming soon)
      x-gitbook-description-html: >-
        <p>Organization API key — issue one via the Rails console (management UI
        coming soon)</p>
  parameters:
    Subdomain:
      in: path
      name: subdomain
      required: true
      schema:
        type: string
      description: Status page subdomain (e.g. `acme-status`)
      x-gitbook-description-html: <p>Status page subdomain (e.g. <code>acme-status</code>)</p>
    ServiceSlug:
      in: path
      name: service_slug
      required: true
      schema:
        type: string
      description: Service slug (auto-generated from name, e.g. `api-gateway`)
      x-gitbook-description-html: >-
        <p>Service slug (auto-generated from name, e.g.
        <code>api-gateway</code>)</p>
    ContainerSlug:
      in: path
      name: container_slug
      required: true
      schema:
        type: string
      description: Container slug (auto-generated from name)
      x-gitbook-description-html: <p>Container slug (auto-generated from name)</p>
    NoticeId:
      in: path
      name: notice_id
      required: true
      schema:
        type: string
        format: uuid
    UpdateId:
      in: path
      name: update_id
      required: true
      schema:
        type: string
        format: uuid
    OutgoingWebhookId:
      in: path
      name: id
      required: true
      schema:
        type: string
      description: TypeID-prefixed identifier (e.g. `wbk_01h2x...`)
      x-gitbook-description-html: <p>TypeID-prefixed identifier (e.g. <code>wbk_01h2x...</code>)</p>
    Page:
      in: query
      name: page
      schema:
        type: integer
        default: 1
        minimum: 1
    PerPage:
      in: query
      name: per_page
      schema:
        type: integer
        default: 20
        maximum: 100
        minimum: 1
  schemas:
    StatusPage:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        subdomain:
          type: string
          example: acme-status
        name:
          type: string
          example: Acme Status
        timezone:
          type: string
          example: America/New_York
        website_url:
          type: string
          format: uri
          example: https://acme.com
        current_status:
          readOnly: true
          type: string
          enum:
            - operational
            - degraded
            - unavailable
          description: Highest-severity status derived from active notices and services
          x-gitbook-description-html: >-
            <p>Highest-severity status derived from active notices and
            services</p>
        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
    StatusPageCreate:
      type: object
      required:
        - subdomain
        - name
        - timezone
        - website_url
      properties:
        subdomain:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]*[a-z0-9]$
          example: acme-status
        name:
          type: string
          example: Acme Status
        timezone:
          type: string
          example: America/New_York
        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

            uses the `ServiceCreate` shape (`name`, optional `slug`, optional

            `description`). If `slug` is omitted it is derived from `name`
            (collisions

            auto-suffixed as `-1`, `-2`, ...). Entries with a blank `name` are
            skipped

            and exact-duplicate entries deduped.


            Note: `container_statuses` is not honored in this nested form
            because

            containers may not exist yet within the same request. To set
            per-container

            statuses, create the status page first and then call `POST
            /services` (or

            update statuses via a notice update).
          items:
            $ref: '#/components/schemas/ServiceCreate'
          example:
            - name: Payment gateway
              slug: pay-gw
            - name: API
              description: Public REST API
              x-gitbook-description-html: <p>Public REST API</p>
            - name: Webhooks
          x-gitbook-description-html: >-
            <p>Optional list of services to create alongside the status page.
            Each entry

            uses the <code>ServiceCreate</code> shape (<code>name</code>,
            optional <code>slug</code>, optional

            <code>description</code>). If <code>slug</code> is omitted it is
            derived from <code>name</code> (collisions

            auto-suffixed as <code>-1</code>, <code>-2</code>, ...). Entries
            with a blank <code>name</code> are skipped

            and exact-duplicate entries deduped.</p>

            <p>Note: <code>container_statuses</code> is not honored in this
            nested form because

            containers may not exist yet within the same request. To set
            per-container

            statuses, create the status page first and then call <code>POST
            /services</code> (or

            update statuses via a notice update).</p>
        containers:
          type: array
          description: >
            Optional list of containers (regions). Each entry uses the
            `ContainerCreate`

            shape (`name`, optional `slug`). If omitted or empty, a single
            container

            named "Default" is auto-created so every service has somewhere to
            live.

            After creation, the cross-product of services × containers is
            materialized

            as ContainerService rows (status `ok`). Entries with a blank `name`
            are

            skipped and exact-duplicate entries deduped.
          items:
            $ref: '#/components/schemas/ContainerCreate'
          example:
            - name: EU
              slug: eu
            - name: US
          x-gitbook-description-html: >-
            <p>Optional list of containers (regions). Each entry uses the
            <code>ContainerCreate</code>

            shape (<code>name</code>, optional <code>slug</code>). If omitted or
            empty, a single container

            named "Default" is auto-created so every service has somewhere to
            live.

            After creation, the cross-product of services × containers is
            materialized

            as ContainerService rows (status <code>ok</code>). Entries with a
            blank <code>name</code> are

            skipped and exact-duplicate entries deduped.</p>
    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
          default: false
        rss_feed_enabled:
          type: boolean
          default: true
    Service:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        slug:
          type: string
          example: api-gateway
          description: >
            URL-safe identifier. May be supplied on create/update; if omitted,
            it is

            auto-generated from `name`. Uniqueness is enforced per status page.
          x-gitbook-description-html: >-
            <p>URL-safe identifier. May be supplied on create/update; if
            omitted, it is

            auto-generated from <code>name</code>. Uniqueness is enforced per
            status page.</p>
        name:
          type: string
          example: API Gateway
        description:
          type: string
          nullable: true
        status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
          description: >
            Overall worst-case status for this service, computed across all
            containers.

            Read-only; to change per-container status use `container_statuses`
            on create

            or a notice update.
          readOnly: true
          x-gitbook-description-html: >-
            <p>Overall worst-case status for this service, computed across all
            containers.

            Read-only; to change per-container status use
            <code>container_statuses</code> on create

            or a notice update.</p>
        order:
          type: integer
        container_statuses:
          type: array
          readOnly: true
          items:
            $ref: '#/components/schemas/ContainerStatusEntry'
          description: >-
            Per-container live status for this service, one entry per container
            on the status page.
          x-gitbook-description-html: >-
            <p>Per-container live status for this service, one entry per
            container on the status page.</p>
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: 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`.

            If a non-unique value is provided, a numeric suffix is appended
            (e.g. `api-1`).
          x-gitbook-description-html: >-
            <p>Optional URL-safe identifier. If omitted, it is auto-generated
            from <code>name</code>.

            If a non-unique value is provided, a numeric suffix is appended
            (e.g. <code>api-1</code>).</p>
        description:
          type: string
          nullable: true
        container_statuses:
          type: array
          items:
            $ref: '#/components/schemas/ContainerStatusEntry'
          description: >
            Optional per-container initial statuses. Each entry sets the status
            for the

            named container; any container on the status page that is not listed
            defaults

            to `ok`. Unknown `container_slug` values or out-of-range `status`
            values

            return 422.
          x-gitbook-description-html: >-
            <p>Optional per-container initial statuses. Each entry sets the
            status for the

            named container; any container on the status page that is not listed
            defaults

            to <code>ok</code>. Unknown <code>container_slug</code> values or
            out-of-range <code>status</code> values

            return 422.</p>
    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).
          x-gitbook-description-html: >-
            <p>Optional. If provided, replaces the URL slug (with uniqueness
            suffixing if needed).</p>
        description:
          type: string
          nullable: true
        order:
          type: integer
          description: >-
            Position in the display list (1-indexed). Other services shift
            accordingly.
          x-gitbook-description-html: >-
            <p>Position in the display list (1-indexed). Other services shift
            accordingly.</p>
    ServiceSummary:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
    ContainerStatusEntry:
      type: object
      required:
        - container_slug
        - status
      properties:
        container_slug:
          type: string
          example: eu
        status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
          example: major
    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 assigned to this container, ordered by display order
          x-gitbook-description-html: <p>Services assigned to this container, ordered by display order</p>
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    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`.

            If a non-unique value is provided, a numeric suffix is appended
            (e.g. `eu-1`).
          x-gitbook-description-html: >-
            <p>Optional URL-safe identifier. If omitted, it is auto-generated
            from <code>name</code>.

            If a non-unique value is provided, a numeric suffix is appended
            (e.g. <code>eu-1</code>).</p>
      description: >
        Service membership is managed automatically — when a container is
        created, every

        existing service on the status page is assigned to it (full N×M grid).
        There is

        no API to assign or remove services individually; per-container service
        status is

        updated via notice updates.
      x-gitbook-description-html: >-
        <p>Service membership is managed automatically — when a container is
        created, every

        existing service on the status page is assigned to it (full N×M grid).
        There is

        no API to assign or remove services individually; per-container service
        status is

        updated via notice updates.</p>
    ContainerUpdate:
      type: object
      properties:
        name:
          type: string
          maxLength: 255
      description: Service membership is not editable via this endpoint.
      x-gitbook-description-html: <p>Service membership is not editable via this endpoint.</p>
    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`:

            - **incident**: `investigating` · `identified` · `monitoring` ·
            `resolved`

            - **maintenance**: `scheduled` · `in_progress` · `verifying` ·
            `completed`

            - **info**: `info`
          x-gitbook-description-html: >-
            <p>Valid values by <code>notice_type</code>:</p>

            <ul>

            <li><strong>incident</strong>: <code>investigating</code> ·
            <code>identified</code> · <code>monitoring</code> ·
            <code>resolved</code></li>

            <li><strong>maintenance</strong>: <code>scheduled</code> ·
            <code>in_progress</code> · <code>verifying</code> ·
            <code>completed</code></li>

            <li><strong>info</strong>: <code>info</code></li>

            </ul>
        severity:
          type: string
          enum:
            - major
            - minor
          nullable: true
        lifecycle:
          type: string
          enum:
            - pending
            - active
            - completed
          readOnly: true
        published:
          type: boolean
        starts_at:
          type: string
          format: date-time
          nullable: true
        ends_at:
          type: string
          format: date-time
          nullable: true
        latest_update:
          nullable: true
          allOf:
            - $ref: '#/components/schemas/NoticeUpdateObject'
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    NoticeDetail:
      allOf:
        - $ref: '#/components/schemas/Notice'
        - type: object
          properties:
            updates:
              type: array
              items:
                $ref: '#/components/schemas/NoticeUpdateObject'
              description: Full timeline, ordered newest-first
              x-gitbook-description-html: <p>Full timeline, ordered newest-first</p>
    NoticeCreate:
      type: object
      required:
        - notice_type
        - title
      properties:
        notice_type:
          type: string
          enum:
            - incident
            - maintenance
            - info
        title:
          type: string
          maxLength: 255
        severity:
          type: string
          enum:
            - major
            - minor
          nullable: true
        published:
          type: boolean
          default: false
        starts_at:
          type: string
          format: date-time
          description: Required for `incident` and `maintenance` types.
          x-gitbook-description-html: >-
            <p>Required for <code>incident</code> and <code>maintenance</code>
            types.</p>
        ends_at:
          type: string
          format: date-time
          nullable: true
        initial_update:
          description: |
            Optional first timeline entry created atomically with the notice.
            Recommended for incidents and maintenance windows.
          allOf:
            - $ref: '#/components/schemas/NoticeUpdateCreate'
          x-gitbook-description-html: |-
            <p>Optional first timeline entry created atomically with the notice.
            Recommended for incidents and maintenance windows.</p>
    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
          enum:
            - major
            - minor
          nullable: true
        published:
          type: boolean
        starts_at:
          type: string
          format: date-time
        ends_at:
          type: string
          format: date-time
          nullable: true
      x-gitbook-description-html: >-
        <p>Edits notice metadata only. Use the Notice Updates resource to change
        status.</p>
    NoticeUpdateObject:
      type: object
      properties:
        id:
          type: string
          format: uuid
          readOnly: true
        status:
          type: string
          description: The notice status at the time of this update
          x-gitbook-description-html: <p>The notice status at the time of this update</p>
        body:
          type: string
          description: HTML content of the update
          x-gitbook-description-html: <p>HTML content of the update</p>
        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
              container_name:
                type: string
              status:
                type: string
                enum:
                  - ok
                  - minor
                  - major
                  - critical
                  - maintenance
          x-gitbook-description-html: >-
            <p>The service statuses that were set as part of this timeline
            entry.</p>
    ServiceStatus:
      type: object
      required:
        - service_slug
        - status
      description: >-
        Sets the status of a service (optionally scoped to a specific
        container).
      properties:
        service_slug:
          type: string
          example: api
        container_slug:
          type: string
          example: eu-region
          description: >
            Only needed if you have configured multiple containers and want to
            target a specific

            one (e.g. "API in EU Region" vs "API in US Region"). Omit to target
            the default container.
          x-gitbook-description-html: >-
            <p>Only needed if you have configured multiple containers and want
            to target a specific

            one (e.g. "API in EU Region" vs "API in US Region"). Omit to target
            the default container.</p>
        status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
      x-gitbook-description-html: >-
        <p>Sets the status of a service (optionally scoped to a specific
        container).</p>
    NoticeUpdateCreate:
      type: object
      required:
        - body
      properties:
        status:
          type: string
          description: >
            Transitions the notice to this status. Defaults to the current
            notice status

            (i.e. adds an update without changing status).
          x-gitbook-description-html: >-
            <p>Transitions the notice to this status. Defaults to the current
            notice status

            (i.e. adds an update without changing status).</p>
        body:
          type: string
          description: HTML or plain-text content for the update.
          maxLength: 10000
          x-gitbook-description-html: <p>HTML or plain-text content for the update.</p>
        posted_at:
          type: string
          format: date-time
          description: Defaults to current time.
          x-gitbook-description-html: <p>Defaults to current time.</p>
        notify:
          type: boolean
          default: true
          description: Whether to send email/Slack notifications for this update.
          x-gitbook-description-html: <p>Whether to send email/Slack notifications for this update.</p>
        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

            all service statuses unchanged.
          x-gitbook-description-html: >-
            <p>Sets the live status of one or more services on the status page.
            Omit to leave

            all service statuses unchanged.</p>
    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.
          x-gitbook-description-html: >-
            <p>Replaces the service statuses recorded for this timeline
            entry.</p>
    OutgoingWebhook:
      type: object
      properties:
        id:
          type: string
          readOnly: true
          description: TypeID-prefixed identifier (e.g. `wbk_01h2x...`)
          x-gitbook-description-html: <p>TypeID-prefixed identifier (e.g. <code>wbk_01h2x...</code>)</p>
        name:
          type: string
          example: Ops alerts
        url:
          type: string
          format: uri
          description: HTTPS URL that will receive `POST` deliveries.
          example: https://hooks.example.com/statuspal
          x-gitbook-description-html: <p>HTTPS URL that will receive <code>POST</code> deliveries.</p>
        events:
          type: array
          items:
            type: string
            enum:
              - service.status_changed
              - notice.created
              - notice.update_posted
              - notice.updated
          example:
            - notice.created
            - 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
            the organization, including pages created later. When `false`, only
            events on pages listed in `status_page_subdomains` fire.
          x-gitbook-description-html: >-
            <p>When <code>true</code>, the webhook fires for events on every
            status page in

            the organization, including pages created later. When
            <code>false</code>, only

            events on pages listed in <code>status_page_subdomains</code>
            fire.</p>
        status_page_subdomains:
          type: array
          items:
            type: string
          description: |
            Only present when `all_status_pages` is `false`. Subdomains of the
            specific status pages this webhook is scoped to.
          example:
            - prod-status
            - eu-status
          x-gitbook-description-html: >-
            <p>Only present when <code>all_status_pages</code> is
            <code>false</code>. Subdomains of the

            specific status pages this webhook is scoped to.</p>
        last_triggered_at:
          type: string
          format: date-time
          nullable: true
          readOnly: true
          description: Timestamp of the most recent **successful** delivery.
          x-gitbook-description-html: >-
            <p>Timestamp of the most recent <strong>successful</strong>
            delivery.</p>
        last_attempted_at:
          type: string
          format: date-time
          nullable: true
          readOnly: true
          description: Timestamp of the most recent delivery attempt (success or failure).
          x-gitbook-description-html: >-
            <p>Timestamp of the most recent delivery attempt (success or
            failure).</p>
        created_at:
          type: string
          format: date-time
          readOnly: true
        updated_at:
          type: string
          format: date-time
          readOnly: true
    OutgoingWebhookWithSecret:
      allOf:
        - $ref: '#/components/schemas/OutgoingWebhook'
        - type: object
          required:
            - secret
          properties:
            secret:
              type: string
              description: >
                Plaintext signing secret (`whs_…`). Returned **only** in
                responses

                to create and regenerate_secret. Store it immediately — it is
                not

                retrievable later.
              example: >-
                whs_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
              x-gitbook-description-html: >-
                <p>Plaintext signing secret (<code>whs_…</code>). Returned
                <strong>only</strong> in responses

                to create and regenerate_secret. Store it immediately — it is
                not

                retrievable later.</p>
    OutgoingWebhookCreate:
      type: object
      required:
        - name
        - url
        - events
      properties:
        name:
          type: string
          example: Ops alerts
        url:
          type: string
          format: uri
          example: https://hooks.example.com/statuspal
        events:
          type: array
          items:
            type: string
            enum:
              - service.status_changed
              - notice.created
              - notice.update_posted
              - notice.updated
          example:
            - notice.created
        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
            status pages this webhook should fire for. Unknown subdomains
            cause a `422`.
          items:
            type: string
          example:
            - prod-status
            - eu-status
          x-gitbook-description-html: >-
            <p>Required when <code>all_status_pages</code> is
            <code>false</code>. Subdomains of the

            status pages this webhook should fire for. Unknown subdomains

            cause a <code>422</code>.</p>
    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
    WebhookEventStatusPage:
      type: object
      description: >
        The status page on which the event occurred (embedded in every event
        envelope). The

        `subdomain` is the public identifier — use it to look up the page via
        the management API.
      required:
        - subdomain
        - name
        - url
      properties:
        subdomain:
          type: string
          example: prod-status
        name:
          type: string
          example: Production Status
        url:
          type: string
          format: uri
          description: >-
            Canonical public URL of the status page (custom domain when
            configured, otherwise the `*.statuspal.io` subdomain).
          example: https://prod-status.statuspal.io
          x-gitbook-description-html: >-
            <p>Canonical public URL of the status page (custom domain when
            configured, otherwise the <code>*.statuspal.io</code>
            subdomain).</p>
      x-gitbook-description-html: >-
        <p>The status page on which the event occurred (embedded in every event
        envelope). The

        <code>subdomain</code> is the public identifier — use it to look up the
        page via the management API.</p>
    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.
          x-gitbook-description-html: >-
            <p>The event name. Always matches the <code>X-StatusPal-Event</code>
            header.</p>
        occurred_at:
          type: string
          format: date-time
          description: >-
            ISO-8601 timestamp of when the event was emitted (not when it was
            delivered).
          x-gitbook-description-html: >-
            <p>ISO-8601 timestamp of when the event was emitted (not when it was
            delivered).</p>
        status_page:
          $ref: '#/components/schemas/WebhookEventStatusPage'
        data:
          type: object
          description: Event-specific payload — see per-event schemas.
          x-gitbook-description-html: <p>Event-specific payload — see per-event schemas.</p>
      x-gitbook-description-html: >-
        <p>Shared envelope for every outbound webhook event. Concrete events
        extend this via <code>allOf</code> and pin <code>event</code> /
        <code>data</code> to their specific shapes.</p>
    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.
              example: api
              x-gitbook-description-html: <p>Unique slug for the service within its status page.</p>
            name:
              type: string
              example: API
        container:
          type: object
          required:
            - slug
            - name
          properties:
            slug:
              type: string
              description: Unique slug for the container within its status page.
              example: eu
              x-gitbook-description-html: <p>Unique slug for the container within its status page.</p>
            name:
              type: string
              example: EU
        old_status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
        new_status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
    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'
      example:
        event: service.status_changed
        occurred_at: '2026-05-21T14:03:12Z'
        status_page:
          subdomain: prod-status
          name: Production Status
          url: https://prod-status.statuspal.io
        data:
          service:
            slug: api
            name: API
          container:
            slug: eu
            name: EU
          old_status: ok
          new_status: major
      x-gitbook-description-html: >-
        <p>Emitted when a <code>ContainerService.status</code> transitions to a
        different value. Naturally rate-limited — same-value updates do not fire
        this event.</p>
    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_`
          example: ntc_01h2x4q9k7m4n3v5w6r8t1y0z2
          x-gitbook-description-html: <p>TypeID, prefix <code>ntc_</code></p>
        title:
          type: string
          example: Database degraded
        type:
          type: string
          enum:
            - incident
            - maintenance
            - info
        status:
          type: string
          description: |
            One of the allowed statuses for the notice's type. Incidents:
            `investigating`, `identified`, `monitoring`, `resolved`. Planned
            maintenance: `scheduled`, `in_progress`, `verifying`, `completed`.
            Essential maintenance: `in_progress`, `verifying`, `completed`.
            Info notices: `info`.
          x-gitbook-description-html: >-
            <p>One of the allowed statuses for the notice's type. Incidents:

            <code>investigating</code>, <code>identified</code>,
            <code>monitoring</code>, <code>resolved</code>. Planned

            maintenance: <code>scheduled</code>, <code>in_progress</code>,
            <code>verifying</code>, <code>completed</code>.

            Essential maintenance: <code>in_progress</code>,
            <code>verifying</code>, <code>completed</code>.

            Info notices: <code>info</code>.</p>
        severity:
          type: string
          enum:
            - major
            - minor
          nullable: true
        published:
          type: boolean
        retroactive:
          type: boolean
        lifecycle:
          type: string
          enum:
            - active
            - pending
            - completed
          nullable: true
        starts_at:
          type: string
          format: date-time
          nullable: true
        ends_at:
          type: string
          format: date-time
          nullable: true
      x-gitbook-description-html: <p>Full notice shape, used in <code>notice.created</code> events.</p>
    NoticeCreatedData:
      type: object
      required:
        - notice
      properties:
        notice:
          $ref: '#/components/schemas/WebhookNotice'
    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'
      example:
        event: notice.created
        occurred_at: '2026-05-21T14:03:12Z'
        status_page:
          subdomain: prod-status
          name: Production Status
          url: https://prod-status.statuspal.io
        data:
          notice:
            id: ntc_01h2x4q9k7m4n3v5w6r8t1y0z2
            title: Database degraded
            type: incident
            status: investigating
            severity: major
            published: true
            retroactive: false
            lifecycle: active
            starts_at: '2026-05-21T14:00:00Z'
            ends_at: null
      x-gitbook-description-html: >-
        <p>Emitted whenever a new notice is created — including draft,
        scheduled, and retroactive notices. Filter on
        <code>data.notice.published</code> / <code>retroactive</code> /
        <code>type</code> if you only want a subset.</p>
    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_`
          x-gitbook-description-html: <p>TypeID, prefix <code>ntc_</code></p>
        title:
          type: string
        type:
          type: string
          enum:
            - incident
            - maintenance
            - info
        status:
          type: string
      x-gitbook-description-html: >-
        <p>Trimmed notice shape used inside <code>notice.update_posted</code>
        events (only the fields needed to identify the parent notice).</p>
    WebhookNoticeUpdate:
      type: object
      required:
        - id
        - body
        - status
      properties:
        id:
          type: string
          description: TypeID, prefix `upd_`
          example: upd_01h2x4qab8p6m4n3v5w6r8t1y0
          x-gitbook-description-html: <p>TypeID, prefix <code>upd_</code></p>
        body:
          type: string
          description: >-
            HTML body of the update. Receivers should sanitize before rendering.
            Plaintext is **not** included.
          x-gitbook-description-html: >-
            <p>HTML body of the update. Receivers should sanitize before
            rendering. Plaintext is <strong>not</strong> included.</p>
        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).
          x-gitbook-description-html: >-
            <p>Same enum semantics as <code>WebhookNotice.status</code>, plus
            <code>update</code> (a comment-only update that does not change the
            parent notice's status).</p>
        posted_at:
          type: string
          format: date-time
          nullable: true
    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
              example: api
            name:
              type: string
              example: API
        container:
          type: object
          required:
            - slug
            - name
          properties:
            slug:
              type: string
              example: eu
            name:
              type: string
              example: EU
        status:
          type: string
          enum:
            - ok
            - minor
            - major
            - critical
            - maintenance
          description: The new status the service was set to as part of this update.
          x-gitbook-description-html: <p>The new status the service was set to as part of this update.</p>
      x-gitbook-description-html: >-
        <p>One container-service status change carried by a
        <code>notice.update_posted</code> event.</p>
    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

            the update was status-only / a comment / a maintenance update that
            left services as

            "operational". Receivers wanting old→new status pairs can correlate
            with parallel

            `service.status_changed` events sharing the same `occurred_at`.
          items:
            $ref: '#/components/schemas/WebhookNoticeUpdateServiceStatus'
          x-gitbook-description-html: >-
            <p>Container-service status changes that were carried by this notice
            update. Empty when

            the update was status-only / a comment / a maintenance update that
            left services as

            "operational". Receivers wanting old→new status pairs can correlate
            with parallel

            <code>service.status_changed</code> events sharing the same
            <code>occurred_at</code>.</p>
    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'
      example:
        event: notice.update_posted
        occurred_at: '2026-05-21T14:08:47Z'
        status_page:
          subdomain: prod-status
          name: Production Status
          url: https://prod-status.statuspal.io
        data:
          notice:
            id: ntc_01h2x4q9k7m4n3v5w6r8t1y0z2
            title: Database degraded
            type: incident
            status: identified
          update:
            id: upd_01h2x4qab8p6m4n3v5w6r8t1y0
            body: >-
              <p>We've identified the bad query and rolled it back. Recovery in
              progress.</p>
            status: identified
            posted_at: '2026-05-21T14:08:45Z'
          service_statuses:
            - service:
                slug: api
                name: API
              container:
                slug: eu
                name: EU
              status: major
      x-gitbook-description-html: >-
        <p>Emitted when a new timeline entry is posted to an existing
        notice.</p>
    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

            tracked-fields list appear here. Datetime fields are ISO-8601
            strings; other fields

            keep their native JSON type.
          additionalProperties:
            type: array
            minItems: 2
            maxItems: 2
            items: {}
          x-gitbook-description-html: >-
            <p>Map of changed field name → <code>[old_value, new_value]</code>.
            Only fields in the server-side

            tracked-fields list appear here. Datetime fields are ISO-8601
            strings; other fields

            keep their native JSON type.</p>
    NoticeUpdatedEvent:
      description: >
        Emitted when an existing notice's tracked fields change (status, title,
        severity, etc.) —

        either directly via the management API or as a side-effect of a timeline
        update flipping

        the parent notice's status. In the latter case, both
        `notice.update_posted` and

        `notice.updated` fire.
      allOf:
        - $ref: '#/components/schemas/WebhookEnvelope'
        - type: object
          required:
            - event
            - data
          properties:
            event:
              type: string
              enum:
                - notice.updated
            data:
              $ref: '#/components/schemas/NoticeUpdatedData'
      example:
        event: notice.updated
        occurred_at: '2026-05-21T14:08:47Z'
        status_page:
          subdomain: prod-status
          name: Production Status
          url: https://prod-status.statuspal.io
        data:
          notice:
            id: ntc_01h2x4q9k7m4n3v5w6r8t1y0z2
            title: Database degraded
            type: incident
            status: resolved
            severity: major
            published: true
            retroactive: false
            lifecycle: completed
            starts_at: '2026-05-21T14:00:00Z'
            ends_at: '2026-05-21T15:30:00Z'
          changes:
            status:
              - identified
              - resolved
            ends_at:
              - null
              - '2026-05-21T15:30:00Z'
      x-gitbook-description-html: >-
        <p>Emitted when an existing notice's tracked fields change (status,
        title, severity, etc.) —

        either directly via the management API or as a side-effect of a timeline
        update flipping

        the parent notice's status. In the latter case, both
        <code>notice.update_posted</code> and

        <code>notice.updated</code> fire.</p>
    PaginationMeta:
      type: object
      properties:
        current_page:
          type: integer
        per_page:
          type: integer
        total_count:
          type: integer
        total_pages:
          type: integer
    Error:
      type: object
      properties:
        error:
          type: string
          example: unprocessable_entity
        message:
          type: string
          example: Validation failed
        details:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            subdomain:
              - has already been taken
            title:
              - can't be blank
    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.
          x-gitbook-description-html: >-
            <p>Admin user's email. Must be a custom-domain address — free
            providers (gmail.com, yahoo.com, outlook.com, …) are rejected.</p>
        org_name:
          type: string
          description: Name of the organization to create.
          x-gitbook-description-html: <p>Name of the organization to create.</p>
        first_name:
          type: string
        last_name:
          type: string
      example:
        email: agent@acme.dev
        org_name: Acme Inc
        first_name: Ada
        last_name: Agent
    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.
          x-gitbook-description-html: >-
            <p><code>pending_activation</code> until an administrator activates
            the account; the <code>api_key</code> only works once the account is
            active.</p>
        api_key:
          type: string
          description: >-
            Bearer token for the new organization. Returned once — store it
            securely.
          example: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
          x-gitbook-description-html: >-
            <p>Bearer token for the new organization. Returned once — store it
            securely.</p>
        organization:
          type: object
          properties:
            id:
              type: string
              example: org_01h6y6z6z6z6z6z6z6z6z6z6z6
            name:
              type: string
              example: Acme Inc
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unauthorized
            message: Invalid or missing API key
      x-gitbook-description-html: <p>Missing or invalid API key</p>
    AccountPendingActivation:
      description: >-
        The account is pending activation. A newly created account must be
        activated by an administrator before its API key can be used.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: account_pending_activation
            message: >-
              This account is pending activation. An administrator must activate
              it before the API key can be used.
      x-gitbook-description-html: >-
        <p>The account is pending activation. A newly created account must be
        activated by an administrator before its API key can be used.</p>
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: not_found
            message: The requested resource was not found
      x-gitbook-description-html: <p>Resource not found</p>
    UnprocessableEntity:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unprocessable_entity
            message: Validation failed
            details:
              name:
                - can't be blank
      x-gitbook-description-html: <p>Validation failed</p>
    TooManyRequests:
      description: Rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: rate_limited
            message: >-
              Too many requests (status code: 429). Please try again in 60
              seconds.
      x-gitbook-description-html: <p>Rate limit exceeded</p>
