ERP Integration
Connect Haltless to an ERP/MES system, push and pull data, 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_id": "AUFNR",
"machine_id": "EQUNR"
}
}
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 |
The sync_interval_minutes value governs how often automatic syncs run for the auto_* toggles you enable.
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.
Supported combinations:
| Entity type | Outbound | Inbound |
|---|---|---|
work_order | Push work orders | — |
production_data | Push production/OEE data | — |
downtime | Push downtime records | — |
machine | — | 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
}