components:
  schemas:
    Budget:
      additionalProperties: false
      properties:
        amount:
          type: string
        created_at:
          format: date-time
          type: string
        created_by:
          type: string
        currency:
          type: string
        custom_period:
          $ref: "#/components/schemas/TimePeriod"
        enabled:
          type: boolean
        filter:
          $ref: "#/components/schemas/Filter"
        id:
          type: string
        name:
          type: string
        period:
          type: string
        project_id:
          type: string
        revision:
          format: int64
          type: integer
        status:
          $ref: "#/components/schemas/Status"
          description: Spend and threshold states for the current window as of its latest
            check, or null before the window's first check.
        thresholds:
          items:
            $ref: "#/components/schemas/Threshold"
          type:
            - array
            - "null"
        updated_at:
          format: date-time
          type: string
      required:
        - id
        - name
        - project_id
        - enabled
        - amount
        - currency
        - period
        - filter
        - thresholds
        - revision
        - created_by
        - created_at
        - updated_at
        - status
      type: object
    BudgetSpec:
      additionalProperties: false
      properties:
        amount:
          description: Budgeted amount per window, as a decimal string.
          pattern: ^[0-9]+(\.[0-9]+)?$
          type: string
        currency:
          description: Defaults to, and must equal, the currency your costs are reported in.
          type: string
        custom_period:
          $ref: "#/components/schemas/TimePeriod"
          description: Required when period is custom, at most 366 days.
        enabled:
          description: Defaults to true. A disabled budget is not checked and sends no
            alerts.
          type: boolean
        filter:
          $ref: "#/components/schemas/Filter"
        name:
          maxLength: 64
          minLength: 1
          type: string
        period:
          description: Calendar periods reset in UTC; custom is one fixed window.
          enum:
            - daily
            - monthly
            - quarterly
            - yearly
            - custom
          type: string
        project_id:
          description: The project the budget belongs to and measures. Omitted, it is the
            caller's own project.
          maxLength: 255
          type: string
        thresholds:
          items:
            $ref: "#/components/schemas/ThresholdSpec"
          maxItems: 10
          minItems: 1
          type:
            - array
            - "null"
      required:
        - name
        - amount
        - period
        - thresholds
      type: object
    Channel:
      additionalProperties: false
      properties:
        address:
          type: string
        created_at:
          format: date-time
          type: string
        created_by:
          type: string
        id:
          type: string
        name:
          type: string
        project_id:
          type: string
        secret:
          description: A webhook's signing secret. It is returned only when the channel is
            created and when the secret is rotated.
          type: string
        status:
          enum:
            - pending_confirmation
            - confirmed
          type: string
        type:
          type: string
        url:
          type: string
      required:
        - id
        - name
        - project_id
        - type
        - status
        - created_by
        - created_at
      type: object
    ChannelSpec:
      additionalProperties: false
      properties:
        address:
          description: "For an email channel: the address. It receives nothing until its
            owner follows the confirmation link sent to it."
          maxLength: 254
          type: string
        name:
          maxLength: 64
          minLength: 1
          type: string
        project_id:
          description: The owning project. Omitted, it is the caller's own project.
          maxLength: 255
          type: string
        type:
          enum:
            - email
            - webhook
          type: string
        url:
          description: "For a webhook channel: an https URL on a public address.
            Deliveries are signed; see X-Budget-Signature."
          maxLength: 2048
          type: string
      required:
        - name
        - type
      type: object
    ChannelsOutputBody:
      additionalProperties: false
      properties:
        channels:
          items:
            $ref: "#/components/schemas/Channel"
          type:
            - array
            - "null"
      required:
        - channels
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
    ErrorModel:
      additionalProperties: false
      properties:
        detail:
          description: A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: "#/components/schemas/ErrorDetail"
          type:
            - array
            - "null"
        instance:
          description: A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
      type: object
    Filter:
      additionalProperties: false
      properties:
        regions:
          description: Regions to count. Empty counts every region.
          items:
            type: string
          maxItems: 100
          type:
            - array
            - "null"
        services:
          description: Services to count. Empty counts every service.
          items:
            enum:
              - compute
              - image
              - volume
            type: string
          maxItems: 3
          type:
            - array
            - "null"
        usage_types:
          description: Usage types to count. Empty counts every usage type.
          items:
            type: string
          maxItems: 100
          type:
            - array
            - "null"
      type: object
    ListOutputBody:
      additionalProperties: false
      properties:
        budgets:
          items:
            $ref: "#/components/schemas/Budget"
          type:
            - array
            - "null"
      required:
        - budgets
      type: object
    Notification:
      additionalProperties: false
      properties:
        attempts:
          format: int64
          type: integer
        channel_id:
          type: string
        created_at:
          format: date-time
          type: string
        id:
          format: int64
          type: integer
        last_error:
          type: string
        observed:
          type: string
        sent_at:
          format: date-time
          type: string
        status:
          enum:
            - pending
            - sent
            - failed
          type: string
        target_amount:
          type: string
        threshold:
          type: string
        time_period:
          $ref: "#/components/schemas/TimePeriod"
      required:
        - id
        - threshold
        - channel_id
        - time_period
        - target_amount
        - observed
        - status
        - attempts
        - created_at
      type: object
    NotificationsOutputBody:
      additionalProperties: false
      properties:
        notifications:
          items:
            $ref: "#/components/schemas/Notification"
          type:
            - array
            - "null"
      required:
        - notifications
      type: object
    Status:
      additionalProperties: false
      properties:
        actual_spend:
          type: string
        amount:
          description: The budget amount the thresholds were judged against.
          type: string
        as_of:
          description: When the spend was measured.
          format: date-time
          type: string
        currency:
          type: string
        data_through:
          description: How far the usage data is complete. Spend after this is not counted
            yet.
          format: date-time
          type: string
        estimated:
          description: "Always true: costs are computed from usage and a price catalogue."
          type: boolean
        evaluated_at:
          format: date-time
          type: string
        forecast_spend:
          description: Linear projection for the whole window; null until enough of it has
            elapsed.
          type:
            - string
            - "null"
        thresholds:
          items:
            $ref: "#/components/schemas/ThresholdStatus"
          type:
            - array
            - "null"
        time_period:
          $ref: "#/components/schemas/TimePeriod"
      required:
        - time_period
        - evaluated_at
        - as_of
        - data_through
        - currency
        - amount
        - actual_spend
        - forecast_spend
        - thresholds
        - estimated
      type: object
    Threshold:
      additionalProperties: false
      properties:
        basis:
          type: string
        channels:
          items:
            type: string
          type:
            - array
            - "null"
        comparison:
          type: string
        enabled:
          type: boolean
        message:
          type: string
        name:
          type: string
        unit:
          type: string
        value:
          type: string
      required:
        - name
        - basis
        - unit
        - value
        - comparison
        - enabled
        - channels
      type: object
    ThresholdSpec:
      additionalProperties: false
      properties:
        basis:
          description: Judge spend so far (actual) or the projection for the whole window
            (forecasted).
          enum:
            - actual
            - forecasted
          type: string
        channels:
          description: Configured notification channels to alert when the threshold enters
            alarm. With none the threshold still tracks its state.
          items:
            type: string
          maxItems: 10
          type:
            - array
            - "null"
        comparison:
          description: Defaults to greater_than_or_equal.
          enum:
            - greater_than
            - greater_than_or_equal
            - less_than
            - less_than_or_equal
          type: string
        enabled:
          description: Defaults to true.
          type: boolean
        message:
          description: Text included in the alert.
          maxLength: 1000
          type: string
        name:
          description: Unique within the budget. State is tracked by name, so renaming a
            threshold restarts it.
          maxLength: 64
          minLength: 1
          type: string
        unit:
          description: Whether value is a percentage of the budget amount or an amount in
            its currency.
          enum:
            - percentage
            - absolute
          type: string
        value:
          description: Decimal string.
          pattern: ^[0-9]+(\.[0-9]+)?$
          type: string
      required:
        - name
        - basis
        - unit
        - value
      type: object
    ThresholdStatus:
      additionalProperties: false
      properties:
        changed_at:
          description: When the threshold last entered or left alarm in this window.
          format: date-time
          type: string
        name:
          type: string
        observed:
          type:
            - string
            - "null"
        state:
          enum:
            - ok
            - alarm
            - unevaluated
            - disabled
          type: string
        target_amount:
          type: string
      required:
        - name
        - state
        - target_amount
        - observed
      type: object
    TimePeriod:
      additionalProperties: false
      properties:
        end:
          description: Exclusive end (RFC 3339).
          format: date-time
          type: string
        start:
          description: Inclusive start (RFC 3339).
          format: date-time
          type: string
      required:
        - start
        - end
      type: object
    UpdateSpec:
      additionalProperties: false
      properties:
        amount:
          description: Budgeted amount per window, as a decimal string.
          pattern: ^[0-9]+(\.[0-9]+)?$
          type: string
        currency:
          description: Defaults to, and must equal, the currency your costs are reported in.
          type: string
        custom_period:
          $ref: "#/components/schemas/TimePeriod"
          description: Required when period is custom, at most 366 days.
        enabled:
          description: Defaults to true. A disabled budget is not checked and sends no
            alerts.
          type: boolean
        filter:
          $ref: "#/components/schemas/Filter"
        name:
          maxLength: 64
          minLength: 1
          type: string
        period:
          description: Calendar periods reset in UTC; custom is one fixed window.
          enum:
            - daily
            - monthly
            - quarterly
            - yearly
            - custom
          type: string
        project_id:
          description: The project the budget belongs to and measures. Omitted, it is the
            caller's own project.
          maxLength: 255
          type: string
        revision:
          description: The revision the budget was read at. A stale revision is refused
            with 409.
          format: int64
          minimum: 1
          type: integer
        thresholds:
          items:
            $ref: "#/components/schemas/ThresholdSpec"
          maxItems: 10
          minItems: 1
          type:
            - array
            - "null"
      required:
        - revision
        - name
        - amount
        - period
        - thresholds
      type: object
    WindowsOutputBody:
      additionalProperties: false
      properties:
        windows:
          items:
            $ref: "#/components/schemas/Status"
          type:
            - array
            - "null"
      required:
        - windows
      type: object
  securitySchemes:
    keystone:
      in: header
      name: X-Auth-Token
      type: apiKey
