Machine Integration
This guide covers how to send machine state data (excavator idle/working/moving states) from an external system into Ditio. This is the primary integration point for telematics providers and fleet management systems.
When to Use This
Section titled “When to Use This”- You have a fleet management system that tracks excavator operating states
- You want machine utilization data to appear in Ditio’s production analytics
- You need to sync historical machine data (daily batch uploads)
- You’re a telematics provider integrating with Ditio on behalf of a customer
Prerequisites
Section titled “Prerequisites”- API credentials with the
masstransportapiv1scope — see Authentication - A company ID and project ID in Ditio, plus the Mass Transport API base URL
(
DITIO_MASSTRANSPORT_BASEin the examples below) — both provided by your Ditio contact during onboarding
How It Works
Section titled “How It Works”Ditio tracks excavator states to calculate machine utilization and production rates. External systems can push state data via the Machine Integration API. Each state record represents a time period where a machine was in a specific operating state (idle, working, moving, etc.).
The typical flow:
- Your system collects machine state data from telematics hardware
- You push state records to Ditio (individually or in bulk)
- Ditio processes the data and makes it available in reports and dashboards
- Your customer sees combined Ditio + external machine data in one place
Step-by-Step
Section titled “Step-by-Step”1. Push a Single Machine State
Section titled “1. Push a Single Machine State”curl -X POST $DITIO_MASSTRANSPORT_BASE/api/external-excavator-state \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "companyId": "company-123", "projectId": "project-456", "machineId": "EX-001", "state": "Working", "startTime": "2025-01-15T08:00:00Z", "endTime": "2025-01-15T08:45:00Z" }'2. Bulk Import (Recommended for Production)
Section titled “2. Bulk Import (Recommended for Production)”For production integrations, use the bulk import endpoint to send multiple records at once:
curl -X POST $DITIO_MASSTRANSPORT_BASE/api/external-excavator-state/import \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '[ { "companyId": "company-123", "projectId": "project-456", "machineId": "EX-001", "state": "Working", "startTime": "2025-01-15T08:00:00Z", "endTime": "2025-01-15T08:45:00Z" }, { "companyId": "company-123", "projectId": "project-456", "machineId": "EX-001", "state": "Idle", "startTime": "2025-01-15T08:45:00Z", "endTime": "2025-01-15T09:00:00Z" } ]'3. Sync Checkpoint
Section titled “3. Sync Checkpoint”Before sending data, check what you’ve already sent by getting the latest timestamp:
curl -H "Authorization: Bearer $TOKEN" \ "$DITIO_MASSTRANSPORT_BASE/api/external-excavator-state/latest-timestamp/company-123/project-456"This returns the timestamp of the most recent record Ditio has received. Only send data newer than this to avoid duplicates.
4. Query Aggregated Data
Section titled “4. Query Aggregated Data”Check machine utilization analytics:
curl -X POST $DITIO_MASSTRANSPORT_BASE/api/external-excavator-state/aggregated-data-per-state \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "companyId": "company-123", "projectId": "project-456", "fromDate": "2025-01-01", "toDate": "2025-01-31" }'Complete Example (Python)
Section titled “Complete Example (Python)”import requestsfrom datetime import datetime, timezone
import os
TOKEN = "your-access-token"BASE_URL = os.environ["DITIO_MASSTRANSPORT_BASE"] + "/api/external-excavator-state"HEADERS = { "Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json",}
COMPANY_ID = "company-123"PROJECT_ID = "project-456"
# Step 1: Check sync checkpointlatest = requests.get( f"{BASE_URL}/latest-timestamp/{COMPANY_ID}/{PROJECT_ID}", headers=HEADERS,)last_sync = latest.json().get("latestTimestamp")print(f"Last synced: {last_sync}")
# Step 2: Collect new records from your systemnew_records = [ { "companyId": COMPANY_ID, "projectId": PROJECT_ID, "machineId": "CAT-336F", "state": "Working", "startTime": "2025-01-15T07:00:00Z", "endTime": "2025-01-15T09:30:00Z", }, { "companyId": COMPANY_ID, "projectId": PROJECT_ID, "machineId": "CAT-336F", "state": "Idle", "startTime": "2025-01-15T09:30:00Z", "endTime": "2025-01-15T10:00:00Z", },]
# Step 3: Bulk importresp = requests.post(f"{BASE_URL}/import", headers=HEADERS, json=new_records)if resp.status_code == 201: print(f"Imported {len(new_records)} state records")else: print(f"Error: {resp.status_code} - {resp.text}")Common Issues
Section titled “Common Issues”| Error | Cause | Fix |
|---|---|---|
400 ArgumentIsNull | Empty array sent to import | Include at least one record |
401 Unauthorized | Token expired | Refresh your access token |
403 Forbidden | Token missing the masstransportapiv1 scope, or client not enabled for the company/project | Request the scope explicitly; contact your Ditio contact to enable write access |
Related
Section titled “Related”- Weight Measures — Push weight/scale data to Ditio
- Equipment Data — Export equipment metadata