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

# Create

> Ask for a pay report to be generated.

Generating a report can take minutes for a wide date window, so this returns as soon as
we have accepted the request, with a report that has a status of pending and no totals.
Fetch the report to find out how it went: it ends up either complete, with its totals
filled in, or failed, with error_code and error_message saying why.

Reports are created as drafts.

🔑 Requires the `schedule_reports.create` scope.


## OpenAPI

````yaml /openapi/tags/pay-reports-v2.json post /v2/pay_reports
openapi: 3.0.3
info:
  description: "This is the API reference for incident.io.\n\nIt documents available API endpoints, provides examples of how to use it, and\ninstructions around things like authentication and error handling.\n\nThe API is hosted at:\n\n- https://api.incident.io/\n\nAnd you will need to create an API key via your [incident.io\ndashboard](https://app.incident.io/settings/api-keys) to make requests.\n\n# Making requests\n\nHere are the key concepts required to make requests to the incident.io API.\n\n## Authentication\n\nFor all requests made to the incident.io API, you'll need an API key.\n\nTo create an API key, head to the incident dashboard and visit [API\nkeys](https://app.incident.io/settings/api-keys). When you create the key, you'll be able to choose what actions it\ncan take for your account: choose carefully, as those roles can only be set\nwhen you first create the key. We'll only show you the token once, so make sure\nyou store it somewhere safe.\n\nAPI keys are global to your incident.io account, and can be managed by anyone\nwho has the right permissions. We display the user that created the API key,\nand the API key will remain valid if that user becomes deactivated.\n\nOnce you have the key, you should make requests to the API that set the\n`Authorization` request header using a \"Bearer\" authentication scheme:\n\n```\nAuthorization: Bearer <YOUR_API_KEY>\n```\n\n## Rate Limits\n\nThe incident.io API enforces rate limits to ensure consistent performance for all users.\n\nThe default rate limit is 1200 requests/minute per API key. This limit applies to most endpoints across the API.\n\nLimits are token buckets that refill continuously rather than resetting on a fixed window boundary. The default\nbucket holds 1200 requests and refills at 20 per second, so you can burst up to the full bucket and then sustain\n20 requests/second indefinitely. There is no boundary at which your quota resets to full in one step.\n\nSome endpoints have lower rate limits, particularly those that interact with external third-party systems that impose\ntheir own limitations. These specific limits vary by endpoint.\n\n### Rate limit headers\n\nResponses to requests authenticated with an API key carry your current allowance, so you can pace yourself rather\nthan waiting to be throttled:\n\n```\nX-RateLimit-Limit: 60, 1200;window=60, 60;window=60\nX-RateLimit-Remaining: 59\nX-RateLimit-Used: 1\nX-RateLimit-Reset: 1785173199\n```\n\n| Header | Meaning |\n| --- | --- |\n| `X-RateLimit-Limit` | The quota that binds this request, followed by every limit that applied and the window it applies over |\n| `X-RateLimit-Remaining` | Requests you can make right now against the binding limit |\n| `X-RateLimit-Used` | Requests you have spent against it |\n| `X-RateLimit-Reset` | Unix timestamp (seconds) at which that limit will be back to full |\n\nMore than one limit can apply to a request: your API key's overall limit, and for some endpoints a lower limit of\ntheir own. `X-RateLimit-Limit` lists all of them, each with its window, so `1200;window=60` means 1200 requests per\nminute. Because our limits refill continuously rather than resetting on a boundary, that window is what tells you\nthe rate you can sustain: 1200 per 60 seconds is 20 requests/second indefinitely.\n\n`Remaining`, `Used` and `Reset` describe whichever limit has the least allowance left, since that is the one you\nwill hit first.\n\n`X-RateLimit-Remaining` may lag by a small number of requests under high concurrency, and can move by more than the\nrequests you made, because limits scoped to your whole organisation are shared with your other API keys.\n\nHeaders are omitted rather than guessed if we cannot determine your allowance for a request.\n\n### Exceeding a rate limit\n\nWhen you exceed a rate limit the API responds with `429 Too Many Requests` and a `Retry-After` header giving the\nnumber of seconds to wait:\n\n```\nX-RateLimit-Limit: 1200, 1200;window=60\nX-RateLimit-Remaining: 0\nX-RateLimit-Used: 1200\nX-RateLimit-Reset: 1785173199\nRetry-After: 1\n```\n\nPrefer `Retry-After` over `X-RateLimit-Reset` when deciding how long to back off. `Retry-After` is when a single\nrequest will succeed; `X-RateLimit-Reset` is the later point at which your whole allowance has returned. It is a\nduration rather than a timestamp, so it does not depend on your clock agreeing with ours.\n\nThe 429 also carries a JSON body with the same information:\n\n```json\n{\n    \"type\": \"too_many_requests\",\n    \"status\": 429,\n    \"request_id\": \"b839a403-7704-41c1-bf6a-39a2d68caefa\",\n    \"rate_limit\": {\n        \"name\": \"api_key_name\",\n        \"limit\": 1200,\n        \"remaining\": 0,\n        \"retry_after\": \"2025-04-17T11:17:18Z\"\n    },\n    \"errors\": [\n        {\n            \"code\": \"too_many_requests\",\n            \"message\": \"Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.\"\n        }\n    ]\n}\n```\n\nThe response includes:\n* The name of the API key (`name`)\n* The bucket limit (`limit`)\n* The number of requests remaining (`remaining`)\n* When you can retry requests (`retry_after`), as an RFC3339 timestamp\n\n## Errors\n\nWe use standard HTTP response codes to indicate the status or failure of API\nrequests.\n\nThe API response body will be JSON, and contain more detailed information on the\nnature of the error.\n\nAn example error when a request is made without an API key:\n\n```json\n{\n  \"type\": \"authentication_error\",\n  \"status\": 401,\n  \"request_id\": \"8e3cc412-b49d-4957-9073-2c19d2c61804\",\n  \"errors\": [\n    {\n      \"code\": \"missing_authorization_material\",\n      \"message\": \"No authorization material provided in request\"\n    }\n  ]\n}\n```\n\nNote that the error:\n\n- Contains the HTTP status (`401`)\n- References the type of error (`authentication_error`)\n- Includes a `request_id` that can be provided to incident.io support to help\n\tdebug questions with your API request\n- Provides a list of individual errors, which go into detail about why the error\n\toccurred\n\nThe most common error will be a 422 Validation Error, which is returned when the\nrequest was rejected due to failing validations.\n\nThese errors look like this:\n\n```json\n{\n  \"type\": \"validation_error\",\n  \"status\": 422,\n  \"request_id\": \"631766c4-4afd-4803-997c-cd700928fa4b\",\n  \"errors\": [\n    {\n      \"code\": \"is_required\",\n      \"message\": \"A severity is required to open an incident\",\n      \"source\": {\n        \"field\": \"severity_id\"\n      }\n    }\n  ]\n}\n```\n\nThis error is caused by not providing a severity identifier, which should be at\nthe `severity_id` field of the request payload. Errors like these can be mapped to\nforms, should you be integrating with the API from a user-interface.\n\n## Compatibility\n\nWe won't make breaking changes to existing API services or endpoints, but will\nexpect integrators to upgrade themselves to the latest API endpoints within 3\nmonths of us deprecating the old service.\n\nWe will make changes that are considered backwards compatible, which include:\n\n- Adding new API endpoints and services\n- Adding new properties to responses from existing API endpoints\n- Reordering properties returned from existing API endpoints\n- Adding optional request parameters to existing API endpoints\n- Altering the format or length of IDs\n- Adding new values to enums\n\nIt is important that clients are robust to these changes, to ensure reliable\nintegrations.\n\nAs an example, if you are generating a client using an openapi-generator, ensure\nthe generated client is configured to support unknown enum values, often\nconfigured via the `enumUnknownDefaultCase` parameter.\n\nWhen breaking changes are unavoidable, we'll create a new service version on a\nseparate path, and run them in parallel.\n\nFor example:\n\n- https://api.incident.io/v1/incidents\n- https://api.incident.io/v2/incidents\n\nFor any questions, email support@incident.io.\n"
  title: incident.io
  version: 1.0.0
