Skip to content

External Excavator State

Endpoints for pushing excavator operating states (idle, moving, working) from a telematics or fleet management system into Ditio, and for reading them back.

MethodRouteDescription
POSTapi/external-excavator-stateRegister one state record
POSTapi/external-excavator-state/importBulk import (upsert) state records
GETapi/external-excavator-state/latest-timestamp/{companyId}/{projectId}Get the sync checkpoint
POSTapi/external-excavator-state/aggregated-data-per-stateAggregate states for a project and period
GETapi/external-excavator-state/{id}Get one state record
PUTapi/external-excavator-state/{id}Update one state record (see the note under Update)
DELETEapi/external-excavator-state/{id}Delete one state record

Routes are relative to $DITIO_MASSTRANSPORT_BASE (see Environments) and need a token with the masstransportapiv1 scope (see Authentication). For a walkthrough with examples, see the Machine Integration guide.

Each record is one machine’s state at one point in time. A machine stays in that state until its next record. Ditio doesn’t need to know your machines or projects in advance: both are your own ids.

Property names are camelCase in responses and case-insensitive in requests.

FieldTypeDescription
idstringDitio’s id for the record (a 24-character hex string). Set by Ditio; leave it out when you create records.
companyIdstringYour Ditio company id. Send it on every record: the sync checkpoint and the aggregation find records by it.
externalMachineIdstringThe machine’s id in your system.
externalProjectIdstringThe project or site id in your system. This is the {projectId} of the sync checkpoint and the projectId of the aggregation.
timeStampstring (date-time)When the machine entered this state. Send ISO 8601 in UTC with a Z suffix, e.g. 2026-10-02T07:41:12Z.
stateinteger0 = Idle, 1 = Moving, 2 = Working. Send the number: a string such as "Working" is rejected with 400.
geoPointobjectOptional position of the machine. See geoPoint.
FieldTypeDescription
typestringSend "Point". Required when you send geoPoint; a missing type, or a value other than "Point" or "Polygon", gives 400.
coordinatesarray of number[longitude, latitude] in WGS 84 decimal degrees, longitude first.
accuracynumberOptional accuracy in metres. Defaults to 0.
propertiesobjectOptional { "name": string, "description": string }.

Responses also include a read-only isValidPoint (boolean) on geoPoint. Leave out geoPoint entirely if you have no position.

{
"companyId": "YOUR_COMPANY_ID",
"externalMachineId": "EX-042",
"externalProjectId": "SITE-17",
"timeStamp": "2026-10-02T07:41:12Z",
"state": 2,
"geoPoint": {
"type": "Point",
"coordinates": [10.7522, 59.9139],
"accuracy": 5
}
}
POST /api/external-excavator-state

Body: one state record.

Response: 201 Created with the stored record, including its id.

Single registration always inserts a new record: sending the same machine, project and timestamp twice stores two records. Use Bulk Import for anything you may resend.

POST /api/external-excavator-state/import

Body: a JSON array of state records, each with your companyId. An empty array gives 400.

Response: 200 OK with the submitted array, each item with an id.

Import is an upsert. The key is companyId + externalMachineId + externalProjectId + timeStamp:

  • A new key inserts a record.
  • An existing key updates the record’s state and geoPoint. Its stored id doesn’t change, so the id returned for that item is not the stored one.

Resending a batch is therefore safe, and it is the way to correct a state you already sent.

GET /api/external-excavator-state/latest-timestamp/{companyId}/{projectId}
ParameterDescription
companyIdYour Ditio company id, the same value you send in companyId on import
projectIdYour externalProjectId

Response: 200 OK with a bare JSON number: the timeStamp of the newest record for that company and external project, in Unix seconds (UTC). It is 0 when there are no records.

1790926872

How to use it is described under Sync checkpoint.

POST /api/external-excavator-state/aggregated-data-per-state

Aggregates the records of one external project in a period, for your company.

FieldTypeDescription
dateFromstring (date-time)Start of the period (inclusive).
dateTostring (date-time)End date. The whole day is included: send the date at midnight, e.g. 2026-10-02T00:00:00Z covers up to 2026-10-02T23:59:59Z.
projectIdstringYour externalProjectId. Only records with exactly this value are counted, so always send it.
excavatorIdsarray of stringOptional. Matched against the record id (Ditio’s id), not externalMachineId. Leave it out or send [] to include every machine.
{
"dateFrom": "2026-10-01T00:00:00Z",
"dateTo": "2026-10-02T00:00:00Z",
"projectId": "SITE-17",
"excavatorIds": []
}

200 OK with an object keyed by the state number as a string. All three keys are always present.

{
"0": 41,
"1": 12,
"2": 87
}
GET /api/external-excavator-state/{id}

Response: 200 OK with the state record. An id that is not a 24-character hex string gives 400 (InvalidExternalExcavatorState); an unknown id gives 404.

PUT /api/external-excavator-state/{id}
DELETE /api/external-excavator-state/{id}

Response: 200 OK with the deleted record. An id that is not a 24-character hex string gives 400; an unknown id gives 404 (ExternalExcavatorStateNotFound).

Error bodies, status codes and retry rules are described in Error Handling. Specific to this API:

StatusWhen
400The body is not valid JSON, a field can’t be read as its type (for example state as a string), geoPoint.type is missing or not "Point"/"Polygon", the import array is empty, or an {id} is not a 24-character hex string
401The token is missing, expired or lacks the masstransportapiv1 scope
404No record with that {id} (get and delete)