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
| Method | Path | Description |
|---|---|---|
GET | /api/v1/erp/connections | List connections |
POST | /api/v1/erp/connections | Create 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}/test | Test connectivity (Admin) |
POST | /api/v1/erp/connections/{connection_id}/sync | Trigger a sync |
GET | /api/v1/erp/connections/{connection_id}/logs | Sync logs for a connection |
GET | /api/v1/erp/logs | Sync 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:
| Provider | Required config keys |
|---|---|
sap | base_url, client, username, password |
dynamics | base_url, tenant_id, client_id, client_secret |
oracle | base_url, username, password |
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"
}
directionisoutbound(push to the ERP) orinbound(pull into Haltless).entity_idis 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
skippedentry 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 type | Outbound | Inbound |
|---|---|---|
work_order | Push work orders | Not supported |
production_data | Push production/OEE data | Not supported |
downtime | Push downtime records | Not supported |
machine | Not supported | Pull 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
}