Payroll Runs

Payroll runs represent individual payroll processing cycles. Each run covers a specific period and contains payroll lines for each employee. Payroll runs are a subtype of Documents with document_type set to PRRUN.

Endpoints

List Payroll Runs

GET /api/v2/payroll-runs

Retrieves a paginated list of payroll runs.

Query Parameters

Parameter Type Required Description
client_account_id integer Yes ID of the client account
from_date date No Filter runs with period_start on or after this date
to_date date No Filter runs with period_end on or before this date

Response

{
  "data": [
    {
      "id": 1,
      "created_by_id": 7,
      "created_at": "2024-03-15T10:00:00Z",
      "client_account_id": 7,
      "document_date": "2024-03-31",
      "document_number": "3",
      "period_start": "2024-03-01",
      "period_end": "2024-03-31",
      "uploaded_file_id": 456,
      "is_draft": false,
      "document_type": "PRRUN"
    }
  ],
  "meta": {
    "page": 1,
    "pages": 1,
    "per_page": 100,
    "records": 1
  }
}

Create Payroll Run

POST /api/v2/payroll-runs

Creates a new payroll run. The run is created as a draft (is_draft: true).

When a run is created, the system automatically seeds it with employees from active employment contracts that have is_payroll_default set to true. For each default contract, a base earning line (fixed salary or hourly pay) is created, and any configured default payroll lines are also added. After seeding, derived amounts (tax withholding, employer costs, etc.) are automatically recalculated.

Request Body

Field Type Required Description
client_account_id integer Yes The client account ID
document_date date No Date of the payroll run
document_number string No Run number (e.g. “3” for the third run of the year)
period_start date No Start date of the payroll period
period_end date No End date of the payroll period

Example Request

{
  "client_account_id": 7,
  "document_date": "2024-03-31",
  "document_number": "3",
  "period_start": "2024-03-01",
  "period_end": "2024-03-31"
}

Response

Returns the created payroll run with status 201 Created.

Update Payroll Run

POST /api/v2/payroll-runs/{id}
PUT /api/v2/payroll-runs/{id}

Updates an existing payroll run. Both POST and PUT methods are accepted.

Request Body

Field Type Required Description
document_date date No Date of the payroll run
document_number string No Run number
period_start date No Start date of the payroll period
period_end date No End date of the payroll period

Response

Returns the updated payroll run.

Delete Payroll Run

DELETE /api/v2/payroll-runs/{id}

Deletes a payroll run. Only draft runs can be deleted (is_draft must be true).

Response

Returns 204 No Content on success. Returns 400 Bad Request if the payroll run is not a draft.

Attributes

Attribute Type Description
id integer Unique identifier (read-only)
created_by_id integer ID of the creating user (read-only)
created_at datetime Creation timestamp (read-only)
client_account_id integer ID of the client account
document_date date Date of the payroll run
document_number string Run number within the year
period_start date Start date of the payroll period
period_end date End date of the payroll period
uploaded_file_id integer Associated voucher/file ID (read-only)
is_draft boolean Whether this is a draft run (read-only)
document_type string Always PRRUN (read-only)

Relationships

The following related objects can be included using the with parameter:

  • payroll_lines - Employee payroll lines for this run

Payroll lines support nested relations using dot notation (e.g. with=payroll_lines.item_type):

  • payroll_lines.item_type - The payroll item type definition
  • payroll_lines.business_partner - The employee
  • payroll_lines.contract - The employment contract
  • payroll_lines.tax_card - The employee’s tax card
  • payroll_lines.garnishment - The linked garnishment

Payroll Line Attributes

