Dataflow architecture, Comarch ERP XL REST API, synchronization with the production environment and 5 pitfalls that cost companies months of delay.
Imagine a machine on the shop floor has just stopped an important order. The MES has known about it for a few minutes. The ERP still sees the order as "in progress". The IT help desk has not received any ticket yet. When the technician finally opens Jira, they lose more minutes gathering context from three different systems. The lack of integration between IT, ERP and production systems means that important operational events get lost in silos or reach the help desk with a delay. This article describes how to build the integration that prevents that: from architecture, through REST APIs, to production monitoring.
Integrations Jira-ERP sound like a weekend project until you start. Reality turns out to be far more complex, and for concrete architectural reasons, not random difficulties.
Jira thinks in terms of issue, project, workflow, SLA. ERP (Comarch, SAP, Sage) sees the world through orders, invoices, counterparties, fixed assets. MES operates on work orders, operations, machines, batches, quality. These three ontologies do not map 1:1; every transformation requires business decisions, not just technical ones.
The ERP changes data on a scale of minutes to hours (new order, invoice status change). Jira operates on minutes to days (ticket opening, status change, comment). MES generates events every second: machine alarms, production parameter changes, sensor readings. A synchronous integration that works for the ERP can completely fall over under the load from the MES.
Jira offers a modern REST API with pagination, webhooks and good documentation. Comarch ERP XL uses a native API based on a DLL library (CDN_API.DLL); integration with Jira requires middleware or a proxy service. Older installations also use a SOAP or COM+ interface. MES systems often have no REST API at all - they communicate over OPC-UA, MQTT, CSV files or proprietary binary protocols. That requires separate adapters for each layer.
The most durable pattern for Jira+ERP+MES integration is event-driven hub-and-spoke with a central middleware layer. Avoid point-to-point integration: with N systems it generates N x (N-1)/2 connections - for 3 systems that is 3 connections, for 5 systems it is already 10.
Hub-and-spoke model: each system talks only to the middleware
It is critical to establish a Master Data Management split - which system owns which data:
Every system can read data from the other systems (through middleware). Writes should happen only through the master system: middleware never overwrites data while bypassing the owner. If you want to understand general system integration patterns via API (REST, webhooks and middleware), read our comprehensive guide to system integration.
Below we cover a concrete, most common scenario: a service ticket in Jira SM is to be automatically enriched with counterparty and fixed asset data from Comarch ERP XL, without manual copying.
Comarch ERP XL uses a native API based on a DLL library (CDN_API.DLL). Integration with Jira requires middleware or a proxy service. An example authorization endpoint for environments that expose a REST layer:
// POST /api/token { "grant_type": "client_credentials", "client_id": "your_client_id", "client_secret": "your_client_secret", "scope": "api" }
The token has a TTL of 3,600 seconds. The middleware should refresh it with a 60-second margin, never on demand (this avoids a race condition on concurrent requests).
In Jira SM: Settings → System → WebHooks → Create WebHook. Set:
https://n8n.yourdomain.pl/webhook/jira-erp)jira:issue_created, jira:issue_updatedproject = "SERVICE" AND issuetype = "Customer service"Jira will send a JSON payload with the full issue object. The middleware must reply 200 OK within 20 seconds; move any longer processing to an asynchronous queue.
From the Jira payload extract the field containing the NIP or client ID (custom field). The middleware then runs:
// GET /api/Kontrahenci?nip={nip} Authorization: Bearer {token} // ERP response: { "Id": "KNT-001234", "Nazwa": "Acme Manufacturing Sp. z o.o.", "OpisTrwaly": "Premium service contract until 2027-06-30", "OpiekunId": "USR-042" }
Map the ERP response onto Jira fields (custom fields) and send a PATCH to the Jira API.
// PUT /rest/api/3/issue/{issueKey} { "fields": { "customfield_10201": "KNT-001234", // ERP counterparty ID "customfield_10202": "Acme Manufacturing", // Company name "customfield_10203": "Premium until 2027-06-30", // Contract status "priority": { "name": "High" } // from ERP SLA conditions } }
Important: custom field IDs (customfield_XXXXX) are specific to each Jira instance. Fetch them via GET /rest/api/3/field and store them in the middleware configuration. Do not hardcode them.
When the Jira ticket changes status to Resolved or Closed, the middleware calls the ERP API to update the complaint/service request status. If you manage SLAs and queues in JSM day-to-day, see also how to configure SLA and escalations in Jira Service Management. Key requirement: idempotency - the same message processed twice must not duplicate a record in the ERP. Use a unique externalId (Jira key) as the deduplication identifier.
Integration with the MES plays by different rules than integration with the ERP. Three key differences you need to address at the design stage:
The MES generates machine alerts on a second-level frequency. Do not use HTTP polling to read MES events. Instead, configure push via MQTT or WebSocket. The middleware subscribes to a MES topic (mes/line1/alarm/critical) and on each event decides whether to open a new Jira ticket, update an existing one, or ignore it (duplicate).
A machine can generate 200 alarms of the same type within a minute (flapping). The middleware must implement window deduplication: if an alarm of the same type from the same machine appeared in the last 5 minutes, do not create a new ticket. Add a note to the existing one.
A Jira ticket created from a MES alarm should contain the full context: work order number, machine/line designation, the value of the parameter that crossed the threshold, the last 10 operations on that machine. Without that, the IT technician cannot assess the severity of the incident without calling the shop floor, which negates the benefits of the integration.
The choice of middleware platform has the greatest impact on the cost of maintaining the integration over 3-5 years. Below is a comparison of the five most popular options for an SME manufacturing company:
| Integration scenario | Recommended tool | Difficulty | Starting cost | Implementation time |
|---|---|---|---|---|
| Jira ↔ ERP (REST↔REST) | n8n self-hosted | Low | ~0 PLN/month | 1-3 days |
| Jira ↔ ERP ↔ MES (full triad) | n8n + Redis queue | Medium | ~200 PLN/month (hosting) | 2-4 weeks |
| Jira ↔ ERP with audit logging | Make (Integromat) | Low | 300-800 PLN/month | 1-2 days |
| MES with OPC-UA protocol | Custom microservice (Python) | High | One-off 15-40k PLN | 4-8 weeks |
| Enterprise integration (SAP + MES + Jira) | MuleSoft Anypoint | Very high | 30-120k PLN/year | 3-6 months |
For most SME manufacturing companies, n8n self-hosted offers the best flexibility/cost ratio. It supports REST, MQTT (via a custom node), webhooks, queueing, retry logic and has a built-in flow monitoring panel. A VPS deployment from 200 PLN/month will cover 90% of integration scenarios.
What happens when the ERP is in a maintenance window? A synchronous integration will hang or return an error, which often means lost events. Solution: always design with a buffer queue (Redis, RabbitMQ). When the ERP is unavailable, events land in the queue and are processed after the system returns. The middleware must implement exponential backoff on retries. Do not bombard the restored ERP with 1,000 requests at once.
A Jira webhook can be sent twice (retry after timeout). If the middleware does not check whether a given event has already been processed, the ERP or MES will receive two identical records. Solution: store the ID of processed events (issueKey + timestamp + eventType) for at least 24h in cache. Check every event before processing.
Custom field IDs in Jira (e.g. customfield_10201) change between environments (dev/staging/prod) and after migrations. If the ID is hardcoded in middleware, the integration breaks after every migration and nobody knows why. Solution: store all field IDs in a configuration file or environment variables. In the CI/CD pipeline add a step that verifies that the configured fields exist in the target Jira.
Jira uses UTC in the API. Comarch ERP can return dates in the server's local time zone. The MES often adds a timestamp without time zone information. Once all the data lands in a single analytics database, SLA reports will be off by n hours and for weeks nobody will notice. Solution: standardize all timestamps to ISO 8601 with UTC (Z) at the middleware input. Never store dates without time zone information.
The most common deployment mistake: the integration is configured on the ERP administrator account "to get it working fast". After admin password rotation or the account being disabled, the integration fails without warning. Solution: create a dedicated service account with the minimum required permissions (read + specific write resources). Store credentials in a vault (HashiCorp Vault, AWS Secrets Manager), never in configuration files in the repository.
An integration deployed without monitoring is an integration that will break silently. You will find out about it from the production manager, not from a dashboard. Three monitoring layers I consider mandatory:
Periodic ping (HEAD or GET /health) to each system every 60 seconds. If any one does not respond within 5 seconds for 3 consecutive attempts, send an alert to Teams/Jira/email. Implementation cost: 30 minutes in n8n or a simple Lambda function.
Monitor how many messages pass through each flow per hour. A sudden drop to zero usually means something has broken. Configure an alert when throughput falls below 20% of the average from the last 7 days for more than 30 minutes.
Every message that could not be processed after N attempts goes to the DLQ. The alert should fire immediately once the DLQ is not empty and require manual analysis, not automatic retry. The DLQ is your "canary in the coal mine" for data transformation errors.
We assess the architecture, choose the middleware and run the implementation from design to production monitoring. Free consultation, no commitments.
Book a free consultation →Planning IT system integrations? See what an implementation with Rotech Group looks like