Crew List (Mannskapsliste)
This guide shows you how to pull the crew list (Norwegian: mannskapsliste) from Ditio: who checked in on your projects and when they left, with project, employer, HSE card and check-in details. This is the data behind the crew list screen and Excel export in the Ditio backoffice.
When to use this
Section titled “When to use this”- You need attendance records per construction site (e.g. for byggherreforskriften mannskapsliste requirements or client audits)
- You want to sync who is on site into an HSE, access-control or BI system
- You need to know who is on site right now
Prerequisites
Section titled “Prerequisites”- API credentials with the
reportingapiv1scope — see Authentication - Results are scoped to the company and projects your credentials can access
# Test (default for all examples)export DITIO_IDENTITY_BASE="https://identity.ditio.dev"export DITIO_REPORTING_BASE="https://core-api.ditio.dev/reporting"How it works
Section titled “How it works”Field workers check in and out via the Ditio mobile app, the browser, or an on-site Ditio terminal (card reader). Each check-in creates a passage tied to a project. The crew list endpoint returns those passages — including workers from subcontractor companies on your projects, and terminal card swipes from people who are not Ditio users.
You get one record per passage, not one per person per day. If someone
leaves site and comes back, that is two records. A passage that is still
open — the person has not checked out — comes back with
checkOutDateTime: null and isOnSite: true.
Step-by-step
Section titled “Step-by-step”1. Authenticate
Section titled “1. Authenticate”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=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ -d "scope=reportingapiv1" | jq -r '.access_token')2. Fetch the crew list
Section titled “2. Fetch the crew list”curl -s "$DITIO_REPORTING_BASE/v1/crew-list-registrations" \ -H "Authorization: Bearer $TOKEN"With no date parameters you get today — which is what you want for “who is on site now”.
Query parameters:
| Parameter | Description |
|---|---|
ProjectIds | Comma-separated project ids. Omit for all projects you can access |
ProjectId | A single project id. Can be combined with ProjectIds |
FromDateTime / ToDateTime | A historical date window. Supply both or neither |
ModifiedSince / ModifiedBefore | Incremental sync — see below |
IncludeOpen | Include passages with no check-out yet. Defaults to true |
ContinuationToken | Paging cursor from the previous response |
ChunkLimit | Records per page. Default 2500, max 10000 |
3. Keep in sync
Section titled “3. Keep in sync”For an integration that runs continuously, sync on ModifiedSince rather
than re-reading a date window. Pass the time of your last successful sync;
you get everything created or changed since, including passages whose
check-in was days earlier.
curl -s "$DITIO_REPORTING_BASE/v1/crew-list-registrations?ModifiedSince=2026-08-17T09:00:00Z" \ -H "Authorization: Bearer $TOKEN"Records are paged. When more data is available the response carries a
continuationToken — pass it back until it is empty:
curl -s "$DITIO_REPORTING_BASE/v1/crew-list-registrations?ModifiedSince=$SINCE&ContinuationToken=$TOKEN_VALUE" \ -H "Authorization: Bearer $TOKEN"Records removed in Ditio come back as tombstones with isDeleted: true, so
you can retract them on your side. See
How extraction works for the full
sync model.
4. Read the response
Section titled “4. Read the response”{ "data": [ { "id": "5f2b8c1de4b0a12f34d56a78", "checkInSource": "APP", "userId": "7f3a09e2-1b64-4c1d-9a0e-2f5d8c4b7a11", "name": "Ola Nordmann", "firstName": "Ola", "lastName": "Nordmann", "birthDate": "01.05.1986", "hseCardId": "4388261", "hseCardExpirationDate": "2027-02-11T00:00:00Z", "organizationNumber": "987654321", "companyName": "Entreprenør AS", "isDitioUser": true, "projectId": "5f2b8c1de4b0a12f34d56a78", "projectName": "E39 Mandal – Lyngdal", "projectNumber": "1042", "externalHmsRegId": "1234567", "checkInDateTime": "2026-08-17T06:58:12Z", "checkOutDateTime": null, "isOnSite": true, "autoCompleted": false, "createdDateTime": "2026-08-17T06:58:12Z", "modifiedDateTime": "2026-08-17T06:58:12Z", "isDeleted": false } ], "continuationToken": null, "syncTypeName": "full", "recordCount": 1, "deletedRecordCount": 0}Field notes:
| Field | Description |
|---|---|
checkInDateTime / checkOutDateTime | When the person arrived and left, in UTC. checkOutDateTime is null while they are still on site |
isOnSite | true while the passage is open. This is the “who is here now” flag |
hseCardId / hseCardExpirationDate | HSE card (byggekort) number and expiry, when registered. null if the worker has no card on file |
organizationNumber / companyName | The employer of the checked-in worker — subcontractors report their own company |
isDitioUser | false for terminal card swipes by people without a Ditio account |
checkInSource | App, Browser or Terminal |
autoCompleted | true if the check-out was performed automatically rather than by the worker |
externalHmsRegId | The project’s HMSREG number, when configured |
isDeleted | Tombstone — the passage was removed in Ditio |
Python
Section titled “Python”import requests
base = "https://core-api.ditio.dev/reporting"headers = {"Authorization": f"Bearer {token}"}params = {"ModifiedSince": last_sync, "IncludeOpen": "true"}
while True: r = requests.get(f"{base}/v1/crew-list-registrations", headers=headers, params=params) r.raise_for_status() page = r.json()
for record in page["data"]: if record["isDeleted"]: retract(record["id"]) elif record["isOnSite"]: mark_on_site(record) else: mark_left(record)
token = page.get("continuationToken") if not token: break params["ContinuationToken"] = tokenvar query = $"v1/crew-list-registrations?ModifiedSince={Uri.EscapeDataString(lastSync)}";string? continuationToken = null;
do{ var path = continuationToken is null ? query : $"{query}&ContinuationToken={Uri.EscapeDataString(continuationToken)}";
var page = await client.GetFromJsonAsync<CrewListPage>(path);
foreach (var record in page!.Data) { // record.IsOnSite == true means the person has not checked out yet. }
continuationToken = page.ContinuationToken;} while (!string.IsNullOrEmpty(continuationToken));A complete, runnable integration — polling this endpoint and pushing
passages to an external HSE register — is in the
integration samples repository
under crew-list-chkbox/.
Excel export
Section titled “Excel export”The “Ditio Mannskapsliste” Excel file from the backoffice is also available,
on the Core API with the ditioapiv3 scope:
curl -s "$DITIO_API_BASE/api/v3/onlineusers/download/excel?fromDateStr=2026-07-01&toDateStr=2026-07-07" \ -H "Authorization: Bearer $TOKEN" \ -o "mannskapsliste.xlsx"It takes fromDateStr, toDateStr (both required, yyyy-MM-dd) and an
optional projIds parameter. The end date here is inclusive, and the file
always contains checked-in workers only.