> ## Documentation Index
> Fetch the complete documentation index at: https://docs.use.observer/llms.txt
> Use this file to discover all available pages before exploring further.

# Change a status page's settings

> Changes only the fields sent; the rest keep their value. Works on any page of the organization, made in the console or by config apply (a config document that names the setting later sets it again). Not settable here: custom CSS, custom domains, and the access modes that carry credentials or allow-lists (password, IP allow-list, JWT, customer-scoped, SSO), which are set in the console. `access_mode: public` makes a protected page public and removes its access settings. `hide_branding: true` needs a plan that includes branding removal. `theme.preset` applies a theme preset and replaces the page's theme. The response is the page as GET /pages/{id} returns it, plus `changed`: the settings that changed.



## OpenAPI

````yaml api-reference/openapi.json PATCH /pages/{id}
openapi: 3.1.0
info:
  title: Observer API
  version: 1.0.0
  description: >-
    Public API for Observer: read services, metrics, SLOs and SLA statements;
    manage incidents, maintenance windows, manual metric status, config as code
    and Observer Agents. Bearer-auth via API keys (obs_pub_…), scoped per key.
    RFC 7807 problem-detail errors. Cursor pagination. Rate limits are per
    organization. Every date-time value is RFC 3339 in UTC with millisecond
    precision (`2026-01-31T12:00:00.000Z`).
servers:
  - url: https://use.observer/api/v1
security:
  - bearerAuth: []
paths:
  /pages/{id}:
    patch:
      tags:
        - pages
      summary: Change a status page's settings
      description: >-
        Changes only the fields sent; the rest keep their value. Works on any
        page of the organization, made in the console or by config apply (a
        config document that names the setting later sets it again). Not
        settable here: custom CSS, custom domains, and the access modes that
        carry credentials or allow-lists (password, IP allow-list, JWT,
        customer-scoped, SSO), which are set in the console. `access_mode:
        public` makes a protected page public and removes its access settings.
        `hide_branding: true` needs a plan that includes branding removal.
        `theme.preset` applies a theme preset and replaces the page's theme. The
        response is the page as GET /pages/{id} returns it, plus `changed`: the
        settings that changed.
      operationId: updatePage
      parameters:
        - name: id
          in: path
          required: true
          description: Page id.
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                title:
                  type: string
                  minLength: 2
                  maxLength: 120
                  description: Page title. A new page defaults to its subdomain.
                access_mode:
                  type: string
                  enum:
                    - public
                    - password
                    - ip_allowlist
                    - jwt
                    - customer_scoped
                    - sso
                  description: >-
                    Who can open the page. Only `public` can be set through the
                    API (it clears any password, allow-list or SSO setting); the
                    other modes carry credentials and are set in the console.
                    Restating the page's current mode is a no-op.
                layout:
                  type: string
                  enum:
                    - minimal
                    - aurora
                    - blueprint
                  description: Page layout.
                timezone:
                  type: string
                  description: >-
                    IANA time zone the page renders days and times in, e.g.
                    `Europe/London`. Default UTC.
                locale:
                  type: string
                  enum:
                    - en
                    - es
                    - fr
                    - de
                    - pt-BR
                    - it
                    - nl
                    - ja
                    - ar
                    - zh-CN
                  description: Page language. Default en.
                allow_subscriptions:
                  type: boolean
                  description: Visitors can subscribe to updates.
                show_auto_refresh:
                  type: boolean
                  description: Show the auto-refresh control.
                hide_branding:
                  type: boolean
                  description: >-
                    Hide the Powered by Observer footer link. Turning it on
                    needs a paid plan.
                footer_links:
                  type: array
                  maxItems: 5
                  items:
                    type: object
                    required:
                      - label
                      - href
                    additionalProperties: false
                    properties:
                      label:
                        type: string
                        minLength: 1
                        maxLength: 32
                      href:
                        type: string
                        minLength: 1
                        maxLength: 200
                  description: Links in the page footer, in order. Replaces the whole list.
                metric_group_order:
                  type:
                    - array
                    - 'null'
                  maxItems: 200
                  items:
                    type:
                      - string
                      - 'null'
                  description: >-
                    Metric group names in display order (null is the ungrouped
                    metrics). null restores the default order.
                metric_group_summary:
                  type: boolean
                  description: Show each metric group as one summary row.
                seo_description:
                  type:
                    - string
                    - 'null'
                  maxLength: 300
                  description: >-
                    Search engine description. Empty or null uses the generated
                    one.
                seo_noindex:
                  type: boolean
                  description: Ask search engines not to index the page.
                theme:
                  type: object
                  required:
                    - preset
                  additionalProperties: false
                  properties:
                    preset:
                      type: string
                      description: >-
                        Slug of a theme preset from the console's theme gallery
                        (for example `midnight`).
                  description: >-
                    Apply a theme preset. Replaces the page's theme colours,
                    fonts and spacing.
      responses:
        '200':
          description: ok
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PageDetail'
                  - type: object
                    properties:
                      changed:
                        type: array
                        items:
                          type: string
                        description: >-
                          Settings that changed (empty when the request changed
                          nothing).
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Daily-Limit:
              $ref: '#/components/headers/X-RateLimit-Daily-Limit'
            X-RateLimit-Daily-Remaining:
              $ref: '#/components/headers/X-RateLimit-Daily-Remaining'
            X-RateLimit-Daily-Reset:
              $ref: '#/components/headers/X-RateLimit-Daily-Reset'
        '400':
          description: '`invalid_json`: the body is not a JSON object.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '401':
          description: >-
            `unauthenticated`: no bearer token was sent, or the key is invalid
            or revoked. `detail` distinguishes the two.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '403':
          description: >-
            `forbidden`: the key lacks `write:config`.
            `plan_does_not_permit_api`: no public API on the plan.
            `feature_locked`: hiding the branding needs a paid plan.
            `item_suspended_plan`: the page is suspended because the
            organization is over its status page limit.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '404':
          description: >-
            `not_found`: no page with that id is available to this key. One
            owned by another organization, or an id that is not a valid UUID,
            returns the same response, so a 404 does not confirm that the id is
            unused.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '409':
          description: '`demo_readonly`: demo pages cannot be changed.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '422':
          description: >-
            `invalid_page_settings`: a field failed validation, is unknown, or
            is not writable through the API (`errors` lists `{ path, message
            }`). `access_mode_console_only`: the access mode needs credentials;
            set it in the console.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '429':
          description: >-
            `rate_limited`: the organization's per-minute or daily request limit
            is used up (`limit.window` says which). Limits are per organization,
            shared by every key. The response carries `Retry-After` and
            `retry_after`, in seconds.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-RateLimit-Limit:
              $ref: '#/components/headers/X-RateLimit-Limit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/X-RateLimit-Remaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/X-RateLimit-Reset'
            X-RateLimit-Daily-Limit:
              $ref: '#/components/headers/X-RateLimit-Daily-Limit'
            X-RateLimit-Daily-Remaining:
              $ref: '#/components/headers/X-RateLimit-Daily-Remaining'
            X-RateLimit-Daily-Reset:
              $ref: '#/components/headers/X-RateLimit-Daily-Reset'
        '500':
          description: '`internal_error`: an unhandled server error. Safe to retry.'
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - bearerAuth:
            - write:config
