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

# Get workflow insights

> The aggregate figures for a workflow over a reporting window: volumes by
outcome, return rate, average end-to-end time, active submitters and per-step
timings with box-plot quartiles.

Everything is derived from the workflow's transition records, under the caller's
own access — a principal whose grants reach only part of the workflow's activity
sees figures for that part. A submission that has never transitioned does not
appear, and a submission whose earlier transitions predate the window is counted
from its first transition inside it.

It also carries the transition volume over time, bucketed at the width asked
for, so an activity chart does not need the records themselves.

The window is required. Optionally narrow the figures to a scheme's or a
contract's submissions, and ask for `include_baseline=true` to get the unscoped
figures alongside them for comparison.

Served by a hand-written handler rather than a generated one, because the
resource is computed rather than stored.




## OpenAPI

````yaml /api-reference/openapi.yaml get /v3/workflow-definitions/{workflow_definition_id}/insights
openapi: 3.1.0
info:
  contact:
    email: support@ctrl-hub.com
    name: Ctrl Hub
    url: https://www.ctrl-hub.com
  description: >
    Ctrl Hub is the all-in-one platform for high-risk industries like utilities,
    construction, infrastructure, and renewables. We help teams manage
    everything from risk assessments and HAVS exposure to vehicle and equipment
    checks, with a guaranteed minimum of 200% ROI.
  license:
    name: MIT License
    url: https://opensource.org/licenses/MIT
  summary: An API for managing your compliance and risk posture
  termsOfService: https://www.ctrl-hub.com/terms-conditions
  title: Ctrl Hub
  version: 1.0.0
servers:
  - description: Production
    url: https://api.ctrl-hub.com
  - description: Staging
    url: https://api.ctrl-hub.dev
  - description: Development
    url: https://api.ctrl-hub.run
