Payroll Export
Ditio generates payroll data automatically from the time registrations field workers submit and the payroll rules and absence codes configured in your company’s payroll setup. When a payroll period is approved, that data needs to reach your payroll or accounting system — this guide covers how to pull it out programmatically.
When to use this
Section titled “When to use this”- You run payroll in an external system (Visma, Tripletex, SAP, or a custom ERP) and want approved hours, overtime, allowances, and absences delivered automatically every period
- You’re a payroll-system vendor building a standard Ditio connector
- You want to replace a manual “download file, upload file” routine with a scheduled sync
Prerequisites
Section titled “Prerequisites”- API credentials with the
ditioapiv3scope — see Authentication - Payroll and absence codes configured in Ditio’s payroll module (without this, no payroll data is generated). Your payroll administrator sets this up — see the payroll articles in the Ditio help centre
# Test (default for all examples)export DITIO_API_BASE="https://core-api.ditio.dev/core"export DITIO_IDENTITY_BASE="https://identity.ditio.dev"
# Production — only after verifying in test# export DITIO_API_BASE="https://core-api.ditio.app/core"# export DITIO_IDENTITY_BASE="https://identity.ditio.app"Export methods
Section titled “Export methods”1. API export (recommended)
Section titled “1. API export (recommended)”The preferred method is the JSON payroll export API. The response contains all data needed to convert into any accounting system format.
GET /api/payroll-export/GET /api/payroll-export/readonly is an alias for the same JSON export.
Query parameters
Section titled “Query parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
fromWorkDate | string | No | Start date, e.g. 2026-01-01. Defaults to 14 days before now when omitted. Date ranges are limited to 45 days. |
toWorkDate | string | No | End date, e.g. 2026-01-31. Defaults to now when omitted. Date ranges are limited to 45 days. |
modifiedSinceDate | string | No | Return payroll data modified since this date. The oldest supported value is one year back. |
dataFilter | int | No | 0 = only approved (default), 5 = only locked, 10 = all data |
userIds | list of string | No | Filter by specific Ditio user IDs. If omitted, returns data for all users |
userPayrollTypeFilter | string | No | paid-by-hour (default), fixed-pay, or all-users |
overridePayrollExportSettingsForFixedPayEmployees | bool | No | Include regular hours and absences for fixed-pay employees |
exportAllPayrollTypes | bool | No | Include payroll types marked “do not export” in Ditio setup |
includeAllAbsence | bool | No | Include absence transactions regardless of absence type |
onlyDataFromExternalProjects | bool | No | Include only data registered in external projects |
companyIds | list of string | No | Filter by project company IDs |
projectIds | list of string | No | Filter by Ditio project IDs |
payrollTypeIds | list of string | No | Filter by payroll type IDs |
absenceTypeIds | list of string | No | Filter by absence type IDs |
If you provide modifiedSinceDate together with fromWorkDate and
toWorkDate, modified data is queried inside that work-date range.
Example
Section titled “Example”TOKEN=$(curl -s -X POST "$DITIO_IDENTITY_BASE/connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "scope=ditioapiv3" | jq -r '.access_token')
curl "$DITIO_API_BASE/api/payroll-export/?fromWorkDate=2026-01-01&toWorkDate=2026-01-31&dataFilter=0" \ -H "Authorization: Bearer $TOKEN"Python example — monthly sync
Section titled “Python example — monthly sync”import osimport requests
API_BASE = os.environ.get("DITIO_API_BASE", "https://core-api.ditio.dev/core")IDENTITY_BASE = os.environ.get("DITIO_IDENTITY_BASE", "https://identity.ditio.dev")
token = requests.post( f"{IDENTITY_BASE}/connect/token", data={ "grant_type": "client_credentials", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "scope": "ditioapiv3", },).json()["access_token"]
response = requests.get( f"{API_BASE}/api/payroll-export/", headers={"Authorization": f"Bearer {token}"}, params={ "fromWorkDate": "2026-01-01", "toWorkDate": "2026-01-31", "dataFilter": 0, # only approved },)response.raise_for_status()payroll_data = response.json()C# example
Section titled “C# example”using System.Net.Http.Headers;
var apiBase = Environment.GetEnvironmentVariable("DITIO_API_BASE") ?? "https://core-api.ditio.dev/core";
using var http = new HttpClient();http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var url = $"{apiBase}/api/payroll-export/" + "?fromWorkDate=2026-01-01&toWorkDate=2026-01-31&dataFilter=0";var response = await http.GetAsync(url);response.EnsureSuccessStatusCode();var json = await response.Content.ReadAsStringAsync();2. Summary lines
Section titled “2. Summary lines”GET /api/payroll-export/summary-as-linesReturns payroll summaries as export lines. When fromWorkDate or toWorkDate
is omitted, the endpoint uses the same default work-date range as the JSON
export.
3. File export
Section titled “3. File export”GET /api/payroll-export/fileReturns a payroll export file in the format configured in your company’s payroll setup. Ditio supports flat-file formats compatible with several accounting systems — to request support for a new format, send a sample export file, field descriptions per column, and the accounting system’s import-format documentation to support@ditio.no.
Additional parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
voucherNumber | string | No | Voucher number for cost file export |
dataExportType | int | No | 5 = preview, 6 = journal (default), 10 = payroll, 20 = absence, 30 = cost, 40 = transaction split |
dataFilter | int | No | 0 = only approved (default), 5 = only locked, 10 = all data |
userPayrollTypeFilter | string | No | paid-by-hour (default), fixed-pay, or all-users |
payrollTypeIds | list of string | No | Filter by payroll type IDs |
absenceTypeIds | list of string | No | Filter by absence type IDs |
Payroll lines via the Data Extraction API
Section titled “Payroll lines via the Data Extraction API”If you’re pulling payroll data into a BI tool or data warehouse (rather than feeding a payroll run), the paginated Data Extraction API may fit better:
| Endpoint | Description |
|---|---|
GET /v1/payroll-lines | Processed payroll lines |
GET /v1/payroll-lines-extended | Extended payroll lines with full detail |
These live on the reporting base URL (https://core-api.ditio.dev/reporting
in test) and use the reportingapiv1 scope. See
Payroll Lines and
Pagination.
Common issues
Section titled “Common issues”| Issue | Cause | Fix |
|---|---|---|
| Empty response | No approved data in the range | Check dataFilter — the default returns only approved data. Use 10 to see everything, and verify the period is approved in Ditio |
400 on a long date range | Ranges are limited to 45 days | Split the export into month-sized chunks |
| Fixed-salary employees missing | Default filter is paid-by-hour | Set userPayrollTypeFilter=all-users (and consider overridePayrollExportSettingsForFixedPayEmployees=true) |
| Some payroll types missing | Types marked “do not export” in setup | Set exportAllPayrollTypes=true, or fix the type configuration |
| Old edits not picked up | modifiedSinceDate limited to one year back | Do a full re-export of the affected work-date range instead |
Postman collections
Section titled “Postman collections”Ready-made Postman files with the token request and a pre-configured payroll export call are available — contact support@ditio.no.
Related
Section titled “Related”- Payroll Lines — paginated payroll extraction for BI
- Export Time Data — raw time registrations (pre-payroll)
- Authentication — credentials and scopes
- Help centre: Lønn — payroll setup for administrators (Norwegian)