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

# List the lock history of a payroll run

> Needs permission pay-run:read.

Lists the lock cycles of a payroll run, newest first. Each cycle says who locked the run
and when, when the lock completed, the balances it reported and its FPS submissions, and,
for a cycle the run was unlocked from, who unlocked it, when, why and for which employees.
A run that has never been unlocked has one cycle. A run that has never been locked has none.



## OpenAPI

````yaml /api-reference/specs/pay-api.yaml get /payroll/{payrollConfigId}/{year}/{period}/history
openapi: 3.0.3
info:
  title: FlowPayroll API
  description: >-
    API for payroll management, including payroll upload, lock, HMRC submission,
    employee management
  version: 0.1.0
servers:
  - url: https://api.sandbox.flowpayroll.ai/v1
security:
  - XAuthToken: []
    XOrgId: []
tags:
  - name: Employees
    description: >-
      Create, retrieve, update, and delete employee records, and look them up by
      NI number or payroll ID.
  - name: Starters & leavers
    description: Set and clear starter and leaver details, individually or in bulk.
  - name: Tax codes
    description: >-
      Manage employee tax codes and query the effective tax code and NI category
      on a given date.
  - name: NI & identifiers
    description: Manage NI categories, National Insurance numbers, and payroll IDs.
  - name: Student loans
    description: Start and end student and postgraduate loans.
  - name: Payroll setup
    description: Assign an employee's payroll config and set opening balances.
  - name: Salary
    description: >-
      The employee's effective-dated annual salary history: read it, add or
      correct a version from a date, and remove one. The Salary API pro-rates
      this history onto each pay run.
  - name: Payroll
  - name: Payroll lines
  - name: PayrollConfig
  - name: Pay Elements
  - name: Calculator
  - name: Payslip
  - name: RTI
  - name: YearEnd
  - name: Organisation
paths:
  /payroll/{payrollConfigId}/{year}/{period}/history:
    get:
      tags:
        - Payroll
      summary: List the lock history of a payroll run
      description: >-
        Needs permission pay-run:read.


        Lists the lock cycles of a payroll run, newest first. Each cycle says
        who locked the run

        and when, when the lock completed, the balances it reported and its FPS
        submissions, and,

        for a cycle the run was unlocked from, who unlocked it, when, why and
        for which employees.

        A run that has never been unlocked has one cycle. A run that has never
        been locked has none.
      operationId: GetPayrollRunHistory
      parameters:
        - name: payrollConfigId
          in: path
          required: true
          schema:
            type: string
          description: The payroll config id
        - name: year
          in: path
          required: true
          schema:
            type: integer
            format: int32
          description: The year in format yyyy
          example: 2026
        - name: period
          in: path
          required: true
          schema:
            type: integer
            format: int32
          description: The period of the pay run (1, 2, 3... etc)
          example: 7
        - $ref: '#/components/parameters/Request-Id'
      responses:
        '200':
          description: The lock history was retrieved successfully
          content:
            application/json:
              schema:
                type: object
                allOf:
                  - $ref: '#/components/schemas/ResponseBody'
                  - properties:
                      content:
                        type: object
                        properties:
                          data:
                            type: array
                            items:
                              $ref: '#/components/schemas/PayrollRunLockCycleDto'
        '400':
          description: The request is invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
        '404':
          description: The payroll config or the payroll run was not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
        '500':
          description: An error occurred
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
        '503':
          description: Service Unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResponseBody'
