# Proposed contract, version 1: endpoints, errors, paging, idempotency, security and the capability of every
# operation. Status: proposal for review, not confirmed design. Conventions: docs/05-interfaces/choosing-an-interface.md.
# Vendor extensions: x-moonitoring-audience (who calls), x-moonitoring-capability (the capability checked),
# x-moonitoring-requirements (the requirements of 1.requisiti-raffinati.txt the operation serves; none yet for status).
openapi: 3.1.0
info:
  title: Status Incidents API
  version: 1.0.0
  description: Components, incidents, maintenances and probes of the status page. Called by the Console.
servers:
- url: https://console.moonitoring.com/api/status/incidents/v1
  description: Prod, through the Console's host
- url: https://stage-console.moonitoring.com/api/status/incidents/v1
  description: Stage, through the Console's host
security:
- bearer: []
tags:
- name: Components
- name: Incidents
- name: Maintenances
- name: Probes
paths:
  /components:
    get:
      summary: List components
      operationId: listComponents
      description: Every component with its current status and who set it.
      tags:
      - Components
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Component'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.read
      x-moonitoring-requirements: []
  /components/{component_id}:
    patch:
      summary: Set a component's status
      operationId: updateComponent
      description: Overrides what the probes say, or hands the status back to them. Every change is an audit event.
      tags:
      - Components
      parameters:
      - name: component_id
        in: path
        required: true
        schema:
          type: string
        description: The component.
      - &id001
        $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IfMatch
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComponentInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Component'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '412':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/PreconditionFailed
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.components.manage
      x-moonitoring-requirements: []
  /incidents:
    get:
      summary: List incidents
      operationId: listIncidents
      description: Newest first; open ones first when `open=true`.
      tags:
      - Incidents
      parameters:
      - name: open
        in: query
        required: false
        schema:
          type: boolean
      - &id003
        $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - &id004
        $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Incident'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.read
      x-moonitoring-requirements: []
    post:
      summary: Open an incident
      operationId: openIncident
      description: Opens an incident with its first update and sets the status of the components it names.
      tags:
      - Incidents
      parameters:
      - &id002
        $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IncidentInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Incident'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.manage
      x-moonitoring-requirements: []
  /incidents/{incident_id}:
    get:
      summary: Read an incident
      operationId: getIncident
      description: With every update, newest first.
      tags:
      - Incidents
      parameters:
      - name: incident_id
        in: path
        required: true
        schema:
          type: string
        description: The incident.
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Incident'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.read
      x-moonitoring-requirements: []
    patch:
      summary: Change an incident
      operationId: updateIncident
      description: Title, impact, the components and their status, the postmortem link.
      tags:
      - Incidents
      parameters:
      - name: incident_id
        in: path
        required: true
        schema:
          type: string
        description: The incident.
      - *id001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IncidentPatch'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Incident'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '412':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/PreconditionFailed
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.manage
      x-moonitoring-requirements: []
  /incidents/{incident_id}/updates:
    post:
      summary: Post an update
      operationId: postIncidentUpdate
      description: A new message and status. `resolved` closes the incident and returns its components to the probes.
      tags:
      - Incidents
      parameters:
      - name: incident_id
        in: path
        required: true
        schema:
          type: string
        description: The incident.
      - *id002
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IncidentUpdateInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Incident'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.manage
      x-moonitoring-requirements: []
  /maintenances:
    get:
      summary: List maintenances
      operationId: listMaintenances
      description: Upcoming and in progress first.
      tags:
      - Maintenances
      parameters:
      - *id003
      - *id004
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Maintenance'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.read
      x-moonitoring-requirements: []
    post:
      summary: Schedule a maintenance
      operationId: scheduleMaintenance
      description: Announced on the page.
      tags:
      - Maintenances
      parameters:
      - *id002
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MaintenanceInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Maintenance'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.manage
      x-moonitoring-requirements: []
  /maintenances/{maintenance_id}:
    patch:
      summary: Change a maintenance
      operationId: updateMaintenance
      description: Move it, edit it, start, verify or complete it, or cancel it before it starts.
      tags:
      - Maintenances
      parameters:
      - name: maintenance_id
        in: path
        required: true
        schema:
          type: string
        description: The maintenance.
      - *id001
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MaintenancePatch'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Maintenance'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '412':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/PreconditionFailed
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.manage
      x-moonitoring-requirements: []
  /probes:
    get:
      summary: List probes
      operationId: listProbes
      description: Every probe with its last result.
      tags:
      - Probes
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Probe'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.incidents.read
      x-moonitoring-requirements: []
  /probes/{probe_id}:
    patch:
      summary: Pause or resume a probe
      operationId: updateProbe
      description: A paused probe changes no status; the page shows the component as staff left it.
      tags:
      - Probes
      parameters:
      - name: probe_id
        in: path
        required: true
        schema:
          type: string
        description: The probe.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProbeInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Probe'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: staff
      x-moonitoring-capability: status.components.manage
      x-moonitoring-requirements: []