servers:
  - url: https://api.incident.io
security:
  - BearerAuth: []
tags:
  - description: >-
      View and manage on-call pay reports, which value the time users spent
      on-call over a date window.
    name: Pay Reports V2
paths:
  /v2/pay_reports:
    post:
      tags:
        - Pay Reports V2
      summary: Create
      description: >-
        Ask for a pay report to be generated.


        Generating a report can take minutes for a wide date window, so this
        returns as soon as

        we have accepted the request, with a report that has a status of pending
        and no totals.

        Fetch the report to find out how it went: it ends up either complete,
        with its totals

        filled in, or failed, with error_code and error_message saying why.


        Reports are created as drafts.
      operationId: Pay Reports V2_Create
      requestBody:
        content:
          application/json:
            example:
              end_date: '2026-03-31'
              name: March 2026
              overlapping_shifts: paid_per_schedule
              pay_config_expression:
                else_branch:
                  result:
                    array_value:
                      - literal: SEV123
                        reference: incident.severity
                    value:
                      literal: SEV123
                      reference: incident.severity
                label: Team Slack channel
                operations:
                  - branches:
                      branches:
                        - condition_groups:
                            - conditions:
                                - operation: one_of
                                  param_bindings:
                                    - array_value:
                                        - literal: SEV123
                                          reference: incident.severity
                                      value:
                                        literal: SEV123
                                        reference: incident.severity
                                  subject: incident.severity
                          result:
                            array_value:
                              - literal: SEV123
                                reference: incident.severity
                            value:
                              literal: SEV123
                              reference: incident.severity
                      returns:
                        array: true
                        type: IncidentStatus
                    cast:
                      returns:
                        array: true
                        type: IncidentStatus
                    concatenate:
                      reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
                    filter:
                      condition_groups:
                        - conditions:
                            - operation: one_of
                              param_bindings:
                                - array_value:
                                    - literal: SEV123
                                      reference: incident.severity
                                  value:
                                    literal: SEV123
                                    reference: incident.severity
                              subject: incident.severity
                    navigate:
                      reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
                    operation_type: navigate
                    parse:
                      returns:
                        array: true
                        type: IncidentStatus
                      source: metadata.annotations["github.com/repo"]
                reference: abc123
                root_reference: incident.status
              pay_config_id: 01G0J1EXE7AXZ2C93K61WBPYEH
              rotation_filters:
                - rotation_ids:
                    - primary
                  schedule_id: 01G0J1EXE7AXZ2C93K61WBPYEH
              schedule_ids:
                - 01FCNDV6P870EA6S7TK1DSYDG0
              start_date: '2026-03-01'
              unpaid_shifts: excluded
            schema:
              $ref: '#/components/schemas/PayReportsCreatePayloadV2'
        required: true
      responses:
        '202':
          content:
            application/json:
              example:
                pay_report:
                  created_at: '2026-04-01T09:00:00Z'
                  creator:
                    alert:
                      id: 01GW2G3V0S59R238FAHPDS1R66
                      title: '*errors.withMessage: PG::Error failed to connect'
                    api_key:
                      id: 01FCNDV6P870EA6S7TK1DSYDG0
                      name: My test API key
                    user:
                      email: lisa@incident.io
                      id: 01FCNDV6P870EA6S7TK1DSYDG0
                      name: Lisa Karlin Curtis
                      role: owner
                      slack_user_id: U02AYNF2XJM
                    workflow:
                      id: 01FCNDV6P870EA6S7TK1DSYDG0
                      name: My little workflow
                  end_date: '2026-03-31'
                  error_code: timed_out
                  error_message: >-
                    Schedule 'Primary Support' has no pay config to price its
                    shifts with
                  id: 01G0J1EXE7AXZ2C93K61WBPYEH
                  name: March 2026
                  overlapping_shifts: paid_per_schedule
                  published_at: '2026-04-01T09:00:00Z'
                  schedule_ids:
                    - 01FCNDV6P870EA6S7TK1DSYDG0
                  start_date: '2026-03-01'
                  status: generating
                  total_duration_seconds: 3600
                  total_pay_by_currency:
                    GBP: 2400
                  unpaid_shifts: excluded
                  updated_at: '2026-04-01T09:00:00Z'
              schema:
                $ref: '#/components/schemas/PayReportsCreateResultV2'
          description: Accepted response.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            invalid_request_error: There was a problem with the request, like a
            missing header or querying a resource that doesn't exist.
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'authentication_error: Authentication failed.'
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            resource_forbidden: Access to this resource is forbidden for the
            authenticated user.
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'not_found: The referenced resource could not be found.'
        '405':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            method_not_allowed: The endpoint does not support this operation for
            the specified resource.
        '406':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            not_acceptable: Requested a media type this endpoint does not
            support.
        '408':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: |-
            request_timeout: The request took too long to process.

            client_timeout: The request was cancelled by the client.
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            conflict: Request conflicted with current state of the resource,
            likely a concurrent update.
        '412':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'precondition_failed: A required condition hasn''t been met.'
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'payload_too_large: The request payload is too large.'
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            validation_error: A required field was not provided, or the provided
            data was invalid.
        '429':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: >-
            too_many_requests: Too many requests hit the API too quickly. We
            recommend an exponential backoff of your requests.


            rate_limit_reached: The rate limit associated with this resource or
            API key has been exceeded. Try again later.
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'api_error: Something went wrong and has been reported internally.'
components:
  schemas:
    PayReportsCreatePayloadV2:
      example:
        end_date: '2026-03-31'
        name: March 2026
        overlapping_shifts: paid_per_schedule
        pay_config_expression:
          else_branch:
            result:
              array_value:
                - literal: SEV123
                  reference: incident.severity
              value:
                literal: SEV123
                reference: incident.severity
          label: Team Slack channel
          operations:
            - branches:
                branches:
                  - condition_groups:
                      - conditions:
                          - operation: one_of
                            param_bindings:
                              - array_value:
                                  - literal: SEV123
                                    reference: incident.severity
                                value:
                                  literal: SEV123
                                  reference: incident.severity
                            subject: incident.severity
                    result:
                      array_value:
                        - literal: SEV123
                          reference: incident.severity
                      value:
                        literal: SEV123
                        reference: incident.severity
                returns:
                  array: true
                  type: IncidentStatus
              cast:
                returns:
                  array: true
                  type: IncidentStatus
              concatenate:
                reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
              filter:
                condition_groups:
                  - conditions:
                      - operation: one_of
                        param_bindings:
                          - array_value:
                              - literal: SEV123
                                reference: incident.severity
                            value:
                              literal: SEV123
                              reference: incident.severity
                        subject: incident.severity
              navigate:
                reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
              operation_type: navigate
              parse:
                returns:
                  array: true
                  type: IncidentStatus
                source: metadata.annotations["github.com/repo"]
          reference: abc123
          root_reference: incident.status
        pay_config_id: 01G0J1EXE7AXZ2C93K61WBPYEH
        rotation_filters:
          - rotation_ids:
              - primary
            schedule_id: 01G0J1EXE7AXZ2C93K61WBPYEH
        schedule_ids:
          - 01FCNDV6P870EA6S7TK1DSYDG0
        start_date: '2026-03-01'
        unpaid_shifts: excluded
      properties:
        end_date:
          description: Last date (YYYY-MM-DD) to include shifts from, inclusive
          example: '2026-03-31'
          type: string
        name:
          description: Human readable name for this report
          example: March 2026
          type: string
        overlapping_shifts:
          description: >-
            How to pay time spent on more than one of these schedules at once.
            paid_once requires the advanced on-call plan.
          enum:
            - paid_once
            - paid_per_schedule
          example: paid_per_schedule
          type: string
        pay_config_expression:
          $ref: '#/components/schemas/ExpressionPayloadV2'
        pay_config_id:
          description: >-
            The pay config to price every shift with. Provide this or
            pay_config_expression, and not both.
          example: 01G0J1EXE7AXZ2C93K61WBPYEH
          minLength: 1
          type: string
        rotation_filters:
          description: >-
            Narrows some of these schedules to a subset of their rotations. A
            schedule that does not appear here includes every rotation.
          example:
            - rotation_ids:
                - primary
              schedule_id: 01G0J1EXE7AXZ2C93K61WBPYEH
          items:
            $ref: '#/components/schemas/PayReportRotationFilterV2'
          type: array
        schedule_ids:
          description: Which schedules to report on
          example:
            - 01FCNDV6P870EA6S7TK1DSYDG0
          items:
            example: abc123
            type: string
          type: array
        start_date:
          description: First date (YYYY-MM-DD) to include shifts from, inclusive
          example: '2026-03-01'
          type: string
        unpaid_shifts:
          description: >-
            Whether shifts that price to zero count towards
            total_duration_seconds
          enum:
            - included
            - excluded
          example: excluded
          type: string
      required:
        - name
        - start_date
        - end_date
        - schedule_ids
      type: object
    PayReportsCreateResultV2:
      example:
        pay_report:
          created_at: '2026-04-01T09:00:00Z'
          creator:
            alert:
              id: 01GW2G3V0S59R238FAHPDS1R66
              title: '*errors.withMessage: PG::Error failed to connect'
            api_key:
              id: 01FCNDV6P870EA6S7TK1DSYDG0
              name: My test API key
            user:
              email: lisa@incident.io
              id: 01FCNDV6P870EA6S7TK1DSYDG0
              name: Lisa Karlin Curtis
              role: owner
              slack_user_id: U02AYNF2XJM
            workflow:
              id: 01FCNDV6P870EA6S7TK1DSYDG0
              name: My little workflow
          end_date: '2026-03-31'
          error_code: timed_out
          error_message: >-
            Schedule 'Primary Support' has no pay config to price its shifts
            with
          id: 01G0J1EXE7AXZ2C93K61WBPYEH
          name: March 2026
          overlapping_shifts: paid_per_schedule
          published_at: '2026-04-01T09:00:00Z'
          schedule_ids:
            - 01FCNDV6P870EA6S7TK1DSYDG0
          start_date: '2026-03-01'
          status: generating
          total_duration_seconds: 3600
          total_pay_by_currency:
            GBP: 2400
          unpaid_shifts: excluded
          updated_at: '2026-04-01T09:00:00Z'
      properties:
        pay_report:
          $ref: '#/components/schemas/PayReportV2'
      required:
        - pay_report
      type: object
    ErrorResponse:
      example:
        debug:
          message: 'Something broke: and something else: and something else'
          stacktrace:
            - thing.go:123
        errors:
          - code: trial_expired
            message: Default incident call link must be a valid URL
            metadata:
              abc123: abc123
            source:
              field: default_call_url
              pointer: /settings/default_call_url
        rate_limit:
          limit: 100
          name: client_ip
          remaining: 98
          retry_after: '2020-01-01T00:00:00Z'
        request_id: 2T1p0e3j
        status: 408
        type: invalid_request_error
      properties:
        debug:
          $ref: '#/components/schemas/ErrorDebug'
        errors:
          description: List of errors that caused this request to fail
          example:
            - code: trial_expired
              message: Default incident call link must be a valid URL
              metadata:
                abc123: abc123
              source:
                field: default_call_url
                pointer: /settings/default_call_url
          items:
            $ref: '#/components/schemas/ErrorSingle'
          type: array
        rate_limit:
          $ref: '#/components/schemas/ErrorRateLimit'
        request_id:
          description: Unique identifier of the request
          example: 2T1p0e3j
          type: string
        status:
          description: HTTP status of the response
          example: 408
          format: int64
          type: integer
        type:
          description: Machine-readable identifier for the general category of error
          enum:
            - invalid_request_error
            - authentication_error
            - resource_forbidden
            - not_found
            - not_acceptable
            - method_not_allowed
            - request_timeout
            - conflict
            - precondition_failed
            - payload_too_large
            - validation_error
            - too_many_requests
            - api_error
            - rate_limit_reached
            - client_timeout
          example: invalid_request_error
          type: string
      required:
        - type
        - status
        - request_id
        - errors
      type: object
    ExpressionPayloadV2:
      example:
        else_branch:
          result:
            array_value:
              - literal: SEV123
                reference: incident.severity
            value:
              literal: SEV123
              reference: incident.severity
        label: Team Slack channel
        operations:
          - branches:
              branches:
                - condition_groups:
                    - conditions:
                        - operation: one_of
                          param_bindings:
                            - array_value:
                                - literal: SEV123
                                  reference: incident.severity
                              value:
                                literal: SEV123
                                reference: incident.severity
                          subject: incident.severity
                  result:
                    array_value:
                      - literal: SEV123
                        reference: incident.severity
                    value:
                      literal: SEV123
                      reference: incident.severity
              returns:
                array: true
                type: IncidentStatus
            cast:
              returns:
                array: true
                type: IncidentStatus
            concatenate:
              reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
            filter:
              condition_groups:
                - conditions:
                    - operation: one_of
                      param_bindings:
                        - array_value:
                            - literal: SEV123
                              reference: incident.severity
                          value:
                            literal: SEV123
                            reference: incident.severity
                      subject: incident.severity
            navigate:
              reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
            operation_type: navigate
            parse:
              returns:
                array: true
                type: IncidentStatus
              source: metadata.annotations["github.com/repo"]
        reference: abc123
        root_reference: incident.status
      properties:
        else_branch:
          $ref: '#/components/schemas/ExpressionElseBranchPayloadV2'
        label:
          description: The human readable label of the expression
          example: Team Slack channel
          type: string
        operations:
          example:
            - branches:
                branches:
                  - condition_groups:
                      - conditions:
                          - operation: one_of
                            param_bindings:
                              - array_value:
                                  - literal: SEV123
                                    reference: incident.severity
                                value:
                                  literal: SEV123
                                  reference: incident.severity
                            subject: incident.severity
                    result:
                      array_value:
                        - literal: SEV123
                          reference: incident.severity
                      value:
                        literal: SEV123
                        reference: incident.severity
                returns:
                  array: true
                  type: IncidentStatus
              cast:
                returns:
                  array: true
                  type: IncidentStatus
              concatenate:
                reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
              filter:
                condition_groups:
                  - conditions:
                      - operation: one_of
                        param_bindings:
                          - array_value:
                              - literal: SEV123
                                reference: incident.severity
                            value:
                              literal: SEV123
                              reference: incident.severity
                        subject: incident.severity
              navigate:
                reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
              operation_type: navigate
              parse:
                returns:
                  array: true
                  type: IncidentStatus
                source: metadata.annotations["github.com/repo"]
          items:
            $ref: '#/components/schemas/ExpressionOperationPayloadV2'
          type: array
        reference:
          description: A short ID that can be used to reference the expression
          example: abc123
          type: string
        root_reference:
          description: >-
            The root reference for this expression (i.e. where the expression
            starts)
          example: incident.status
          type: string
      required:
        - label
        - reference
        - root_reference
        - operations
      type: object
    PayReportRotationFilterV2:
      description: Narrows one of a report's schedules to some of its rotations.
      example:
        rotation_ids:
          - primary
        schedule_id: 01G0J1EXE7AXZ2C93K61WBPYEH
      properties:
        rotation_ids:
          description: >-
            Which of the schedule's rotations to include. To include all of
            them, leave this schedule out of rotation_filters rather than
            listing every rotation here.
          example:
            - primary
          items:
            example: abc123
            type: string
          minItems: 1
          type: array
        schedule_id:
          description: The schedule to narrow. Must also appear in schedule_ids.
          example: 01G0J1EXE7AXZ2C93K61WBPYEH
          type: string
      required:
        - schedule_id
        - rotation_ids
      type: object
    PayReportV2:
      description: >-
        A pay report values the time a set of users spent on-call over a date
        window, using the rates from a pay config.


        Reports are immutable snapshots: once generated, changing the pay config
        or the

        schedules behind it will not change the report. Generate a new one
        instead.


        A report starts as a draft and becomes visible to everyone in your
        organisation when

        you publish it.


        Reports are generated in the background, so a report you have just asked
        for has no

        totals yet. Its status says whether they are still coming, and a report
        that failed

        carries the reason it will never have them.
      properties:
        created_at:
          description: When this report was created
          example: '2026-04-01T09:00:00Z'
          format: date-time
          type: string
        creator:
          $ref: '#/components/schemas/ActorV2'
        end_date:
          description: Last date (YYYY-MM-DD) this report includes shifts from, inclusive
          example: '2026-03-31'
          type: string
        error_code:
          description: Why a report could not be generated
          enum:
            - invalid_request
            - timed_out
          example: timed_out
          type: string
          x-public-api-version: v2
        error_message:
          description: >-
            What went wrong, written for whoever asked for the report. Only set
            on a failed report.
          example: >-
            Schedule 'Primary Support' has no pay config to price its shifts
            with
          type: string
        id:
          description: Unique identifier for this pay report
          example: 01G0J1EXE7AXZ2C93K61WBPYEH
          type: string
        name:
          description: Human readable name for this report
          example: March 2026
          type: string
        overlapping_shifts:
          description: How time spent on more than one schedule at once was paid
          enum:
            - paid_once
            - paid_per_schedule
          example: paid_per_schedule
          type: string
          x-public-api-version: v2
        published_at:
          description: >-
            When this report was published. Unset while the report is still a
            draft.
          example: '2026-04-01T09:00:00Z'
          format: date-time
          type: string
        schedule_ids:
          description: The schedules this report covers
          example:
            - 01FCNDV6P870EA6S7TK1DSYDG0
          items:
            example: abc123
            type: string
          type: array
        start_date:
          description: First date (YYYY-MM-DD) this report includes shifts from, inclusive
          example: '2026-03-01'
          type: string
        status:
          description: How far a report has got through being generated
          enum:
            - pending
            - generating
            - complete
            - failed
          example: generating
          type: string
          x-public-api-version: v2
        total_duration_seconds:
          description: >-
            Total time spent on-call across every shift in this report, in
            seconds. Unset until the report is complete, and for a legacy
            report, which we do not summarise.
          example: 3600
          format: int64
          type: integer
        total_pay_by_currency:
          additionalProperties:
            example: 1
            format: int64
            type: integer
          description: >-
            Total owed for this report, keyed by ISO 4217 currency code, in the
            lowest denomination of that currency. Reports spanning pay configs
            with different currencies have an entry per currency, and those
            totals must not be summed. Unset until the report is complete, and
            for a legacy report, which we do not summarise.
          example:
            GBP: 2400
          type: object
        unpaid_shifts:
          description: Whether shifts that priced to zero are part of the report
          enum:
            - included
            - excluded
          example: excluded
          type: string
          x-public-api-version: v2
        updated_at:
          description: When this report was last updated
          example: '2026-04-01T09:00:00Z'
          format: date-time
          type: string
      required:
        - id
        - name
        - start_date
        - end_date
        - schedule_ids
        - status
        - overlapping_shifts
        - unpaid_shifts
        - created_at
        - updated_at
      type: object
    ErrorDebug:
      example:
        message: 'Something broke: and something else: and something else'
        stacktrace:
          - thing.go:123
      properties:
        message:
          description: Original internal error message
          example: 'Something broke: and something else: and something else'
          type: string
        stacktrace:
          description: Stacktrace of the error, if applicable
          example:
            - thing.go:123
          items:
            example: thing.go:123
            type: string
          type: array
      required:
        - message
        - stacktrace
      type: object
    ErrorSingle:
      example:
        code: trial_expired
        message: Default incident call link must be a valid URL
        metadata:
          abc123: abc123
        source:
          field: default_call_url
          pointer: /settings/default_call_url
      properties:
        code:
          description: Machine-readable identifier for this specific error
          example: trial_expired
          type: string
        message:
          description: Human readable description of the error
          example: Default incident call link must be a valid URL
          type: string
        metadata:
          additionalProperties:
            example: abc123
            type: string
          description: Additional metadata about the error, keyed by a string identifier
          example:
            abc123: abc123
          type: object
        source:
          $ref: '#/components/schemas/ErrorSource'
      required:
        - code
        - message
      type: object
    ErrorRateLimit:
      example:
        limit: 100
        name: client_ip
        remaining: 98
        retry_after: '2020-01-01T00:00:00Z'
      properties:
        limit:
          description: >-
            The maximum number of requests that the consumer is permitted to
            make per minute
          example: 100
          format: int64
          type: integer
        name:
          description: Which rate limit was exceeded
          example: client_ip
          type: string
        remaining:
          description: The number of requests remaining in the current rate limit window
          example: 98
          format: int64
          type: integer
        retry_after:
          description: >-
            When the client can retry, as an RFC3339 timestamp in UTC. Prefer
            the Retry-After response header, which carries the same instant as a
            number of seconds
          example: '2020-01-01T00:00:00Z'
          type: string
      required:
        - name
        - limit
        - remaining
        - retry_after
      type: object
    ExpressionElseBranchPayloadV2:
      example:
        result:
          array_value:
            - literal: SEV123
              reference: incident.severity
          value:
            literal: SEV123
            reference: incident.severity
      properties:
        result:
          $ref: '#/components/schemas/EngineParamBindingPayloadV2'
      required:
        - result
      type: object
    ExpressionOperationPayloadV2:
      example:
        branches:
          branches:
            - condition_groups:
                - conditions:
                    - operation: one_of
                      param_bindings:
                        - array_value:
                            - literal: SEV123
                              reference: incident.severity
                          value:
                            literal: SEV123
                            reference: incident.severity
                      subject: incident.severity
              result:
                array_value:
                  - literal: SEV123
                    reference: incident.severity
                value:
                  literal: SEV123
                  reference: incident.severity
          returns:
            array: true
            type: IncidentStatus
        cast:
          returns:
            array: true
            type: IncidentStatus
        concatenate:
          reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
        filter:
          condition_groups:
            - conditions:
                - operation: one_of
                  param_bindings:
                    - array_value:
                        - literal: SEV123
                          reference: incident.severity
                      value:
                        literal: SEV123
                        reference: incident.severity
                  subject: incident.severity
        navigate:
          reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
        operation_type: navigate
        parse:
          returns:
            array: true
            type: IncidentStatus
          source: metadata.annotations["github.com/repo"]
      properties:
        branches:
          $ref: '#/components/schemas/ExpressionBranchesOptsPayloadV2'
        cast:
          $ref: '#/components/schemas/ExpressionCastOptsPayloadV2'
        concatenate:
          $ref: '#/components/schemas/ExpressionConcatenateOptsPayloadV2'
        filter:
          $ref: '#/components/schemas/ExpressionFilterOptsPayloadV2'
        navigate:
          $ref: '#/components/schemas/ExpressionNavigateOptsPayloadV2'
        operation_type:
          description: The type of the operation
          enum:
            - navigate
            - filter
            - concatenate
            - count
            - min
            - max
            - sum
            - random
            - first
            - parse
            - branches
            - cast
          example: navigate
          type: string
        parse:
          $ref: '#/components/schemas/ExpressionParseOptsPayloadV2'
      required:
        - operation_type
      type: object
    ActorV2:
      example:
        alert:
          id: 01GW2G3V0S59R238FAHPDS1R66
          title: '*errors.withMessage: PG::Error failed to connect'
        api_key:
          id: 01FCNDV6P870EA6S7TK1DSYDG0
          name: My test API key
        user:
          email: lisa@incident.io
          id: 01FCNDV6P870EA6S7TK1DSYDG0
          name: Lisa Karlin Curtis
          role: owner
          slack_user_id: U02AYNF2XJM
        workflow:
          id: 01FCNDV6P870EA6S7TK1DSYDG0
          name: My little workflow
      properties:
        alert:
          $ref: '#/components/schemas/AlertActorV2'
        api_key:
          $ref: '#/components/schemas/APIKeyActorV2'
        user:
          $ref: '#/components/schemas/UserV2'
        workflow:
          $ref: '#/components/schemas/WorkflowActorV2'
      type: object
    ErrorSource:
      example:
        field: default_call_url
        pointer: /settings/default_call_url
      properties:
        field:
          description: Field name that is the source of the error
          example: default_call_url
          type: string
        pointer:
          description: JSON pointer to the request field that is the source of the error
          example: /settings/default_call_url
          type: string
      required:
        - field
        - pointer
      type: object
    EngineParamBindingPayloadV2:
      example:
        array_value:
          - literal: SEV123
            reference: incident.severity
        value:
          literal: SEV123
          reference: incident.severity
      properties:
        array_value:
          description: If set, this is the array value of the step parameter
          example:
            - literal: SEV123
              reference: incident.severity
          items:
            $ref: '#/components/schemas/EngineParamBindingValuePayloadV2'
          type: array
        value:
          $ref: '#/components/schemas/EngineParamBindingValuePayloadV2'
      type: object
    ExpressionBranchesOptsPayloadV2:
      example:
        branches:
          - condition_groups:
              - conditions:
                  - operation: one_of
                    param_bindings:
                      - array_value:
                          - literal: SEV123
                            reference: incident.severity
                        value:
                          literal: SEV123
                          reference: incident.severity
                    subject: incident.severity
            result:
              array_value:
                - literal: SEV123
                  reference: incident.severity
              value:
                literal: SEV123
                reference: incident.severity
        returns:
          array: true
          type: IncidentStatus
      properties:
        branches:
          description: The branches to apply for this operation
          example:
            - condition_groups:
                - conditions:
                    - operation: one_of
                      param_bindings:
                        - array_value:
                            - literal: SEV123
                              reference: incident.severity
                          value:
                            literal: SEV123
                            reference: incident.severity
                      subject: incident.severity
              result:
                array_value:
                  - literal: SEV123
                    reference: incident.severity
                value:
                  literal: SEV123
                  reference: incident.severity
          items:
            $ref: '#/components/schemas/ExpressionBranchPayloadV2'
          type: array
        returns:
          $ref: '#/components/schemas/ReturnsMetaV2'
      required:
        - branches
        - returns
      type: object
    ExpressionCastOptsPayloadV2:
      example:
        returns:
          array: true
          type: IncidentStatus
      properties:
        returns:
          $ref: '#/components/schemas/ReturnsMetaV2'
      required:
        - returns
      type: object
    ExpressionConcatenateOptsPayloadV2:
      example:
        reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
      properties:
        reference:
          description: The reference that you want to concatenate with
          example: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
          type: string
      required:
        - reference
      type: object
    ExpressionFilterOptsPayloadV2:
      example:
        condition_groups:
          - conditions:
              - operation: one_of
                param_bindings:
                  - array_value:
                      - literal: SEV123
                        reference: incident.severity
                    value:
                      literal: SEV123
                      reference: incident.severity
                subject: incident.severity
      properties:
        condition_groups:
          description: >-
            The condition groups to apply in this filter. Only one group needs
            to be satisfied for the filter to pass.
          example:
            - conditions:
                - operation: one_of
                  param_bindings:
                    - array_value:
                        - literal: SEV123
                          reference: incident.severity
                      value:
                        literal: SEV123
                        reference: incident.severity
                  subject: incident.severity
          items:
            $ref: '#/components/schemas/ConditionGroupPayloadV2'
          type: array
      required:
        - condition_groups
      type: object
    ExpressionNavigateOptsPayloadV2:
      example:
        reference: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
      properties:
        reference:
          description: The reference that you want to navigate to
          example: catalog_attribute["01FCNDV6P870EA6S7TK1DSYD5H"]
          type: string
      required:
        - reference
      type: object
    ExpressionParseOptsPayloadV2:
      example:
        returns:
          array: true
          type: IncidentStatus
        source: metadata.annotations["github.com/repo"]
      properties:
        returns:
          $ref: '#/components/schemas/ReturnsMetaV2'
        source:
          description: Source expression that is evaluated to a result
          example: metadata.annotations["github.com/repo"]
          type: string
      required:
        - source
        - returns
      type: object
    AlertActorV2:
      example:
        id: 01GW2G3V0S59R238FAHPDS1R66
        title: '*errors.withMessage: PG::Error failed to connect'
      properties:
        id:
          description: The ID of this alert
          example: 01GW2G3V0S59R238FAHPDS1R66
          type: string
        title:
          description: >-
            The title of the alert, parsed from the alert payload according to
            the alert source configuration
          example: '*errors.withMessage: PG::Error failed to connect'
          type: string
      required:
        - id
        - title
      type: object
    APIKeyActorV2:
      example:
        id: 01FCNDV6P870EA6S7TK1DSYDG0
        name: My test API key
      properties:
        id:
          description: Unique identifier for this API key
          example: 01FCNDV6P870EA6S7TK1DSYDG0
          type: string
        name:
          description: The name of the API key, for the user's reference
          example: My test API key
          type: string
      required:
        - id
        - name
      type: object
    UserV2:
      example:
        email: lisa@incident.io
        id: 01FCNDV6P870EA6S7TK1DSYDG0
        name: Lisa Karlin Curtis
        role: owner
        slack_user_id: U02AYNF2XJM
      properties:
        email:
          description: Email address of the user.
          example: lisa@incident.io
          type: string
        id:
          description: Unique identifier of the user
          example: 01FCNDV6P870EA6S7TK1DSYDG0
          type: string
        name:
          description: Name of the user
          example: Lisa Karlin Curtis
          type: string
        role:
          description: >-
            DEPRECATED: Role of the user as of March 9th 2023, this value is no
            longer updated.
          enum:
            - viewer
            - responder
            - administrator
            - owner
            - unset
          example: owner
          type: string
        slack_user_id:
          description: Slack ID of the user
          example: U02AYNF2XJM
          type: string
      required:
        - role
        - id
        - name
      type: object
    WorkflowActorV2:
      example:
        id: 01FCNDV6P870EA6S7TK1DSYDG0
        name: My little workflow
      properties:
        id:
          description: Unique identifier for the workflow
          example: 01FCNDV6P870EA6S7TK1DSYDG0
          type: string
        name:
          description: Name provided by the user when creating the workflow
          example: My little workflow
          type: string
      required:
        - id
        - name
      type: object
    EngineParamBindingValuePayloadV2:
      example:
        literal: SEV123
        reference: incident.severity
      properties:
        literal:
          description: If set, this is the literal value of the step parameter
          example: SEV123
          type: string
        reference:
          description: >-
            If set, this is the reference into the trigger scope that is the
            value of this parameter
          example: incident.severity
          type: string
      type: object
    ExpressionBranchPayloadV2:
      example:
        condition_groups:
          - conditions:
              - operation: one_of
                param_bindings:
                  - array_value:
                      - literal: SEV123
                        reference: incident.severity
                    value:
                      literal: SEV123
                      reference: incident.severity
                subject: incident.severity
        result:
          array_value:
            - literal: SEV123
              reference: incident.severity
          value:
            literal: SEV123
            reference: incident.severity
      properties:
        condition_groups:
          description: >-
            When one of these condition groups are satisfied, this branch will
            be evaluated
          example:
            - conditions:
                - operation: one_of
                  param_bindings:
                    - array_value:
                        - literal: SEV123
                          reference: incident.severity
                      value:
                        literal: SEV123
                        reference: incident.severity
                  subject: incident.severity
          items:
            $ref: '#/components/schemas/ConditionGroupPayloadV2'
          type: array
        result:
          $ref: '#/components/schemas/EngineParamBindingPayloadV2'
      required:
        - condition_groups
        - result
      type: object
    ReturnsMetaV2:
      example:
        array: true
        type: IncidentStatus
      properties:
        array:
          description: Whether the return value should be single or multi-value
          example: true
          type: boolean
        type:
          description: >-
            Expected return type of this expression (what to try casting the
            result to)
          example: IncidentStatus
          type: string
      required:
        - type
        - array
      type: object
    ConditionGroupPayloadV2:
      example:
        conditions:
          - operation: one_of
            param_bindings:
              - array_value:
                  - literal: SEV123
                    reference: incident.severity
                value:
                  literal: SEV123
                  reference: incident.severity
            subject: incident.severity
      properties:
        conditions:
          description: >-
            All conditions in this list must be satisfied for the group to be
            satisfied
          example:
            - operation: one_of
              param_bindings:
                - array_value:
                    - literal: SEV123
                      reference: incident.severity
                  value:
                    literal: SEV123
                    reference: incident.severity
              subject: incident.severity
          items:
            $ref: '#/components/schemas/ConditionPayloadV2'
          type: array
      required:
        - conditions
      type: object
    ConditionPayloadV2:
      example:
        operation: one_of
        param_bindings:
          - array_value:
              - literal: SEV123
                reference: incident.severity
            value:
              literal: SEV123
              reference: incident.severity
        subject: incident.severity
      properties:
        operation:
          description: The name of the operation on the subject
          example: one_of
          type: string
        param_bindings:
          description: List of parameter bindings
          example:
            - array_value:
                - literal: SEV123
                  reference: incident.severity
              value:
                literal: SEV123
                reference: incident.severity
          items:
            $ref: '#/components/schemas/EngineParamBindingPayloadV2'
          type: array
        subject:
          description: The reference of the subject in the trigger scope
          example: incident.severity
          type: string
      required:
        - subject
        - operation
        - param_bindings
      type: object
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key from your incident.io dashboard (Settings → API keys)

````