Skip to main content

ERP Integration

Connect Haltless to an ERP system, push work orders, production data, and downtime to it, pull asset (machine) records from it, and review sync history. Supported providers: SAP, Microsoft Dynamics 365, and Oracle. All endpoints are authenticated with a Bearer JWT (see Authentication).

Endpoints​

MethodPathDescription
GET/api/v1/erp/connectionsList connections
POST/api/v1/erp/connectionsCreate a connection (Admin)
GET/api/v1/erp/connections/{connection_id}Get a connection
PATCH/api/v1/erp/connections/{connection_id}Update a connection (Admin)
DELETE/api/v1/erp/connections/{connection_id}Delete a connection (Admin)
POST/api/v1/erp/connections/{connection_id}/testTest connectivity (Admin)
POST/api/v1/erp/connections/{connection_id}/syncTrigger a sync
GET/api/v1/erp/connections/{connection_id}/logsSync logs for a connection
GET/api/v1/erp/logsSync logs across all connections

Endpoints marked Admin require an account administrator role.

Connections​

Create a connection​

POST /api/v1/erp/connections

Provider credentials go in the config object; its required keys depend on the provider. Connection targets must be reachable over HTTPS at a public host.

{
"provider": "sap",
"name": "SAP Production",
"config": {
"base_url": "https://sap.example.com",
"client": "100",
"username": "haltless_integration",
"password": "••••••"
},
"is_active": true,
"auto_push_work_orders": false,
"auto_push_production_data": false,
"auto_push_downtime": false,
"auto_pull_assets": false,
"sync_interval_minutes": 60,
"field_mapping": {
"work_order": { "MaintOrderDesc": "ZZ_ShortText" }
}
}

field_mapping renames fields in what Haltless sends, per entity: work_order, production_data, or downtime. Each entry maps a field name Haltless would send to the name your ERP expects; fields not listed are sent unchanged.

Required config keys by provider:

ProviderRequired config keys
sapbase_url, client, username, password
dynamicsbase_url, tenant_id, client_id, client_secret
oraclebase_url, username, password
note

Syncs run when you trigger them, with POST /api/v1/erp/connections/{connection_id}/sync or from the ERP settings page. The auto_* toggles and sync_interval_minutes are saved with the connection, but automatic, scheduled syncing is not available yet.

Connection response​

Secret values inside config are masked in every response.

{
"id": "...",
"tenant_id": "...",
"provider": "sap",
"name": "SAP Production",
"config": { "base_url": "https://sap.example.com", "client": "100", "username": "haltless_integration", "password": "***" },
"is_active": true,
"auto_push_work_orders": false,
"auto_push_production_data": false,
"auto_push_downtime": false,
"auto_pull_assets": false,
"sync_interval_minutes": 60,
"field_mapping": { "work_order_id": "AUFNR" },
"last_sync_at": "2026-08-05T10:00:00Z",
"last_sync_status": "success",
"created_by": "USER_UUID",
"created_at": "2026-08-01T09:00:00Z",
"updated_at": "2026-08-05T10:00:00Z"
}

Test a connection​

POST /api/v1/erp/connections/{connection_id}/test

{
"success": true,
"message": "Successfully connected.",
"provider": "sap"
}

Syncs​

Trigger a sync​

POST /api/v1/erp/connections/{connection_id}/sync

{
"direction": "outbound",
"entity_type": "work_order",
"entity_id": "WORK_ORDER_UUID"
}
  • direction is outbound (push to the ERP) or inbound (pull into Haltless).
  • entity_id is optional and targets a single record on an outbound push.
  • Requires an operator or administrator whose access covers all machines; a user limited to some machine groups gets 403.
  • A push sends each record once, oldest first, and stops after a time budget; records left over are sent by the next sync, and the response ends with a skipped entry saying how many are waiting. A pull updates the location of machines it can match by external asset id or by identifier; it never creates machines.

Supported combinations:

Entity typeOutboundInbound
work_orderPush work ordersNot supported
production_dataPush production/OEE dataNot supported
downtimePush downtime recordsNot supported
machineNot supportedPull asset master data

An unsupported combination returns 400. The response is a list of sync-log entries for the operation.

Sync logs​

GET /api/v1/erp/connections/{connection_id}/logs and GET /api/v1/erp/logs

Both are paginated (page, page_size).

{
"items": [
{
"id": "...",
"erp_connection_id": "...",
"direction": "outbound",
"entity_type": "work_order",
"entity_id": "...",
"external_id": "AUFNR-000123",
"status": "success",
"error_message": null,
"request_summary": "1 work order",
"response_summary": "created",
"created_at": "2026-08-05T10:00:00Z"
}
],
"total": 1,
"page": 1,
"page_size": 50
}