Skip to content

Equipment Data

Machines are money on a construction site — knowing where each excavator is registered, how many hours it ran, and on whose project, is what makes fleet cost tracking work. This guide covers the two halves of equipment data in Ditio: maintaining the machine catalogue (write) and extracting usage records (read).

  • Your fleet management system is the master record and Ditio should mirror it
  • You bill customers for machine hours and need completed usage records — including when your machines work on other companies’ projects
  • You’re building utilization dashboards per machine, project, or department
  • API credentials — see Authentication
  • Scope ditioapiv3 for catalogue writes, reportingapiv1 for usage extraction (request both in one token: scope=ditioapiv3 reportingapiv1)
Terminal window
# Test (default for all examples)
export DITIO_API_BASE="https://core-api.ditio.dev/core"
export DITIO_REPORTING_BASE="https://core-api.ditio.dev/reporting"
# Production — only after verifying in test
# export DITIO_API_BASE="https://core-api.ditio.app/core"
# export DITIO_REPORTING_BASE="https://core-api.ditio.app/reporting"

Use the Machines & Equipment API to create and maintain machines. The short version:

  1. Fetch valid machine typesGET /api/MachineType returns your company’s configured types; the typeId you send on create must match one
  2. Create machines with your fleet numbers as machineNumber
  3. Keep them freshPATCH hour meters and service dates on a schedule
  4. Deactivate, don’t delete — retired machines get active: false
Terminal window
curl -X POST "$DITIO_API_BASE/api/v4/integration/machines" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"companyId": "YOUR_COMPANY_ID",
"machineNumber": "M-042",
"name": "Volvo A30G",
"typeId": "dumper",
"active": true
}'

Full field reference, bulk endpoints, and the machines-vs-equipment distinction: Machines & Equipment.

The Machine Registrations endpoint streams completed usage records for the machines your company owns — including registrations made on other companies’ projects (e.g. when your machine is rented out).

Terminal window
# Everything created or edited since your last sync
curl -s -G "$DITIO_REPORTING_BASE/v1/machine-registrations" \
-H "Authorization: Bearer $TOKEN" \
--data-urlencode "ModifiedSince=2026-07-01T00:00:00Z"

Key behaviors:

  • Incremental sync (ModifiedSince) catches new and edited registrations — including edits to old records that a date-window query would miss. Deleted records arrive as tombstones with isDeleted: true.
  • Cross-company privacy: when your machine ran on another company’s project, that company’s personal identifiers (driverName, driverId) are returned empty — you still get the machine, project, times, quantity, and the operator’s company name.
  • Pagination: follow continuationToken until empty — see Pagination.

Python example — utilization per machine

Section titled “Python example — utilization per machine”
import os
from collections import defaultdict
import requests
REPORTING_BASE = os.environ.get(
"DITIO_REPORTING_BASE", "https://core-api.ditio.dev/reporting"
)
headers = {"Authorization": f"Bearer {token}"}
hours_by_machine = defaultdict(float)
params = {
"FromDateTime": "2026-06-01T00:00:00Z",
"ToDateTime": "2026-07-01T00:00:00Z",
}
while True:
page = requests.get(
f"{REPORTING_BASE}/v1/machine-registrations",
headers=headers, params=params,
).json()
for registration in page["data"]:
hours_by_machine[registration["machineName"]] += registration["qty"]
continuation = page.get("continuationToken")
if not continuation:
break
params["ContinuationToken"] = continuation
for machine_name, hours in sorted(hours_by_machine.items(), key=lambda x: -x[1]):
print(f"{machine_name}: {hours:.1f}")

To resolve resource IDs appearing in other exports (time registrations, payroll lines) into names and numbers, use the resource metadata endpoint — see Resource Metadata (GET /v1/resource on the reporting base).

IssueCauseFix
MachineService.machineTypeInvalid on createtypeId doesn’t match a configured typeFetch GET /api/MachineType first and map your categories to valid typeId values
Operator names empty in extractionThe registration involves another company’s employeeExpected — cross-company personal data is redacted by design
Edits missing from date-window pullsFull sync only sees the stop-time windowUse incremental sync (ModifiedSince) for ongoing updates