info:
  description: Spending limits for projects, with alerts by email or webhook when
    spend or its forecast crosses a threshold.
  title: Budget
  version: 0.0.0-dev
openapi: 3.1.0
paths:
  /v1/budgets:
    get:
      description: Lists the budgets of your token's project, each with the status of
        its current window.
      operationId: list_budgets
      parameters:
        - description: The project whose budgets to list. Defaults to your token's
            project; naming another project is refused with 403.
          explode: false
          in: query
          name: project_id
          schema:
            description: The project whose budgets to list. Defaults to your token's
              project; naming another project is refused with 403.
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListOutputBody"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: List budgets
      tags:
        - Budgets
    post:
      operationId: create_budget
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BudgetSpec"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Budget"
          description: Created
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Create a budget
      tags:
        - Budgets
  /v1/budgets/{budget_id}:
    delete:
      operationId: delete_budget
      parameters:
        - description: Budget identifier.
          in: path
          name: budget_id
          required: true
          schema:
            description: Budget identifier.
            type: string
      responses:
        "204":
          description: No Content
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Delete a budget and its history
      tags:
        - Budgets
    get:
      operationId: get_budget
      parameters:
        - description: Budget identifier.
          in: path
          name: budget_id
          required: true
          schema:
            description: Budget identifier.
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Budget"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Get a budget and the status of its current window
      tags:
        - Budgets
    put:
      description: The body carries the revision the budget was read at; a stale one
        is refused with 409.
      operationId: update_budget
      parameters:
        - description: Budget identifier.
          in: path
          name: budget_id
          required: true
          schema:
            description: Budget identifier.
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateSpec"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Budget"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Replace a budget
      tags:
        - Budgets
  /v1/budgets/{budget_id}/notifications:
    get:
      operationId: list_budget_notifications
      parameters:
        - description: Budget identifier.
          in: path
          name: budget_id
          required: true
          schema:
            description: Budget identifier.
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 50
            format: int64
            maximum: 500
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/NotificationsOutputBody"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: List a budget's alerts and their delivery, newest first
      tags:
        - Budgets
  /v1/budgets/{budget_id}/windows:
    get:
      operationId: list_budget_windows
      parameters:
        - description: Budget identifier.
          in: path
          name: budget_id
          required: true
          schema:
            description: Budget identifier.
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 50
            format: int64
            maximum: 500
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WindowsOutputBody"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: List a budget's past and current windows, newest first
      tags:
        - Budgets
  /v1/notification_channels:
    get:
      operationId: list_notification_channels
      parameters:
        - description: The project whose channels to list. Defaults to your token's
            project; naming another project is refused with 403.
          explode: false
          in: query
          name: project_id
          schema:
            description: The project whose channels to list. Defaults to your token's
              project; naming another project is refused with 403.
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChannelsOutputBody"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: List notification channels
      tags:
        - Notification channels
    post:
      description: An email channel is sent a confirmation link and receives nothing
        until it is followed. A webhook channel is usable at once; its signing
        secret is in this response only.
      operationId: create_notification_channel
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChannelSpec"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Channel"
          description: Created
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Create a notification channel
      tags:
        - Notification channels
  /v1/notification_channels/{channel_id}:
    delete:
      description: Refused with 409 while a budget's threshold names it.
      operationId: delete_notification_channel
      parameters:
        - description: Notification channel identifier.
          in: path
          name: channel_id
          required: true
          schema:
            description: Notification channel identifier.
            type: string
      responses:
        "204":
          description: No Content
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Delete a notification channel
      tags:
        - Notification channels
    get:
      operationId: get_notification_channel
      parameters:
        - description: Notification channel identifier.
          in: path
          name: channel_id
          required: true
          schema:
            description: Notification channel identifier.
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Channel"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Get a notification channel
      tags:
        - Notification channels
  /v1/notification_channels/{channel_id}/resend_confirmation:
    post:
      description: At most one is sent every ten minutes.
      operationId: resend_channel_confirmation
      parameters:
        - description: Notification channel identifier.
          in: path
          name: channel_id
          required: true
          schema:
            description: Notification channel identifier.
            type: string
      responses:
        "202":
          description: Accepted
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Send an email channel's confirmation link again
      tags:
        - Notification channels
  /v1/notification_channels/{channel_id}/rotate_secret:
    post:
      operationId: rotate_channel_secret
      parameters:
        - description: Notification channel identifier.
          in: path
          name: channel_id
          required: true
          schema:
            description: Notification channel identifier.
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Channel"
          description: OK
        "400":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Bad Request
        "401":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unauthorized
        "403":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Forbidden
        "404":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Not Found
        "409":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Conflict
        "422":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Unprocessable Entity
        "500":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Internal Server Error
        "503":
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/ErrorModel"
          description: Service Unavailable
      summary: Replace a webhook channel's signing secret
      tags:
        - Notification channels
security:
  - keystone: []
servers:
  - url: https://budget.public.global.vexxhost.net
tags:
  - name: Budgets
  - name: Notification channels