security: []
tags:
  - description: |
      Actions are follow-ups assigned to users and teams, produced manually or
      by domain producers such as the data-capture workflow runner.
    name: Actions
  - description: |
      Audit events are the events that are logged by the system.
    name: Audit Events
  - description: |
      View the platform's health and availability.
    name: Status
  - description: >
      User-owned dashboards composed of cards on a fixed-slot bento layout.
      Cards come from a per-domain registry; the API stores their config as
      opaque JSON.
    name: Dashboards
  - description: >
      A record of documents the platform generated and handed over, retained as
      evidence of what

      was issued. `subject_type` says what kind of records an export covers, and
      it is what decides

      how the request is authorised: there is no export permission of its own,
      so if you can see the

      records you can export them.
    name: Exports
  - description: >
      Scheduled delivery of a saved query's results, as a CSV attachment or a
      summary email. Every run is retained with the file it sent, so what a
      recipient received stays retrievable. A report runs as the person who
      created it, under their own access.
    name: Reports
  - description: |
      Manage appointments for work to be carried out with your customers
    name: Customer Appointments
  - description: |
      Manage interactions you have with your customers
    name: Customer Interactions
  - description: |
      Manage accounts for your customers
    name: Customer Accounts and Contacts
  - description: |
      Qualifications are the skills and knowledge that an organisation requires.
    name: Qualifications
  - description: |
      Workflows allow you to automate your processes.
    name: Workflows
  - description: |
      Manage documents
    name: Documents
  - description: |
      Manage documents
    name: Folders
  - description: |
      Manage documents
    name: Document Reviews
  - description: |
      Manage feature configurations for an organisation.
    name: Feature Configurations
  - description: |
      Equipment are the physical assets that an organisation manages.
    name: Equipment
  - description: |
      The central cost register: time-versioned rate codes for material, labour,
      contractor and miscellaneous spend, used to cost work against the job
      hierarchy.
    name: Costs
  - description: >
      Locations are places an organisation manages, optionally classified by a
      location type.
    name: Locations
  - description: |
      Manage your forms and their schemas
    name: Forms, Schemas and Categories
  - description: |
      Create and view form submissions
    name: Submissions
  - description: |
      View the roles available in the system.
    name: IAM Roles
  - description: >
      IAM role groups can be assigned to principals to manage authorisation
      centrally.
    name: IAM Role Groups
  - description: |
      Manage service accounts which can access the API programmatically.
    name: Service Accounts
  - description: |
      Manage bridges between organisations.
    name: Bridges
  - description: |
      Manage settings for an organisation.
    name: Settings
  - description: |
      Manage teams within an organisation.
    name: Teams
  - description: |
      Manage job roles within an organisation.
    name: Job Roles
  - description: |
      Manage users and accounts.
    name: Users
  - description: |
      Invite and manage invitations to organisations.
    name: Invitations
  - description: >
      IAM grants are the asignment of roles or permissions to principals to
      manage resource access.
    name: IAM Grants
  - description: |
      View the permissions available in the system.
    name: IAM Permissions
  - description: |
      SSO providers are the identity providers for an organisation.
    name: SSO Providers
  - description: |
      Whoami returns information about the currently authenticated principal.
    name: Whoami
  - description: |
      Manage your images
    name: Images
  - description: >
      AI agent personas that synthesise data into role-specific intelligent
      briefings.
    name: Agents
  - description: |
      Briefings generated by AI agents, including reasoning traces.
    name: Briefings
  - description: >
      Organisations are the center point for most resources in the platform.
      Most other endpoints are subresources of an organisation.
    name: Organisations
  - description: |
      Permits managements, integrated with street manager.
    name: Permits
  - description: |
      Projects manage your work and governance.
    name: Projects
  - description: >
      Import templates allow users to save and reuse their CSV importer
      configuration as named templates.
    name: Import Templates
  - description: |
      Properties are the physical locations.
    name: Properties
  - description: |
      Search across schemes, work orders, and operations.
    name: Search
  - description: |
      Provides the API specification in JSON and YAML formats
    name: Specifications
  - description: |
      Streets are the physical roads.
    name: Streets
  - description: |
      Integration with street manager
    name: Street Manager
  - description: |
      Vehicles are the physical vehicles that an organisation manages.
    name: Vehicles
  - description: >
      Scheme contracts (also known as regions) group schemes allocated from the
      network to a contractor.
    name: Scheme Contracts
  - description: >
      Scheme shares allow you to share your schemes with other organisations
      across bridges.
    name: Scheme Shares
  - description: |
      Schemes are large programmes of work
    name: Schemes
  - description: |
      Work orders the component parts of a scheme.
    name: Work Orders
  - description: |
      Operations are the work to be carried out within work orders.
    name: Operations
externalDocs:
  description: More documentation and resources
  url: https://docs.ctrl-hub.com
paths:
  /v3/workflow-definitions/{workflow_definition_id}/insights:
    get:
      tags:
        - Workflows
      description: >
        The aggregate figures for a workflow over a reporting window: volumes by

        outcome, return rate, average end-to-end time, active submitters and
        per-step

        timings with box-plot quartiles.


        Everything is derived from the workflow's transition records, under the
        caller's

        own access — a principal whose grants reach only part of the workflow's
        activity

        sees figures for that part. A submission that has never transitioned
        does not

        appear, and a submission whose earlier transitions predate the window is
        counted

        from its first transition inside it.


        It also carries the transition volume over time, bucketed at the width
        asked

        for, so an activity chart does not need the records themselves.


        The window is required. Optionally narrow the figures to a scheme's or a

        contract's submissions, and ask for `include_baseline=true` to get the
        unscoped

        figures alongside them for comparison.


        Served by a hand-written handler rather than a generated one, because
        the

        resource is computed rather than stored.
      operationId: GetWorkflowInsights
      parameters:
        - $ref: '#/components/parameters/workflow_definition_id'
        - $ref: '#/components/parameters/workflow_insights_filter'
        - $ref: '#/components/parameters/insights_bucket'
        - $ref: '#/components/parameters/include_baseline'
      responses:
        '200':
          $ref: '#/components/responses/GetWorkflowInsights'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - Session: []
        - OAuth2: []
        - Cookie: []