components:
  parameters:
    Request-Id:
      name: Request-Id
      in: header
      required: false
      description: >-
        Optional. Your id for this request: it is carried into every log line
        about it, so quote it when you contact support.
      schema:
        type: string
  schemas:
    ResponseBody:
      type: object
      required:
        - message
      properties:
        message:
          $ref: '#/components/schemas/MessageWithTokenResponse'
          description: >-
            A readable message about the outcome and a stable token a client can
            branch on.
        content:
          type: object
          required:
            - metadata
          properties:
            data:
              description: >-
                The resource or list the request asked for; left out when there
                is none.
            metadata:
              type: object
              required:
                - dateFormat
                - dateTimeFormat
              properties:
                dateFormat:
                  type: string
                  description: The format of the dates in this response, yyyy-MM-dd.
                dateTimeFormat:
                  type: string
                  description: >-
                    The format of the timestamps in this response,
                    yyyy-MM-ddTHH:mm:ss.fffZ in UTC.
                paginationToken:
                  type: string
                  nullable: true
                  description: >-
                    Send this value back as the paginationToken query parameter
                    to get the next page; absent when there are no more pages.
              description: >-
                The date formats the response uses and, on a paged list, the
                token for the next page.
          description: >-
            The data the request returns with its metadata; left out on a
            response that carries no data, such as most errors.
        validationIssues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          nullable: true
          description: >-
            Each field the request was refused for and why; left out when the
            request was not refused for its fields.
    PayrollRunLockCycleDto:
      type: object
      description: >-
        One lock of a pay run. A run that has never been unlocked has one cycle;
        every unlock starts

        the next, so the list is the run's history: who locked it and when, who
        unlocked it and why,

        the totals the lock settled, and every FPS sent under it. Nothing in a
        cycle is rewritten by a

        later one.
      required:
        - cycle
        - unlockedEmployeeIds
        - fpsSubmissions
        - current
      properties:
        cycle:
          type: integer
          format: int32
          description: The cycle number, from 1.
        lockedBy:
          type: string
          nullable: true
          description: The user ID of who locked the run for this cycle.
        lockedDate:
          type: string
          nullable: true
          description: The date and time the run was locked for this cycle.
        completedDate:
          type: string
          nullable: true
          description: The date and time this cycle's processing completed.
        unlockedBy:
          type: string
          nullable: true
          description: >-
            The user ID of who unlocked the run, ending this cycle. Null while
            the cycle is current.
        unlockedDate:
          type: string
          nullable: true
          description: The date and time the run was unlocked, ending this cycle.
        unlockReason:
          type: string
          nullable: true
          description: The reason given for unlocking.
        unlockScope:
          type: string
          nullable: true
          description: 'What was unlocked, Valid values: ''Full'', ''Employees''.'
        unlockedEmployeeIds:
          type: array
          items:
            type: string
          description: The employees reopened when the scope is 'Employees'.
        lateReportingReason:
          type: string
          nullable: true
          description: >-
            The HMRC late reporting reason the cycle's FPS carries, when the run
            was locked again after an earlier FPS.
        totalBalances:
          $ref: '#/components/schemas/PayrollRunBalancesDto'
          nullable: true
          description: The run totals settled by this cycle.
        fpsSubmissions:
          type: array
          items:
            $ref: '#/components/schemas/PayrollRunFpsSubmissionDto'
          description: Every FPS submission made under this cycle, oldest first.
        current:
          type: boolean
          description: True for the run's latest cycle.
        reopenExpected:
          type: integer
          format: int32
          nullable: true
          description: >-
            How many Final payslips the unlock of this cycle set out to reopen.
            Null for a cycle that was never unlocked, or whose unlock has not
            started reopening payslips yet.
        reopenDone:
          type: integer
          format: int32
          nullable: true
          description: >-
            How many of them the unlock has reopened so far. The run can be
            locked again once it equals `reopenExpected`.
        unlockOverriddenBy:
          type: string
          nullable: true
          description: >-
            The user who locked the run again before every payslip was reopened,
            with `X-Unlock-Override: true`. Null when nobody did.
        unlockedWith:
          type: string
          nullable: true
          description: >-
            The earlier pay run (`{year}-{period}`) whose unlock reopened this
            run as well, when this run was not the one unlocked. Null when the
            unlock was requested on this run.
        leaversWithIssuedP45:
          type: array
          items:
            type: string
          nullable: true
          description: >-
            The leavers whose final payslip the unlock of this cycle reopened
            after their P45 had been issued. Their correction reaches HMRC on
            the next FPS; no new P45 is produced, so tell them in writing. Null
            when there were none.
    MessageWithTokenResponse:
      type: object
      required:
        - text
        - token
      properties:
        text:
          type: string
          description: The message in English, ready to show to a user.
        token:
          type: string
          description: >-
            A stable snake_case key for the message, so a client can show its
            own wording or a translation instead of text.
        tokenArguments:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssueArgument'
          nullable: true
          description: >-
            Values to fill into the client's own wording for token, such as the
            request id; absent when the message has none.
    ValidationIssue:
      type: object
      description: >-
        Field validation item. `reasonToken` is a stable snake_case key for i18n
        or custom client messages; `reason` is the default English text from the
        API.
      required:
        - field
        - reason
        - reasonToken
      properties:
        field:
          type: string
          description: Dot-path of the field (e.g. name.firstName, address.line1).
        reason:
          type: string
          description: Default human-readable message.
        reasonToken:
          type: string
          description: Machine-readable error identifier (snake_case).
        reasonTokenArguments:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssueArgument'
          nullable: true
          description: >-
            Values to fill into the client's own wording for reasonToken; absent
            when the reason has none.
    PayrollRunBalancesDto:
      type: object
      description: >-
        Payroll run balances containing base values and statutory payments
        reclaims
      required:
        - baseValues
        - statutoryPaymentsReclaims
      properties:
        baseValues:
          $ref: '#/components/schemas/BaseValuesDto'
          description: Base values for the payroll run
        statutoryPaymentsReclaims:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/StatutoryPaymentsReclaimDto'
          description: Dictionary of statutory payments reclaims by type
    PayrollRunFpsSubmissionDto:
      type: object
      description: An FPS sent, or attempted, under one lock cycle.
      required:
        - status
        - recordedDate
      properties:
        status:
          type: string
          description: 'The submission status, Valid values: ''Sending'', ''Sent'', ''Failed''.'
        recordedDate:
          type: string
          description: When this status was recorded.
        submissionId:
          type: string
          nullable: true
          description: HMRC's submission ID, once accepted.
        submissionDate:
          type: string
          nullable: true
          description: HMRC's submission timestamp, once accepted.
        correlationId:
          type: string
          nullable: true
          description: HMRC's correlation ID for the submission.
        lateReason:
          type: string
          nullable: true
          description: The late reporting reason the submission carried, if any.
        previewDownloadUrl:
          type: string
          nullable: true
          description: >-
            A link to the FPS XML as previewed before this attempt, valid for 15
            minutes. Null when no preview was stored.
        submissionDownloadUrl:
          type: string
          nullable: true
          description: >-
            A link to the submitted FPS body, as sent to HMRC without the
            credentials, valid for 15 minutes. Null until the attempt was sent,
            or when no body was stored.
        errors:
          type: array
          items:
            type: string
          nullable: true
          description: >-
            The errors HMRC answered the attempt with, when it was refused. Null
            or empty when it was accepted or has not been answered.
        hmrcResponse:
          type: string
          nullable: true
          description: >-
            HMRC's response to the attempt, as received. Null until HMRC has
            answered.
    ValidationIssueArgument:
      type: object
      required:
        - name
        - value
      properties:
        name:
          type: string
          description: The name of the value, as a client's wording refers to it.
        value:
          description: The value itself, as a string, number or other JSON value.
    BaseValuesDto:
      type: object
      properties:
        gross:
          type: number
          format: decimal
          description: Gross pay
          example: 306
        grossTaxable:
          type: number
          format: decimal
          description: Gross taxable pay
          example: 306
        grossNi:
          type: number
          format: decimal
          description: Gross pay for National Insurance purposes
          example: 306
        grossForEmployerNi:
          type: number
          format: decimal
          description: Gross pay for employer National Insurance purposes
          example: 306
        grossForEmployerClass1ANi:
          type: number
          format: decimal
          description: Gross pay for employer Class 1A National Insurance purposes
          example: 306
        grossPensionable:
          type: number
          format: decimal
          description: Gross pensionable pay
          example: 306
        grossForCourtOrders:
          type: number
          format: decimal
          description: Gross pay for court orders
          example: 306
        tax:
          type: number
          format: decimal
          description: Tax amount
          example: 45.2
        ni:
          type: number
          format: decimal
          description: Employee National Insurance contribution
          example: 25.3
        pension:
          type: number
          format: decimal
          description: >-
            The member's pension movement for the slice this object covers
            (period, year to date or employment to date): contributions deducted
            from pay, including additional voluntary contributions, minus any
            opt-out refunds paid back. Negative in a period that refunds more
            than it deducts. Salary-sacrifice contributions are employer money
            and live in employerPension, never here. Reconciles with the pension
            summary items: read one source or the other, never both.
          example: 0
        employerNi:
          type: number
          format: decimal
          description: Employer National Insurance contribution
          example: 35.4
        employerClass1ANI:
          type: number
          format: decimal
          description: Employer Class 1A National Insurance contribution
          example: 35.4
        employerPension:
          type: number
          format: decimal
          description: >-
            The employer's pension contributions for the slice, including
            salary-sacrifice amounts (sacrificed pay is the employer's
            contribution), minus any salary-sacrifice opt-out refunds.
          example: 0
        studentLoan:
          type: number
          format: decimal
          description: Student loan repayment
          example: 0
        postgraduateLoan:
          type: number
          format: decimal
          description: Postgraduate loan repayment
          example: 0
        net:
          type: number
          format: decimal
          description: Net pay after deductions including net deductions
          example: 235.5
        netDeductions:
          type: number
          format: decimal
          description: Net deductions applied to the net pay
          example: 0
        totalPayable:
          type: number
          format: decimal
          description: Total payable
          example: 235.5
        totalEmployerCost:
          type: number
          format: decimal
          description: Total employer cost
          example: 306
        niBand:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/NiCalculationResultDto'
          description: National Insurance band breakdown
        statutory:
          type: object
          additionalProperties:
            type: number
            format: decimal
          description: Statutory payments breakdown
          example:
            SSP: 0
            SMP: 0
        pensionContributionsByType:
          type: object
          additionalProperties:
            type: number
            format: decimal
          description: >-
            Pension contributions broken down by pension type. Contributions
            only: opt-out refunds never appear here, so read
            pensionRefundsByType for those. Net member movement per scheme =
            contributions minus refunds.
          example:
            NetPayArrangement: 0
            ReliefAtSource: 0
            SalarySacrifice: 0
        qualifyingEarningsForPension:
          type: number
          format: decimal
          description: Qualifying earnings for pension calculation
          example: 0
        apprenticeshipLevy:
          type: number
          format: decimal
          description: >-
            Per-payslip gross apprenticeship levy attributable to this period.
            Equal to 0.5 percent of grossForEmployerNi when the organisation
            pays AL, otherwise 0. The org-level £15,000 annual allowance is
            applied at the EPS level, not deducted per payslip — so summing this
            across a pay run gives the gross levy used for reconciliation
            against the organisation's monthly AL balance.
          example: 1.53
        employmentAllowance:
          type: number
          format: decimal
          description: >-
            Employment Allowance used by this pay run — an employer-level
            figure, populated on the pay run's totalBalances when the run
            completes. Not stamped on individual payslips: payslip
            forPeriod/yearToDate values are always 0 for payslips generated
            after per-payslip apportionment was removed; payslips written while
            it existed retain their historical share. Per-employee views
            (journal Employment Allowance lines) are derived from the run-level
            figure.
          example: 0
        apprenticeshipLevyAllowance:
          type: number
          format: decimal
          description: >-
            Apprenticeship Levy allowance (annual £15,000 pot, accrued monthly)
            used by this pay run — an employer-level figure, populated on the
            pay run's totalBalances when the run completes. Not stamped on
            individual payslips: payslip forPeriod/yearToDate values are always
            0 for payslips generated after per-payslip apportionment was
            removed; payslips written while it existed retain their historical
            share. Per-employee views are derived from the run-level figure.
          example: 0
        statutoryRecovery:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/StatutoryPaymentsReclaimDto'
          description: >-
            Per-statutory-type recovery this payslip contributes to the EPS.
            Keys are the StatutoryTypeEnum string values (StatutoryMaternityPay,
            StatutoryPaternityPay, SharedParentalPay, StatutoryAdoptionPay,
            StatutoryParentalBereavementPay, StatutoryNeonatalCarePay).
            Statutory Sick Pay is never recoverable per HMRC DANSP37000 and is
            omitted from this map.
          example:
            StatutoryMaternityPay:
              reclaimed: 100
              nicCompensationRecovered: 8.5
        isEmpty:
          type: boolean
          nullable: true
          description: >-
            Whether every value in this record is zero, as judged by the
            producer. A pay run's totalBalances is written asynchronously after
            the run completes and reads back as an all-zero record until then,
            so a consumer cannot tell "not written yet" from "genuinely nil" by
            inspecting the figures. Null means this producer did not supply the
            flag — treat it as unknown, never as false.
          example: false
        pensionRefundsByType:
          type: object
          additionalProperties:
            type: number
            format: decimal
          description: >-
            The MEMBER contributions paid back through this period, broken down
            by pension type. Absent unless a refund happened. The refund also
            appears as a Payable internal_pension_{scheme}_refund summary item
            and nets forPeriod.pension, so the period scalar can be negative in
            a refund period. The employer half is reported separately in
            employerPensionRefundsByType.
          example:
            ReliefAtSource: 146.76
        employerPensionRefundsByType:
          type: object
          additionalProperties:
            type: number
            format: decimal
          description: >-
            The EMPLOYER contributions reversed by an opt-out refund, broken
            down by pension type. Absent unless a refund happened. Employer
            money never passes through the member's net pay (the scheme repays
            the employer directly), but it is netted off employerPension for the
            period, and therefore off the monthly balance, the organisation
            year-to-date figures and the journal cost slices built from it. This
            field is the disclosure of what was reversed, so read it to explain
            a balance, never to subtract again.
          example:
            ReliefAtSource: 110.07
    StatutoryPaymentsReclaimDto:
      type: object
      properties:
        reclaimed:
          type: number
          format: decimal
          description: Amount reclaimed this tax year
          example: 100
        nicCompensationRecovered:
          type: number
          format: decimal
          description: National Insurance contribution compensation recovered this tax year
          example: 50
    NiCalculationResultDto:
      type: object
      properties:
        employeeNi:
          type: number
          format: decimal
          description: Employee National Insurance under this NI category letter.
        employerNi:
          type: number
          format: decimal
          description: Employer National Insurance under this NI category letter.
        totalNi:
          type: number
          format: decimal
          description: Employee and employer National Insurance added together.
        grossForEmployeeNi:
          type: number
          format: decimal
          description: >-
            Earnings that employee National Insurance was worked out on under
            this letter.
        grossForEmployerNi:
          type: number
          format: decimal
          description: >-
            Earnings that employer National Insurance was worked out on under
            this letter.
        bandResults:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/NiBandResultDto'
          description: >-
            The same figures split by National Insurance band, keyed by band
            name.
      example:
        employeeNi: 290.1
        employerNi: 310.25
        totalNi: 600.35
        grossForEmployeeNi: 3500
        grossForEmployerNi: 3500
        bandResults:
          PT-UEL:
            grossInBand: 2000
            employeeNiForBand: 180
            employerNiForBand: 220
          UEL+:
            grossInBand: 500
            employeeNiForBand: 110.1
            employerNiForBand: 90.25
    NiBandResultDto:
      type: object
      properties:
        grossInBand:
          type: number
          format: decimal
          description: Gross pay in this NI band
          example: 12570
        employeeNiForBand:
          type: number
          format: decimal
          description: Employee NI contribution for this band
          example: 0
        employerNiForBand:
          type: number
          format: decimal
          description: Employer NI contribution for this band
          example: 0
  securitySchemes:
    XAuthToken:
      type: apiKey
      in: header
      name: X-Auth-Token
      description: Access token obtained from OAuth2 client credentials flow
    XOrgId:
      type: apiKey
      in: header
      name: X-Org-Id
      description: >-
        Organisation to scope the request to. Required when the principal can
        access more than one organisation; optional for single-organisation
        principals (the authorizer resolves it automatically).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.