DEV Community

Smrati
Smrati

Posted on

Integrating asset tracking data with ERP systems: a developer's guide

Data for asset tracking in its own silo is valuable. But asset tracking data entering your ERP – updating inventory management data, generating purchase orders, creating maintenance workflows – is truly revolutionary. This is how you can make such an integration without adding to the already heavy maintenance burden.

Why you should consider such integration

Most often asset tracking systems and ERP systems are created independently of each other and serve entirely different goals. Asset tracking systems have information about locations of assets and their condition. ERP systems, in turn, contain all data on cost, ownership, and workflows associated with those assets. Both types of systems complement each other perfectly.

Properly done, such integration makes it possible to automatically reconcile inventory, do usage-based depreciations, generate maintenance workflows, and kick off purchasing processes.

The four touchpoints of integration

Location synchronization

Positioning data being synchronized into ERP inventory management — exact positioning in real time of the asset based on SKU or asset identifier

Maintenance initiation

Thresholds or usage hours automatically initiating a maintenance order on the ERP CMMS module

Inventory sync

Tracking data continuously synchronizing inventory counts to the ERP — no cycle counts necessary

Depreciation & lifecycle

Usage hours automatically populating ERP asset register records — actual usage depreciation rather than linear

Three ways of achieving the integration

Approach Implementation Description
Direct API Tracking system invokes ERP API REST/SOAP on each event Small number of events, simple environment, high coupling tolerable
Event queue Tracking events written to Kafka or RabbitMQ event queue Large numbers of events, ERP rate limits, replay required
Middleware ERP connection done via MuleSoft/Boomi or custom middleware multiple ERP modules, enterprise-level requirements

Step 1 – Normalize the Asset Data Model

There has to be a single standard data model for your assets before you start making API calls. The ERP system IDs and tracking system IDs of your assets are most likely different. Create a mapping layer first.

// Asset ID mapping — tracking system ID → ERP asset number
const assetMap = {
  'tag-7821': { erpId: 'ASSET-00421', erpModule: 'fixed-assets' },
  'tag-7822': { erpId: 'ASSET-00422', erpModule: 'inventory' },
}

function normalizeEvent(trackingEvent) {
  const mapping = assetMap[trackingEvent.assetId]
  if (!mapping) throw new Error(`No ERP mapping for ${trackingEvent.assetId}`)

  return {
    erpAssetId: mapping.erpId,
    erpModule: mapping.erpModule,
    location: trackingEvent.location,
    condition: trackingEvent.sensors,
    timestamp: trackingEvent.ts,
    source: 'asset-tracking'
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2 – Post asset location updates to ERP inventory

ERP systems have evolved enough today to allow RESTful API calls for inventory updates (SAP, Oracle, Microsoft Dynamics, etc.). Here is a way of pushing the asset location information through API calls to your ERP system’s warehouse management module:

// Push location update to ERP — SAP-style REST endpoint
async function syncLocationToERP(normalizedEvent) {
  const { erpAssetId, location, timestamp } = normalizedEvent

  const response = await fetch(`${ERP_BASE_URL}/api/v1/assets/${erpAssetId}/location`, {
    method: 'PATCH',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${ERP_TOKEN}`,
      'X-Source-System': 'asset-tracking'
    },
    body: JSON.stringify({
      warehouseLocation: location.zone,
      coordinates: { lat: location.lat, lng: location.lng },
      lastSeen: timestamp
    })
  })

  if (!response.ok) {
    await queueForRetry(normalizedEvent)  // never drop failed syncs
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3 – Create maintenance work orders automatically
Upon the occurrence of breaches of the threshold values of the sensors or service intervals due to usage hour counts of your assets, the software integration solution can automatically create work orders in the ERP system’s maintenance module:

// Triggered when asset tracking fires a maintenance alert
async function createWorkOrder(alert) {
  const { erpAssetId } = normalizeEvent(alert)

  const workOrder = {
    assetId: erpAssetId,
    type: 'PREVENTIVE',
    priority: alert.severity === 'critical' ? 'HIGH' : 'MEDIUM',
    description: `Auto-generated: ${alert.triggerReason}`,
    triggeredBy: 'iot-sensor',
    sensorData: alert.sensorSnapshot,
    scheduledFor: getNextMaintenanceWindow()
  }

  await fetch(`${ERP_BASE_URL}/api/v1/work-orders`, {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${ERP_TOKEN}` },
    body: JSON.stringify(workOrder)
  })
}
Enter fullscreen mode Exit fullscreen mode

Idempotence tip: Most ERP systems’ API endpoints are not designed to tolerate duplicate API requests. Be sure to include an idempotency key such as “X-Idempotency-Key: ” on each request.

Step 4 - Manage ERP rate limits through a queue
ERPs are not designed to withstand the ingestion volume from IoT systems. The default API rate limit from SAP is usually 100-500 requests per minute, while your IoT tracking system might be generating 10x more. Queue layer will buffer spikes and write records intelligently.

// Queue-based ERP sync — batches events, respects rate limits
const erpQueue = []
let processing = false

async function flushToERP() {
  if (processing || erpQueue.length === 0) return
  processing = true

  const batch = erpQueue.splice(0, 50)  // process 50 at a time
  await Promise.allSettled(batch.map(syncLocationToERP))

  processing = false
  setTimeout(flushToERP, 1000)  // 1 req/sec rate limiting
}

// Called every time a tracking event arrives
function queueERPSync(event) {
  erpQueue.push(normalizeEvent(event))
  flushToERP()
}
Enter fullscreen mode Exit fullscreen mode

Do NOT call ERP API from your MQTT handler directly. If the ERP is slow or rate-limited, your entire IoT data ingestion process would be halted. You should always decouple your ingestion with a queue, even if it is an in-memory queue for small-scale deployment.

Popular ERPs and their APIs

SAP S/4HANA
RESTful OData v4 endpoints. Well documented, rate limited. Use SAP Integration Suite for complex mapping. Asset Management module supports usage-based record update.

Oracle ERP Cloud
REST APIs for the Fixed Assets and Inventory module. Allows bulk import using FBDI endpoint for location update at scale. Offers webhook support for outgoing messages.

MS Dynamics 365
Dataverse (OData) API. Asset Management module works well with IoT Hub out-of-the-box. Use Power Automate for IoT tracking -> ERP processes with no code.

NetSuite
SuiteScript REST API. Lightweight and friendly to developers. Good choice for midmarket solutions, when other ERPs have too much overhead.

Recommended technology stack

  1. Node.js / Python
  2. Kafka / RabbitMQ
  3. Redis (de-duplication cache)
  4. REST / OData
  5. MuleSoft / Boomi
  6. PostgreSQL (audit logs)

Always keep an audit log of all ERP sync attempts made — whatever was synced, what did the ERP reply with, and whether a retry was required. If a data discrepancy in your ERP is detected six months down the line, this is how you will be able to track what went on and when.

AssetTrackPro's integrations come with out-of-the-box connectors for SAP, Oracle, and Microsoft Dynamics, so all your tracking data is connected to your ERP right off the bat. Check out our integrations →

Are you connecting asset tracking with your ERP? Leave the integration layer to AssetTrackPro.
Learn more about AssetTrackPro →

Top comments (0)