components:
  schemas:
    PageDetail:
      allOf:
        - type: object
          required:
            - id
            - title
            - subdomain
            - public_url
            - access_mode
          properties:
            id:
              type: string
              format: uuid
            title:
              type: string
            subdomain:
              type: string
            public_url:
              type: string
              format: uri
              description: >-
                Where the page is served: the custom domain when it is active,
                else the subdomain URL.
            access_mode:
              type: string
              description: public, password, sso, ip_allowlist, jwt or customer_scoped.
            layout:
              type: string
            timezone:
              type: string
            locale:
              type: string
            allow_subscriptions:
              type: boolean
            show_auto_refresh:
              type: boolean
            hide_branding:
              type: boolean
              description: >-
                The operator's choice; the footer link is hidden only on a plan
                that includes branding removal.
            footer_links:
              type: array
              items:
                type: object
                properties:
                  label:
                    type: string
                  href:
                    type: string
            metric_group_order:
              type:
                - array
                - 'null'
              items:
                type:
                  - string
                  - 'null'
            metric_group_summary:
              type: boolean
            seo_description:
              type:
                - string
                - 'null'
            seo_noindex:
              type: boolean
            custom_domain:
              type:
                - object
                - 'null'
              description: The custom domain, when one is set up (in the console).
              properties:
                domain:
                  type: string
                state:
                  type: string
                  description: >-
                    Provisioning state; public_url uses the domain only when
                    this is active.
                last_error:
                  type:
                    - string
                    - 'null'
                suspended:
                  type: boolean
                  description: >-
                    true while the domain stops resolving because the
                    organization is over its custom-domain limit (the subdomain
                    keeps working).
            config_key:
              type:
                - string
                - 'null'
              description: >-
                The page's key in config documents (null for one made in the
                console and never applied from config). Per-key DELETE takes
                this.
            managed_by:
              type: string
              enum:
                - config
                - console
              description: >-
                config: owned by config apply (prune and per-key delete may
                remove it). console: made in the console; config apply adopts it
                when a document names it.
            is_demo:
              type: boolean
            updated_at:
              type: string
              format: date-time
            suspended:
              type: boolean
              description: >-
                true while the status page is suspended because the organization
                is over its plan's limit (after a 7-day grace). Nothing is
                deleted; it is read-only until the person chooses it as active
                in Billing or upgrades. Writes return 403 `item_suspended_plan`.
            suspended_at:
              type:
                - string
                - 'null'
              format: date-time
              description: When the suspension started.
        - type: object
          properties:
            metrics:
              type: array
              description: >-
                The page's metrics in display order. public_label and
                show_uptime are console settings that config apply keeps.
              items:
                type: object
                properties:
                  metric_id:
                    type: string
                    format: uuid
                  config_key:
                    type:
                      - string
                      - 'null'
                  title:
                    type: string
                  group:
                    type:
                      - string
                      - 'null'
                  order:
                    type:
                      - integer
                      - 'null'
                  public_label:
                    type:
                      - string
                      - 'null'
                  show_uptime:
                    type: boolean
    Problem:
      type: object
      required:
        - type
        - title
        - status
      example:
        type: https://docs.use.observer/api/getting-started/errors#forbidden
        title: forbidden
        status: 403
        detail: 'missing scope: write:incidents'
      properties:
        type:
          type: string
          format: uri
          description: Errors reference URI with the title token as the fragment.
          example: https://docs.use.observer/api/getting-started/errors#forbidden
        title:
          type: string
          description: Stable error token. Branch on this, not on detail.
        status:
          type: integer
        detail:
          type: string
          description: Human-readable explanation. Wording may change.
        retry_after:
          type: integer
          description: >-
            429 only: seconds until the exhausted window resets (mirrors
            Retry-After).
        limit:
          type: object
          description: '429 only: which organization limit was hit.'
          properties:
            scope:
              type: string
              enum:
                - organization
            window:
              type: string
              enum:
                - minute
                - day
            max:
              type: integer
            plan:
              type: string
        errors:
          type: array
          description: >-
            Validation failures (config_invalid, invalid_customer_targeting):
            one entry per problem.
          items:
            type: object
            properties:
              path:
                type: string
              message:
                type: string
        warnings:
          type: array
          description: >-
            config_invalid only: the same non-fatal warnings a successful apply
            returns.
          items:
            type: object
            properties:
              path:
                type: string
              message:
                type: string
        unknown_customers:
          type: array
          description: >-
            unknown_customers only: the submitted values that matched no
            customer in your organization.
          items:
            type: string
        unknown_services:
          type: array
          description: >-
            unknown_services only: the submitted `affected_services` values that
            matched no service in your organization.
          items: {}
        referenced_by:
          type: object
          description: >-
            in_use only: what depends on the object (slos, pages: lists of { id,
            config_key, name }; subscribers: a count).
        quota:
          type: object
          description: >-
            quota_exceeded / feature_locked on a create, item_suspended_plan on
            a write to a suspended item: the plan limit involved.
          properties:
            capability:
              type: string
            used:
              type:
                - integer
                - 'null'
            cap:
              type:
                - integer
                - 'null'
            plan:
              type:
                - string
                - 'null'
        upgrade:
          type: object
          description: >-
            Plan-limit problems only, when a higher plan lifts the limit: the
            smallest such plan and the pricing page.
          properties:
            plan:
              type: string
            label:
              type: string
            url:
              type: string
              format: uri
  headers:
    X-RateLimit-Limit:
      description: Requests allowed per minute for the organization.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current minute.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Seconds until the per-minute window resets.
      schema:
        type: integer
    X-RateLimit-Daily-Limit:
      description: Requests allowed per UTC day for the organization.
      schema:
        type: integer
    X-RateLimit-Daily-Remaining:
      description: Requests left today (UTC).
      schema:
        type: integer
    X-RateLimit-Daily-Reset:
      description: Seconds until the daily quota resets (UTC midnight).
      schema:
        type: integer
    Retry-After:
      description: '429 only: seconds to wait before retrying.'
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: obs_pub_
      description: >-
        An organization API key (obs_pub_…) sent as `Authorization: Bearer
        <key>`. Each key carries scopes; an endpoint lists the scope it needs.
        `read:change_events` is reserved: keys can carry it, but no endpoint
        needs it yet.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.