Attribute Type Description
id integer Unique identifier (read-only)
created_by_id integer ID of the creating user (read-only)
created_at datetime Creation timestamp (read-only)
document_id integer Parent payroll run ID (read-only)
business_partner_id integer Employee ID
item_type_id integer Payroll item type ID
contract_id integer Employment contract ID
tax_card_id integer Employee tax card ID
garnishment_id integer Linked garnishment ID (read-only)
description string Line description
quantity decimal Quantity (e.g. hours worked)
rate decimal Rate (e.g. hourly rate)
amount decimal Calculated amount
currency_code string Currency code
sort_order integer Display order
relation_type string Type of related object (read-only)
relation_id integer ID of related object (read-only)

Error Responses

Status Code Description
400 Invalid request (missing required fields)
403 Forbidden (no access to client account)
404 Payroll run not found

Payroll Run Items

Payroll run items are the individual salary components (earnings, deductions, employer costs) within a payroll run. When items are added, updated, or deleted, the system automatically recalculates derived amounts (tax withholding, employer costs, etc.) for all employees in the run.

List Items

GET /api/v2/payroll/runs/{document_id}/items

Retrieves a paginated list of payroll line items for a specific run. The item_type relation is included by default.

Query Parameters

Parameter Type Required Description
page integer No Page number (default: 1)
per_page integer No Items per page (default: 1000)
with string No Include related resources (supported: item_type, business_partner, contract, tax_card, garnishment)

Response

{
  "data": [
    {
      "id": 501,
      "created_by_id": 7,
      "created_at": "2024-03-15T10:30:00Z",
      "document_id": 1,
      "business_partner_id": 56,
      "item_type_id": 10,
      "contract_id": 3,
      "tax_card_id": 12,
      "garnishment_id": null,
      "description": "Fastlønn",
      "quantity": "1.000000",
      "rate": "45000.000000",
      "amount": "45000.000000",
      "currency_code": "NOK",
      "sort_order": 1,
      "relation_type": null,
      "relation_id": null,
      "item_type": {
        "id": 10,
        "code": "FIXED_SALARY",
        "name_nob": "Fastlønn",
        "category": "EARNING"
      }
    }
  ],
  "meta": {
    "page": 1,
    "pages": 1,
    "per_page": 1000,
    "records": 1
  }
}

Add Item

POST /api/v2/payroll/runs/{document_id}/items

Adds a new payroll line item to a draft run. If this is the first item for a given employee, their default payroll lines are automatically seeded. After adding, the system recalculates all derived amounts for the run.

Request Body

Field Type Required Description
business_partner_id integer Yes Employee ID
item_type_id integer Yes Payroll item type ID
contract_id integer No Employment contract ID
tax_card_id integer No Employee tax card ID
description string No Line description
quantity decimal No Quantity (e.g. hours worked)
rate decimal No Rate (e.g. hourly rate)
amount decimal No Amount (auto-calculated if quantity and rate are set)
currency_code string No Currency code (default: account currency)
sort_order integer No Display order

Example Request

{
  "business_partner_id": 56,
  "item_type_id": 10,
  "contract_id": 3,
  "description": "Fastlønn",
  "quantity": "1",
  "rate": "45000",
  "amount": "45000"
}

Response

Returns the created item with status 201 Created.

Error Responses

Status Code Description
400 Cannot add items to a finalized (non-draft) document
403 Access denied to client account
404 Payroll document not found

Update Item

POST /api/v2/payroll/runs/{document_id}/items/{item_id}
PUT /api/v2/payroll/runs/{document_id}/items/{item_id}

Updates an existing payroll line item. Both POST and PUT methods are accepted. After updating, the system recalculates all derived amounts for the run.

Request Body

Same fields as Add Item. Only provided fields are updated.

Response

Returns the updated item.

Error Responses

Status Code Description
400 Cannot edit items on a finalized document
403 Access denied to client account
404 Payroll document or line item not found

Delete Item

DELETE /api/v2/payroll/runs/{document_id}/items/{item_id}

Removes a payroll line item from a draft run. After deletion, the system recalculates derived amounts. If the deleted item is a base earning (FIXED_SALARY or HOURLY_PAY), auto-recalculation skips regenerating that employee’s base earning to avoid re-seeding it.

Response

