# This file is generated by apps/frontend/scripts/public-api-contract.mjs. Do not edit.
openapi: 3.1.0
info:
  title: NiceUptime Public API
  version: 1.0.0
  summary: Initial stable public API contract.
  description: Stable public API contract. Only operations in this document are public API.
  license:
    name: Proprietary
    url: https://www.niceuptime.com/terms
servers:
  - url: https://api.niceuptime.com
    description: Public API
paths:
  /v1/monitors:
    get:
      tags:
        - monitors
      operationId: listMonitors
      summary: List tenant monitors.
      security:
        - managementAPIKeyBearer: []
      parameters:
        - $ref: "#/components/parameters/MonitorType"
        - $ref: "#/components/parameters/MonitorState"
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 200
            default: 100
        - name: cursor
          in: query
          required: false
          schema:
            type: string
        - name: include_observations
          in: query
          required: false
          description: Include up to 100 recent observations for each monitor. Defaults to false.
          schema:
            type: boolean
            default: false
      responses:
        "200":
          description: Monitors visible to the tenant.
          headers:
            RateLimit-Limit:
              description: Maximum requests allowed in the current minute window for this API key's tenant.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests remaining in the current minute window for this API key's tenant.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Seconds until the applicable rate-limit window resets.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Limit:
              description: Legacy alias of RateLimit-Limit.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Remaining:
              description: Legacy alias of RateLimit-Remaining.
              schema:
                type: integer
                minimum: 0
            X-RateLimit-Reset:
              description: Legacy alias of RateLimit-Reset.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                type: object
                required:
                  - monitors
                properties:
                  monitors:
                    type: array
                    items:
                      $ref: "#/components/schemas/Monitor"
                  next_cursor:
                    type: string
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          description: API-key management rate limit exceeded.
          headers:
            RateLimit-Limit:
              description: Maximum requests allowed in the current minute window for this API key's tenant.
              schema:
                type: integer
                minimum: 1
            RateLimit-Remaining:
              description: Requests remaining in the current minute window for this API key's tenant.
              schema:
                type: integer
                minimum: 0
            RateLimit-Reset:
              description: Seconds until the applicable rate-limit window resets.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Limit:
              description: Legacy alias of RateLimit-Limit.
              schema:
                type: integer
                minimum: 1
            X-RateLimit-Remaining:
              description: Legacy alias of RateLimit-Remaining.
              schema:
                type: integer
                minimum: 0
            X-RateLimit-Reset:
              description: Legacy alias of RateLimit-Reset.
              schema:
                type: integer
                minimum: 1
            Retry-After:
              description: Seconds to wait before retrying after a rejected request.
              schema:
                type: integer
                minimum: 1
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  parameters:
    MonitorType:
      name: type
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/MonitorType"
    MonitorState:
      name: state
      in: query
      required: false
      schema:
        $ref: "#/components/schemas/MonitorState"
  schemas:
    MonitorType:
      type: string
      enum:
        - pulse
        - probe
    MonitorState:
      type: string
      enum:
        - active
        - paused
        - archived
    Monitor:
      type: object
      additionalProperties: false
      required:
        - id
        - type
        - name
        - state
        - status
        - tags
        - policy
        - regions
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        type:
          $ref: "#/components/schemas/MonitorType"
        name:
          type: string
        state:
          $ref: "#/components/schemas/MonitorState"
        status:
          $ref: "#/components/schemas/MonitorStatus"
        tags:
          type: array
          items:
            $ref: "#/components/schemas/MonitorTag"
        policy:
          $ref: "#/components/schemas/MonitorPolicy"
        regions:
          type: array
          items:
            type: string
            pattern: ^[a-z]{2,16}-[a-z0-9-]{2,32}$
        probe:
          $ref: "#/components/schemas/ProbeConfig"
        observations:
          type: array
          items:
            $ref: "#/components/schemas/MonitorObservation"
        observation_policy:
          $ref: "#/components/schemas/ObservationPolicy"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    MonitorStatus:
      type: string
      description: Current Heartbeat-derived status. Read surfaces return `unknown` until a state snapshot exists.
      enum:
        - unknown
        - ok
        - late
        - failing
        - recovering
    MonitorTag:
      type: object
      additionalProperties: false
      required:
        - id
        - name
        - created_at
        - updated_at
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 40
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    MonitorPolicy:
      type: object
      additionalProperties: false
      required:
        - expected_interval_seconds
        - grace_seconds
        - failure_threshold
        - recovery_threshold
      properties:
        expected_interval_seconds:
          type: integer
          minimum: 30
        grace_seconds:
          type: integer
          minimum: 0
        failure_threshold:
          type: integer
          minimum: 1
        recovery_threshold:
          type: integer
          minimum: 1
    ProbeConfig:
      type: object
      additionalProperties: false
      required:
        - method
        - url
        - timeout_ms
        - expected_status
        - tls_policy
        - headers
      properties:
        method:
          type: string
          enum:
            - GET
            - HEAD
        url:
          type: string
          format: uri
          pattern: ^https?://
        timeout_ms:
          type: integer
          minimum: 500
          maximum: 30000
        expected_status:
          type: object
          additionalProperties: false
          required:
            - mode
          properties:
            mode:
              type: string
              enum:
                - class_2xx
                - class_3xx
                - explicit
            codes:
              type: array
              uniqueItems: true
              items:
                type: integer
                minimum: 100
                maximum: 599
        tls_policy:
          type: string
          enum:
            - default
            - require_valid
        headers:
          type: array
          maxItems: 20
          items:
            type: object
            additionalProperties: false
            required:
              - name
              - value
            properties:
              name:
                type: string
              value:
                type: string
                maxLength: 512
        assertions:
          type: array
          description: Max-plan tenants can create or modify response assertions. Lower-plan tenants may preserve an unchanged persisted list while updating unrelated Probe fields.
          maxItems: 10
          uniqueItems: true
          default: []
          items:
            type: object
            additionalProperties: false
            required:
              - kind
              - value
            properties:
              kind:
                type: string
                enum:
                  - body_contains
                  - json_pointer_equals
              pointer:
                type: string
                description: Required for json_pointer_equals and must be an RFC 6901 JSON Pointer.
              value:
                type: string
                minLength: 1
        body_hash:
          type:
            - string
            - "null"
          description: Reserved for non-MVP request-body probes.
    MonitorObservation:
      type: object
      additionalProperties: false
      required:
        - id
        - source
        - status
        - observed_at
      properties:
        id:
          type: string
          format: uuid
        source:
          type: string
        status:
          type: string
        observed_at:
          type: string
          format: date-time
        region:
          type: string
        latency_ms:
          type: integer
          minimum: 0
    ObservationPolicy:
      type: object
      additionalProperties: false
      required:
        - plan
        - visible_days
        - max_retention_days
        - response_windows
      properties:
        plan:
          type: string
          enum:
            - free
            - pro
            - max
        visible_days:
          type: integer
          minimum: 1
        max_retention_days:
          type: integer
          minimum: 1
        response_windows:
          type: array
          items:
            $ref: "#/components/schemas/ObservationResponseWindow"
    ObservationResponseWindow:
      type: object
      additionalProperties: false
      required:
        - label
        - seconds
      properties:
        label:
          type: string
        seconds:
          type: integer
          minimum: 1
    Error:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          $ref: "#/components/schemas/ErrorBody"
      examples:
        - error:
            code: validation_error
            message: validation failed
            fields:
              - name: price_id
                message: price_id must match configured pro plan
    ErrorBody:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
        message:
          type: string
        fields:
          type: array
          items:
            $ref: "#/components/schemas/ErrorField"
        support_code:
          type: string
          pattern: ^REQ-[A-Z0-9]{1,8}$
        occurred_at:
          type: string
          format: date-time
    ErrorField:
      type: object
      additionalProperties: false
      required:
        - name
        - message
      properties:
        name:
          type: string
        message:
          type: string
  responses:
    BadRequest:
      description: Invalid input.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Missing, expired, or invalid credentials.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
  securitySchemes:
    managementAPIKeyBearer:
      type: http
      scheme: bearer
      description: Management API key beginning with nu_live_. Supported only on operations that name this scheme.
