Skip to content

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 Ditio Web.

  • 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
  • API credentials with the reportingapiv1 scope — see Authentication
  • Results are scoped to the company and projects your credentials can access

Examples use the environment variables from Environments and default to the test environment.

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.

Get a token with scope=reportingapiv1 into $TOKEN (set DITIO_SCOPE=reportingapiv1), as shown in Getting a token in your scripts.

Terminal window
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”. “Today” is the current UTC day (00:00–24:00 UTC), not your local day: in Norway, a check-in just after local midnight belongs to the previous UTC day until 01:00 or 02:00 local time.

Query parameters:

ParameterDescription
ProjectIdsComma-separated project ids. Omit for all projects you can access
ProjectIdA single project id. Can be combined with ProjectIds
FromDateTime / ToDateTimeA historical date window. Supply both or neither
ModifiedSince / ModifiedBeforeIncremental sync — see below
IncludeOpenInclude passages with no check-out yet. Defaults to true

Paging (ContinuationToken, ChunkLimit) works as on every extraction endpoint — see Pagination.

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.

Terminal window
curl -s "$DITIO_REPORTING_BASE/v1/crew-list-registrations?ModifiedSince=2026-08-17T09:00:00Z" \
-H "Authorization: Bearer $TOKEN"

Records are paged; follow continuationToken until it is empty, as described in Pagination.

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.

{
"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": "Example Road – Phase 2",
"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:

FieldDescription
checkInDateTime / checkOutDateTimeWhen the person arrived and left, in UTC. checkOutDateTime is null while they are still on site
isOnSitetrue while the passage is open. This is the “who is here now” flag
hseCardId / hseCardExpirationDateHSE card (byggekort) number and expiry, when registered. null if the worker has no card on file
organizationNumber / companyNameThe employer of the checked-in worker — subcontractors report their own company
isDitioUserfalse for terminal card swipes by people without a Ditio account
checkInSourceWhere the check-in was registered, e.g. App, Browser, Terminal or Integration. Treat it as an open set: other values can appear, so don’t fail on one you don’t recognise
autoCompletedtrue if the check-out was performed automatically rather than by the worker
externalHmsRegIdThe project’s HMSREG number, when configured
isDeletedTombstone — the passage was removed in Ditio
import os
# Paste get_token (/getting-started/authentication/#getting-a-token-in-your-scripts) and fetch_all (/getting-started/pagination/#fetching-all-pages-in-code) above this.
REPORTING_BASE = os.environ.get("DITIO_REPORTING_BASE", "https://core-api.ditio.dev/reporting")
headers = {"Authorization": f"Bearer {get_token('reportingapiv1')}"}
last_sync = "2026-08-17T09:00:00Z" # the time of your last successful sync
params = {"ModifiedSince": last_sync, "IncludeOpen": "true"}
for record in fetch_all(f"{REPORTING_BASE}/v1/crew-list-registrations", headers, params):
if record["isDeleted"]:
retract(record["id"]) # your logic
elif record["isOnSite"]:
mark_on_site(record) # your logic
else:
mark_left(record) # your logic
using System.Net.Http.Headers;
var reportingBase = Environment.GetEnvironmentVariable("DITIO_REPORTING_BASE")
?? "https://core-api.ditio.dev/reporting";
var lastSync = "2026-08-17T09:00:00Z"; // the time of your last successful sync
using var http = new HttpClient();
// DitioAuth.GetTokenAsync: see /getting-started/authentication/#token-expiry
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", await DitioAuth.GetTokenAsync(http, "reportingapiv1"));
var url = $"{reportingBase}/v1/crew-list-registrations" +
$"?ModifiedSince={Uri.EscapeDataString(lastSync)}&IncludeOpen=true";
// DitioPaging.FetchAllAsync: see /getting-started/pagination/#fetching-all-pages-in-code
await foreach (var record in DitioPaging.FetchAllAsync<CrewListRecord>(http, url))
{
if (record.IsDeleted)
Console.WriteLine($"Retract {record.Id}");
else if (record.IsOnSite)
Console.WriteLine($"{record.Name} is on site at {record.ProjectName}");
else
Console.WriteLine($"{record.Name} left {record.ProjectName} at {record.CheckOutDateTime:u}");
}
// Only the fields this example reads; add the others from the response as you need them.
record CrewListRecord(
string Id,
string? Name,
string? ProjectName,
DateTime CheckInDateTime,
DateTime? CheckOutDateTime,
bool IsOnSite,
bool IsDeleted);

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/.

The “Ditio Mannskapsliste” Excel file is a download in Ditio Web and is not part of the supported API. To produce a similar file from your integration, build it from the records above.