components:
  parameters:
    workflow_definition_id:
      name: workflow_definition_id
      in: path
      required: true
      description: The unique identifier for the workflow.
      schema:
        type: string
        format: uuid
      example: 02a41ff2-1436-42df-b168-900153e2d993
    workflow_insights_filter:
      name: filter
      in: query
      description: >
        Narrows the transition records the figures are computed from.


        The reporting window is **required** — an unbounded window would mean

        aggregating the whole collection, so it is rejected rather than served:


        - `ge(created_at,xxx)`: the start of the window. Required.

        - `le(created_at,xxx)`: the end of the window. Required.


        The cohort filters are optional and mutually exclusive. Both resolve to
        a set

        of submissions server-side, through the operation a submission captured:


        - `eq(scheme,xxx)`: only submissions whose payload operation belongs to
        the scheme.

        - `eq(contract,xxx)`: as `scheme`, expanded across every scheme in the
        contract.


        A submission that captured no operation cannot join a scheme or a
        contract, so

        it is invisible to both cohorts. Unscoped figures include it.


        The organisation is not a filter — it is the organisation that owns the
        workflow

        definition in the path.


        For more information on using named filters, see [the
        docs](https://docs.ctrl-hub.com/api-reference/features#filtering)
      required: true
      schema:
        type: string
        minLength: 1
    insights_bucket:
      name: bucket
      in: query
      description: >
        The bucket width for the activity series. The five widths are the ones
        an

        activity chart picks between as the reporting window widens, from five
        minutes

        over a few hours to a week over a year.
      required: false
      schema:
        type: string
        default: 1d
        enum:
          - 5m
          - 1h
          - 6h
          - 1d
          - 1w
    include_baseline:
      name: include_baseline
      in: query
      description: >
        Adds a `baseline` block to the attributes: the same figures over the
        same window

        with the cohort filter dropped, so a cohort can be read against the
        whole

        network. Costs one extra aggregation, not an extra round trip.
      required: false
      schema:
        type: boolean
        default: false
  responses:
    GetWorkflowInsights:
      description: >-
        The aggregate figures for the workflow definition over the requested
        window
      headers:
        Content-Type:
          $ref: '#/components/headers/content-type'
        Content-Length:
          $ref: '#/components/headers/content-length'
        X-Request-ID:
          $ref: '#/components/headers/x-request-id'
      content:
        application/vnd.api+json:
          schema:
            allOf:
              - type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/WorkflowInsights'
              - $ref: '#/components/schemas/JSONAPI'
    BadRequest:
      description: >
        There was an error with the request - this could be due to an invalid
        body, query parameters,

        or headers that were sent to the API.
      headers:
        Content-Type:
          $ref: '#/components/headers/content-type'
        Content-Length:
          $ref: '#/components/headers/content-length'
        X-Request-ID:
          $ref: '#/components/headers/x-request-id'
      content:
        application/vnd.api+json:
          schema:
            type: object
            properties:
              errors:
                type: array
                items:
                  $ref: '#/components/schemas/Error'
          example:
            id: 98ca4a78-b66f-4234-9719-aaf832ee6669
            status: '400'
            title: A validation error was encountered
            source:
              parameter: include
            meta:
              resource: wrong_value
    Unauthorised:
      description: Authentication failed
      headers:
        Content-Type:
          $ref: '#/components/headers/content-type'
        Content-Length:
          $ref: '#/components/headers/content-length'
        X-Request-ID:
          $ref: '#/components/headers/x-request-id'
      content:
        application/vnd.api+json:
          schema:
            type: object
            properties:
              errors:
                type: array
                items:
                  $ref: '#/components/schemas/Error'
          example:
            id: 05fc9c8d-73b9-4697-9337-57f7a567a48f
            status: '401'
            title: You are not authorised to access this resource
            detail: In order to access this resource, you need the 'admin' role.
            code: AUTH.001
    NotFound:
      description: The requested resource could not be found
      headers:
        Content-Type:
          $ref: '#/components/headers/content-type'
        Content-Length:
          $ref: '#/components/headers/content-length'
        X-Request-ID:
          $ref: '#/components/headers/x-request-id'
      content:
        application/vnd.api+json:
          schema:
            type: object
            properties:
              errors:
                type: array
                items:
                  $ref: '#/components/schemas/Error'
          example:
            id: 7b4c8f12-3e9a-4d5b-8c6f-1a2b3c4d5e6f
            status: '404'
            title: Resource not found
            detail: The requested resource could not be found or does not exist.
            code: NOT_FOUND.001
    InternalServerError:
      description: There was a problem handling the request on the server side
      headers:
        Content-Type:
          $ref: '#/components/headers/content-type'
        Content-Length:
          $ref: '#/components/headers/content-length'
        X-Request-ID:
          $ref: '#/components/headers/x-request-id'
      content:
        application/vnd.api+json:
          schema:
            type: object
            properties:
              errors:
                type: array
                items:
                  $ref: '#/components/schemas/Error'
          example:
            id: fe9d9a69-f0a7-4fdc-bb2c-176027f316c5
            status: '500'
            title: Internal Server Error
            detail: An unexpected error occurred on the server.
  headers:
    content-type:
      description: The content type of the response
      schema:
        type: string
      example: application/vnd.api+json
    content-length:
      description: The length of the response body in bytes
      schema:
        type: integer
        format: int32
      example: 1234
    x-request-id:
      description: >-
        An ID that can be provided when reporting bugs to help identify the
        issue
      schema:
        type: string
      example: 8470f56af4cf25e22be08e72c70dbbdc
  schemas:
    WorkflowInsights:
      type: object
      description: >
        The aggregate view of one workflow definition's activity over a
        reporting

        window. A synthetic, read-only resource: it is computed from the
        workflow

        transition records the caller can see, never stored, and its identifier
        is the

        workflow definition it was computed for.
      required:
        - id
        - type
        - attributes
        - meta
        - relationships
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the workflow definition the figures cover.
        type:
          type: string
          const: workflow-insights
        attributes:
          $ref: '#/components/schemas/WorkflowInsightsAttributes'
        meta:
          $ref: '#/components/schemas/WorkflowInsightsMeta'
        relationships:
          $ref: '#/components/schemas/WorkflowInsightsRelationships'
    JSONAPI:
      type: object
      description: JSON API response object
      required:
        - jsonapi
      properties:
        jsonapi:
          type: object
          required:
            - version
          properties:
            version:
              type: string
              description: The version of the JSON API specification
              examples:
                - '1.0'
    Error:
      type: object
      description: An error response
      properties:
        id:
          description: >-
            A unique identifier for this particular occurrence of the problem.
            If you encounter this, please provide us with the error ID and we
            can investigate it on our side.
          type: string
          format: uuid
          examples:
            - 05fc9c8d-73b9-4697-9337-57f7a567a48f
        status:
          description: >-
            The status code for the error. This might not match the HTTP status
            code if there are more that one errors to return with different
            status codes.
          type: string
          examples:
            - '401'
            - '500'
        title:
          description: A human readable title for the error.
          type: string
          examples:
            - You are not authorised to access this resource
        detail:
          description: >-
            Where there is more detail that we can provide outside of the title,
            we will provide it here.
          type: string
          examples:
            - In order to access this resource, you need the 'admin' role.
        code:
          description: >-
            A unique code for the error that may help us to diagnose the issue.
            Not all errors have codes, so this is usually empty.
          type: string
          examples:
            - AUTH.001
        source:
          description: A JSON object containing additional information about the error.
          type: object
          properties:
            pointer:
              description: >-
                A JSON Pointer to the value in the request that caused the
                error.
              type: string
              examples:
                - /data/attributes/email
            parameter:
              description: >-
                A string indicating which query parameter in the request caused
                the error.
              type: string
              examples:
                - include
      required:
        - id
        - status
        - title
    WorkflowInsightsAttributes:
      allOf:
        - $ref: '#/components/schemas/WorkflowInsightAggregate'
        - type: object
          required:
            - activity
          properties:
            activity:
              allOf:
                - $ref: '#/components/schemas/WorkflowInsightActivity'
              description: >
                Transition volume over time, for an activity chart. Always
                present: it is

                derived from the same records as the figures, so asking for it
                separately

                would only mean sweeping the window twice.
            baseline:
              allOf:
                - $ref: '#/components/schemas/WorkflowInsightAggregate'
              description: >
                The same figures over the same window with the cohort filter
                dropped,

                so a contract's or scheme's performance can be read against the
                whole

                network's.


                Present only when `include_baseline=true` was asked for **and**
                a cohort

                filter was applied. Asked for without a cohort it is absent
                rather than a

                copy of the figures above it, which would be a second sweep of
                the window

                to say the same thing twice.
    WorkflowInsightsMeta:
      type: object
      description: >-
        Metadata describing the window and cohort the figures were computed
        over.
      required:
        - window
        - cohort
      properties:
        window:
          type: object
          description: The reporting window that was applied, echoed back from the filter.
          required:
            - from
            - to
          properties:
            from:
              type: string
              format: date-time
              description: The start of the window, inclusive.
            to:
              type: string
              format: date-time
              description: The end of the window, inclusive.
        cohort:
          type: object
          description: >
            The cohort the figures were narrowed to. Both members are null when
            no

            cohort filter was applied, in which case the figures cover every
            submission

            the caller can see on the workflow.
          required:
            - scheme
            - contract
          properties:
            scheme:
              type:
                - string
                - 'null'
              format: uuid
              description: The scheme the cohort was resolved from.
            contract:
              type:
                - string
                - 'null'
              format: uuid
              description: >-
                The contract the cohort was resolved from, expanded across its
                schemes.
    WorkflowInsightsRelationships:
      type: object
      description: Relationships for a workflow insights aggregate
      required:
        - organisation
        - definition
      properties:
        organisation:
          type: object
          required:
            - data
          properties:
            data:
              $ref: '#/components/schemas/OrganisationRelationship'
        definition:
          type: object
          required:
            - data
          properties:
            data:
              $ref: '#/components/schemas/WorkflowDefinitionRelationship'
    WorkflowInsightAggregate:
      type: object
      description: >
        The aggregate figures for one workflow definition over one reporting
        window.


        Everything here is derived from the workflow transition records inside
        the

        window, so a submission that has never transitioned does not appear at
        all and

        a submission whose earlier transitions fall before the window is counted
        from

        its first transition inside it.
      required:
        - totals
        - return_rate
        - avg_end_to_end_minutes
        - active_submitters
        - steps
        - truncated
      properties:
        totals:
          type: object
          description: >
            Submission counts. `submissions` is every submission that
            transitioned in

            the window; the four below partition it by the type of the step each
            one

            last moved into.
          required:
            - submissions
            - completed
            - rejected
            - cancelled
            - in_progress
          properties:
            submissions:
              type: integer
              description: Submissions that transitioned at least once inside the window.
            completed:
              type: integer
              description: >-
                Submissions whose last transition in the window landed on a
                `completed` step.
            rejected:
              type: integer
              description: >-
                Submissions whose last transition in the window landed on a
                `rejected` step.
            cancelled:
              type: integer
              description: >-
                Submissions whose last transition in the window landed on a
                `cancelled` step.
            in_progress:
              type: integer
              description: >-
                Submissions that had not reached a terminal step by the end of
                the window.
        return_rate:
          type: integer
          description: >
            The percentage of submissions that were sent back, as a whole
            number. A

            submission counts as returned when it left the same step more than
            once.

            Zero for an empty window rather than undefined.
        avg_end_to_end_minutes:
          type: integer
          description: >
            The mean whole minutes between a submission's first transition in
            the

            window and its terminal one, over finished submissions only.
            Submissions

            still in progress are left out rather than counted as zero.
        active_submitters:
          type: integer
          description: >-
            The number of distinct users who recorded a transition in the
            window.
        steps:
          type: array
          description: >
            Per-step timings, keyed on the step a transition left. Two steps
            that share

            a name stay separate, because the key is the step's identifier
            within the

            workflow definition version. Ordered by transition count, busiest
            first.
          items:
            type: object
            required:
              - id
              - name
              - avg_minutes
              - transitions
              - contributors
              - box
            properties:
              id:
                type: string
                description: >-
                  The identifier of the step within the workflow definition
                  version.
              name:
                type: string
                description: The name of the step, as it was recorded on the transition.
              avg_minutes:
                type: integer
                description: The mean time spent in the step, in whole minutes.
              transitions:
                type: integer
                description: The number of transitions out of the step in the window.
              contributors:
                type: integer
                description: >-
                  The number of distinct users who moved a submission out of the
                  step.
              box:
                type: object
                description: >
                  The five-number summary of the time spent in the step, for a
                  box

                  plot. Quartiles are linearly interpolated and rounded to whole

                  minutes.
                required:
                  - min
                  - q1
                  - median
                  - q3
                  - max
                properties:
                  min:
                    type: integer
                  q1:
                    type: integer
                  median:
                    type: integer
                  q3:
                    type: integer
                  max:
                    type: integer
        truncated:
          type: boolean
          description: >
            True when the window held more transition records than the server
            will

            aggregate in one request, so the figures cover only the earliest
            part of

            it. Narrow the window rather than reading a partial answer as a
            whole one.
    WorkflowInsightActivity:
      type: object
      description: >
        Transition volume over the window, bucketed, for an activity chart.


        Only buckets that hold at least one transition are returned: a chart
        draws the

        empty ones from the window and the bucket width, and a window can hold a
        great

        many of them.
      required:
        - bucket
        - series
      properties:
        bucket:
          type: string
          description: >-
            The bucket width the counts were grouped into, echoed back from the
            request.
        series:
          type: array
          description: >
            One entry per non-empty bucket, oldest first. Bucket boundaries are
            whole

            multiples of the width from the epoch, so they do not depend on the
            caller's

            timezone.
          items:
            type: object
            required:
              - at
              - transitions
              - steps
            properties:
              at:
                type: string
                format: date-time
                description: The start of the bucket.
              transitions:
                type: integer
                description: The number of transitions recorded in the bucket.
              steps:
                type: object
                description: >
                  The same count split by the step each transition left, keyed
                  on the

                  step's identifier within the workflow definition version. Two
                  steps

                  that share a name stay separate, as they do in `steps`; a
                  chart

                  filtering by name sums the ids whose name matches.
                additionalProperties:
                  type: integer
    OrganisationRelationship:
      type: object
      description: Represents a relationship to an organisation
      required:
        - id
        - type
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the organisation
        type:
          type: string
          const: organisations
    WorkflowDefinitionRelationship:
      type: object
      description: Represents a relationship to a workflow definition
      required:
        - id
        - type
      properties:
        id:
          type: string
          format: uuid
          description: The unique identifier of the workflow definition
        type:
          type: string
          const: workflow-definitions
  securitySchemes:
    Session:
      description: |
        Session token for authentication.
      in: header
      name: X-Session-Token
      type: apiKey
    OAuth2:
      description: |
        OAuth2 token for authentication.
      flows:
        clientCredentials:
          scopes: {}
          tokenUrl: https://auth.ctrl-hub.com/oauth2/token
      type: oauth2
    Cookie:
      description: |
        Cookie token for authentication.
      in: cookie
      name: ctrl_hub_session
      type: apiKey

````