components:
  schemas:
    Component:
      type: object
      description: One thing a customer uses, as the page lists it.
      properties:
        component_id:
          type: string
          description: Stable, such as `sign-in` or `farm-sync`.
        group:
          type: string
          description: The group it is shown under, such as `platform` or `apps`.
        name: &id005
          type: object
          description: The same text in every language of the page; Italian and English.
          properties:
            it:
              type: string
              maxLength: 4000
            en:
              type: string
              maxLength: 4000
          required:
          - it
          - en
        description: *id005
        status: &id006
          type: string
          enum:
          - operational
          - degraded_performance
          - partial_outage
          - major_outage
          - under_maintenance
          description: What a person using the component sees now.
        status_source:
          type: string
          enum:
          - probes
          - staff
          description: Whether the probes or a member of staff set the current status.
        public:
          type: boolean
          description: Shown on the public page; stage pages show every component.
        position:
          type: integer
        updated_at: &id007
          type: string
          format: date-time
        version:
          type: integer
      required:
      - component_id
      - group
      - name
      - status
      - status_source
      - public
      - position
      - updated_at
      - version
    ComponentInput:
      type: object
      properties:
        status: *id006
        description: *id005
        release_to_probes:
          type: boolean
          description: Hands the status back to the probes after a manual override.
    Incident:
      type: object
      properties:
        incident_id:
          type: string
        title: *id005
        status: &id008
          type: string
          enum:
          - investigating
          - identified
          - monitoring
          - resolved
        impact: &id009
          type: string
          enum:
          - none
          - minor
          - major
          - critical
          description: How bad it is for customers; drives the colour of the page's banner.
        components:
          type: array
          items:
            type: object
            properties:
              component_id:
                type: string
              status: *id006
            required:
            - component_id
            - status
        opened_by:
          type: string
          enum:
          - probes
          - staff
        updates:
          type: array
          items:
            $ref: '#/components/schemas/IncidentUpdate'
          description: Newest first.
        postmortem_url:
          type: string
          format: uri
        started_at: *id007
        identified_at: *id007
        monitoring_at: *id007
        resolved_at: *id007
        version:
          type: integer
      required:
      - incident_id
      - title
      - status
      - impact
      - components
      - opened_by
      - updates
      - started_at
      - version
    IncidentUpdate:
      type: object
      properties:
        update_id:
          type: string
        status: *id008
        body: *id005
        posted_at: *id007
        posted_by:
          type: string
          description: The staff member's public name, or `Monitoring` for probes.
      required:
      - update_id
      - status
      - body
      - posted_at
      - posted_by
    IncidentInput:
      type: object
      properties:
        title: *id005
        impact: *id009
        body: *id005
        components:
          type: array
          minItems: 1
          items:
            type: object
            properties:
              component_id:
                type: string
              status: *id006
            required:
            - component_id
            - status
      required:
      - title
      - impact
      - body
      - components
    IncidentPatch:
      type: object
      properties:
        title: *id005
        impact: *id009
        postmortem_url:
          type: string
          format: uri
        components:
          type: array
          items:
            type: object
            properties:
              component_id:
                type: string
              status: *id006
            required:
            - component_id
            - status
    IncidentUpdateInput:
      type: object
      properties:
        status: *id008
        body: *id005
      required:
      - status
      - body
    Maintenance:
      type: object
      properties:
        maintenance_id:
          type: string
        title: *id005
        body: *id005
        status: &id010
          type: string
          enum:
          - scheduled
          - in_progress
          - verifying
          - completed
          - cancelled
        components:
          type: array
          items:
            type: string
        scheduled_for: *id007
        scheduled_until: *id007
        started_at: *id007
        completed_at: *id007
        version:
          type: integer
      required:
      - maintenance_id
      - title
      - body
      - status
      - components
      - scheduled_for
      - scheduled_until
      - version
    MaintenanceInput:
      type: object
      properties:
        title: *id005
        body: *id005
        components:
          type: array
          minItems: 1
          items:
            type: string
        scheduled_for: *id007
        scheduled_until: *id007
      required:
      - title
      - body
      - components
      - scheduled_for
      - scheduled_until
    MaintenancePatch:
      type: object
      properties:
        title: *id005
        body: *id005
        status: *id010
        scheduled_for: *id007
        scheduled_until: *id007
    Probe:
      type: object
      description: A check the prober runs every minute.
      properties:
        probe_id:
          type: string
        component_id:
          type: string
        kind:
          type: string
          enum:
          - http_health
          - journey
        target:
          type: string
          description: What it calls, such as `https://api.moonitoring.com/access/health`.
        paused:
          type: boolean
        last_result:
          type: string
          enum:
          - pass
          - slow
          - fail
        last_run_at: *id007
        latency_ms_p95:
          type: integer
          description: Over the last hour.
      required:
      - probe_id
      - component_id
      - kind
      - target
      - paused
    ProbeInput:
      type: object
      properties:
        paused:
          type: boolean
      required:
      - paused
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: The short-lived staff token signed by `access`, sent by the Console through its own host.