Returns 204 No Content on success.

Error Responses

Status Code Description
400 Cannot delete items from a finalized document
403 Access denied to client account
404 Payroll document or line item not found

Posting and Reversal

Once a payroll run’s items are finalized, it can be posted to the general ledger. Posting creates journal entries with employee dimensions and generates a PDF voucher. If the earning period and payment date fall in different calendar months, periodization (accrual and reversal) entries are automatically generated.

Preview Posting

GET /api/v2/payroll/runs/{document_id}/posting-preview

Returns a preview of the journal entry that would be created when posting, without persisting anything. Useful for reviewing before committing. The response follows the same shape as GET /api/v2/journal-entries/{id} with lines and dimensions included, plus an account_name field on each line.

Example Response

{
  "id": null,
  "client_account_id": 7,
  "memo": "Lønnskjøring 3",
  "lines": [
    {
      "line_id": 1,
      "posting_date": "2024-03-31",
      "account_code": "5000",
      "account_name": "Lønn til ansatte",
      "currency_code": "NOK",
      "debit": "45000.000000",
      "credit": "0.000000",
      "description": "",
      "dimensions": [
        {
          "relation_type": "BusinessPartner",
          "relation_id": 56
        }
      ]
    },
    {
      "line_id": 2,
      "posting_date": "2024-03-31",
      "account_code": "2610",
      "account_name": "Skattetrekk",
      "currency_code": "NOK",
      "debit": "0.000000",
      "credit": "15300.000000",
      "description": "",
      "dimensions": []
    }
  ]
}

Post Payroll Run

POST /api/v2/payroll/runs/{document_id}/post

Creates journal entries from the payroll document, generates a PDF voucher, and marks the run as finalized (is_draft becomes false). Also triggers automatic payslip email delivery and A-melding submission for the period.

Response

{
  "document_id": 1,
  "journal_entry_id": 42
}

Error Responses

Status Code Description
400 Document has already been posted, or has no items to post
403 Access denied to client account
404 Payroll document not found

Reverse Payroll Run

POST /api/v2/payroll/runs/{document_id}/reverse

Reverses a posted payroll document’s journal entry and returns the run to draft status (is_draft becomes true), allowing items to be edited again.

Response

{
  "document_id": 1,
  "reversal_journal_entry_id": 43
}

Error Responses

Status Code Description
400 Cannot reverse a draft document, or no journal entry found
403 Access denied to client account
404 Payroll document not found

Payslips

Generate and distribute payslips for employees in a payroll run.

List Payslips

GET /api/v2/payroll/runs/{document_id}/payslips

Returns payslip summaries for all employees in the payroll run.

Response

{
  "payslips": [
    {
      "employee_id": 56,
      "employee_name": "Ola Nordmann",
      "total_gross": "45000.000000",
      "total_deductions": "15300.000000",
      "net_pay": "29700.000000",
      "total_employer_costs": "6345.000000"
    }
  ]
}

Download Payslip PDF

GET /api/v2/payroll/runs/{document_id}/payslips/{bp_id}/pdf

Downloads a single employee’s payslip as a PDF file.

Path Parameters

Parameter Type Description
document_id integer Payroll run document ID
bp_id integer Employee business partner ID

Response

Returns a PDF file with Content-Type: application/pdf and Content-Disposition: attachment headers. The filename follows the pattern lonnsslipp_{period_from}_{period_to}_{bp_id}.pdf.

Error Responses

Status Code Description
403 Access denied to client account
404 Payroll document not found, or no payslip found for this employee

Send Payslips

POST /api/v2/payroll/runs/{document_id}/payslips/send

Queues payslip emails for all employees in the payroll run. Emails are sent asynchronously. Employees without an email address on file are skipped.

Response

{
  "message": "Payslip emails queued for delivery"
}

Returns status 202 Accepted.

Error Responses

Status Code Description
400 Cannot send payslips for a draft document
403 Access denied to client account
404 Payroll document not found