Skip to content

Safety Reporting

HSE data is only useful if it reaches the people who act on it. Ditio captures incidents (alerts), checklist submissions, and machine inspections in the field — this guide covers pulling that data out for HSE dashboards, compliance archives, and external safety management systems.

  • You aggregate HSE KPIs (incident counts, checklist completion rates) across systems in a BI tool
  • Your compliance process requires archiving submitted checklists and incident reports as PDFs outside Ditio
  • You forward incidents to an external safety management system
  • API credentials with the reportingapiv1 scope — see Authentication
  • Understanding of Pagination — all extraction endpoints use continuation tokens
Terminal window
# Test (default for all examples)
export DITIO_REPORTING_BASE="https://core-api.ditio.dev/reporting"
# Production — only after verifying in test
# export DITIO_REPORTING_BASE="https://core-api.ditio.app/reporting"
EndpointDescription
GET /v1/incident-registrationsSafety/HSE incident reports (alerts)
GET /v1/checklist-registrationsQA and safety checklist submissions
GET /v1/machine-checklist-registrationsMachine inspection checklists
GET /v1/machine-incident-registrationsMachine-specific safety incidents

All four support the shared extraction filters (FromDateTime/ToDateTime for full sync, ModifiedSince/ModifiedBefore for incremental sync, ProjectId, CompanyId, ChunkLimit, ContinuationToken).

Terminal window
curl -s -G "$DITIO_REPORTING_BASE/v1/incident-registrations" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "FromDateTime=2026-06-01T00:00:00Z" \
--data-urlencode "ToDateTime=2026-07-01T00:00:00Z"

Follow continuationToken until empty. For ongoing syncs, switch to ModifiedSince with your last successful sync timestamp — that also catches records edited after the fact.

Each incident, checklist, and absence record carries a pdfUrl field — an absolute link to the PDF Ditio generated when the record was submitted. It is null until generation has happened; skip those records and pick them up on the next sync. Fetch the bytes with the same bearer token. Full details: PDF Extraction.

Terminal window
curl -s -G "$DITIO_REPORTING_BASE/v1/checklist-registrations" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "ModifiedSince=2026-06-01T00:00:00Z" \
| jq -r '.data[] | select(.pdfUrl != null) | .pdfUrl' \
| while read -r url; do curl -sL -H "Authorization: Bearer $TOKEN" -O "$url"; done

Checklist records also expose the files attached inside the checklist via sections[].attachments[].url and sections[].images[].url.

Photos attached to incidents and checklists (and feed posts) are available in one paginated stream through Image Extraction, with GPS coordinates, uploader, and project/task context per image. Use Sources=alert,checklist to skip feed images:

Terminal window
curl -s -G "$DITIO_REPORTING_BASE/v1/images" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "Sources=alert" \
--data-urlencode "Sources=checklist" \
--data-urlencode "ModifiedSince=2026-06-01T00:00:00Z"
import os
import requests
REPORTING_BASE = os.environ.get(
"DITIO_REPORTING_BASE", "https://core-api.ditio.dev/reporting"
)
headers = {"Authorization": f"Bearer {token}"}
def extract_all(endpoint, last_sync_timestamp):
params = {"ModifiedSince": last_sync_timestamp}
while True:
page = requests.get(
f"{REPORTING_BASE}/v1/{endpoint}", headers=headers, params=params
).json()
yield from page["data"]
continuation = page.get("continuationToken")
if not continuation:
break
params["ContinuationToken"] = continuation
last_sync = "2026-06-01T00:00:00Z"
for incident in extract_all("incident-registrations", last_sync):
forward_to_hse_system(incident) # your logic
if incident.get("pdfUrl"):
pdf = requests.get(incident["pdfUrl"], headers=headers).content
archive_pdf(incident["id"], pdf) # your logic
IssueCauseFix
pdfUrl is nullThe PDF hasn’t been generated yet (happens on submit/report)Skip and pick up on the next incremental sync
Missing recent editsFull sync filters on creation windowUse ModifiedSince incremental sync for ongoing pulls
403 ForbiddenToken lacks access to the requested project/companyCheck the ProjectId/CompanyId filter and your client’s company