> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnilinker.pl/llms.txt
> Use this file to discover all available pages before exploring further.

# Monitor ERP sync in Omnilinker

> Check from the Omnilinker web app whether the ERP Sync agent is online and whether changes from your ERP are arriving.

Omnilinker shows two kinds of information about an ERP connection:

* **Whether the agent is alive.** The ERP Sync agent sends Omnilinker a heartbeat every 60 seconds. The
  connection's **Agent** tab shows when the last one arrived.
* **What happened to each change.** Every change the agent sends is recorded as a sync log entry. The
  **Sync Logs** pages and the dashboard summarize these entries.

To see what the agent itself is doing on the machine it runs on, use the [tray app](/erp/tray-app).

## Where to look

Everything is under **ERP Integration** in the main menu:

| Menu item       | Route                          | What it shows                                                  | Permission      |
| --------------- | ------------------------------ | -------------------------------------------------------------- | --------------- |
| **Dashboard**   | `/erp-integration/dashboard`   | Totals across all connections and the latest sync log entries. | ERP Connections |
| **Connections** | `/erp-integration/connections` | Your connections. Open one to see its details and tabs.        | ERP Connections |
| **Sync Logs**   | `/erp-integration/sync-logs`   | Sync log entries of all connections.                           | Sync Logs       |

The **ERP Integration** menu appears only when the ERP Integration feature is enabled for your organization. See
[Modules and feature availability](/administration/features).

## Dashboard

**ERP Integration** > **Dashboard** opens the **ERP Integration Dashboard**. It loads once when you open it. Click
**Refresh** in the **Connections Overview** card to load it again.

The four cards at the top count sync log entries of your **active** connections, over all time:

| Card                   | Shows                                                                                                                                                                                   |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Active Connections** | How many connections are active, with **of `<n>` total** below. Click it to open **Connections**.                                                                                       |
| **Products Synced**    | The number of sync log entries with status **Completed**. Despite the name, it counts every entity type (products, brands, price levels, prices, warehouses, stock), not only products. |
| **Success Rate**       | **Completed** entries as a percentage of all entries. Green from 90%, amber from 70%, red below 70%. With no entries it shows 100%.                                                     |
| **Failed Operations**  | The number of entries with status **Failed**. When it is above zero, click it to open **Sync Logs**.                                                                                    |

<Note>
  The Failed Operations card opens **Sync Logs** without a filter. Set **Status** to **Failed** there to see only the
  failed entries.
</Note>

**Connections Overview** shows up to six connections as cards. Each card shows the connection name, its provider,
an **Active** or **Inactive** badge and the time of the last successful sync. The dot before the name is gray for an
inactive connection, amber when the connection has never synced or last synced more than 24 hours ago, and green
otherwise. Click a card to open the connection. **View All** opens **Connections**.

<Warning>
  The last successful sync time is not updated by the agent at present. It shows **Never** even while changes arrive
  normally, and the dot stays amber. Use the connection's [Agent tab](#agent-tab) and [sync logs](#sync-logs) to
  judge whether sync is working.
</Warning>

The sync button on an active connection's card does the same as **Trigger Sync** on the connection page. See
[the warning below](#connection-details).

**Recent Activity** lists the 10 newest sync log entries across all connections, with **Timestamp**,
**Connection**, **Entity Type**, **Direction** (**From ERP** or **To ERP**) and **Status**. It is hidden when there
are no entries. **View All** opens **Sync Logs**.

## Connections

**ERP Integration** > **Connections** lists your connections with these columns:

| Column        | Shows                                                                                                |
| ------------- | ---------------------------------------------------------------------------------------------------- |
| **Name**      | The connection name.                                                                                 |
| **Provider**  | The ERP system, for example **Wapro**.                                                               |
| **Status**    | **Active** or **Inactive**.                                                                          |
| **Last Sync** | The time of the last successful sync, or **Never**. Not updated by the agent at present (see above). |

**Status** only tells you whether the connection is switched on. An **Active** connection whose agent is offline is
still **Active**. To see whether the agent is running, open the connection and check its **Agent** tab.

An **Inactive** connection does not accept anything from the agent: its heartbeats and changes are rejected until you
activate it again. To switch a connection on or off, open the row's **Actions** menu and click **Activate** or
**Deactivate** (requires the Edit ERP Connection permission).

## Connection details

Click **Details** in a connection's **Actions** menu, or a connection card on the dashboard, to open the connection
page. The header card shows the **Provider**, the **Status** (**Active** or **Inactive**), **Last Sync** and the
description. Below it are the tabs.

<Warning>
  **Trigger Sync** at the top of the page (and the sync button on dashboard cards) shows "Synchronization has been
  triggered", but it does not make the agent do anything. To make the agent look for changes now, use **Sync Now** in
  the [tray app](/erp/tray-app#sync-now-pause-and-resume), or `POST /api/sync/now` on the agent's
  [local API](/erp/local-api).
</Warning>

| Tab                    | What it is for                                                                                       | Shown when                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| **Sync Configuration** | Which entity types sync, and how. See [Sync configuration](/erp/sync-configuration).                 | Always                                                      |
| **Field Mappings**     | How ERP fields map to catalog fields. See [Field mappings](/erp/field-mappings).                     | Always                                                      |
| **Mappings**           | Map ERP price levels and warehouses to Omnilinker ones. See [Reference items](/erp/reference-items). | You have the Reference Data and Entity Mappings permissions |
| **Sync Logs**          | This connection's sync log entries. See [Sync logs](#sync-logs).                                     | Always                                                      |
| **Agent**              | The agent's heartbeat, versions and capabilities, as last reported to Omnilinker.                    | You have the Agent Status permission                        |
| **Local Service**      | The agent's live status read from your own computer.                                                 | Always                                                      |

### Agent tab

The **Agent** tab (**On-premise Agent**) shows what the agent last reported in its heartbeat. It is Omnilinker's
view of the agent, so it works from any computer. It loads when you open the tab; click **Refresh** to load it again.

Until the agent has connected for the first time, the tab says **No agent has connected yet**.

| Field                      | Shows                                                                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Health**                 | **Online** if the last heartbeat is at most 3 minutes old, otherwise **Offline**.                                                          |
| **Last heartbeat**         | How long ago the last heartbeat arrived, for example **2 min ago**. Hover to see the exact time.                                           |
| **Change tracking**        | The change-detection mode the agent is actually running: **Hash scan** or **WFM\_INT change tracking**. See [Wapro](/erp/providers/wapro). |
| **Provider**               | The ERP provider key, for example `Wapro`.                                                                                                 |
| **Agent version**          | The agent's version number.                                                                                                                |
| **Applied config version** | The version of the connection's configuration the agent is using.                                                                          |
| **Plugins**                | The provider plugins in the agent and their versions.                                                                                      |
| **ERP version**            | Version details the agent read from the ERP database. Shown only when reported.                                                            |
| **Capabilities**           | What the ERP supports, as chips: a check mark for supported, a cross for not supported. Shown only when reported.                          |

The agent sends a heartbeat every 60 seconds, so a healthy agent never shows more than about a minute here.

**When the agent is offline.** **Offline** means Omnilinker has had no heartbeat for more than 3 minutes. The
agent may be stopped, unable to reach `omnilinker.pl`, or rejected by Omnilinker (revoked API key, inactive
connection, or an agent version that is too old). **Last heartbeat** tells you when it stopped. See
[Troubleshooting](/erp/troubleshooting).

**Configuration drift.** When you change the connection's settings, its configuration version goes up. If the agent
is still on an older version, the tab shows **Configuration drift detected**: "The agent is running configuration
version `<n>`, but the current version is `<m>`." The agent notices the change at its next heartbeat and downloads the
new configuration. If the banner stays for more than a few minutes, the agent is probably offline.

**When the agent version is too old.** Omnilinker can set a minimum supported agent version. An agent older than
that is rejected on every request with the error "Agent version `<version>` is no longer supported (minimum
supported version: `<minimum>`). Please update the ERP Sync agent." You do not see this message in the web app. What
you see is:

* **Health** turns **Offline** and **Last heartbeat** stops moving, because heartbeats are rejected too.
* **Agent version** still shows the old version, from the last heartbeat that was accepted.

The error message itself is in the agent's log file. The agent [updates itself](/erp/install-agent#update-the-agent)
at night when a newer version is published. If the tab stays **Offline**, update it by hand. See also
[Troubleshooting](/erp/troubleshooting).

### Local Service tab

The **Local Service** tab reads the agent's status directly from the agent's [local API](/erp/local-api) at
`http://localhost:5555`, from the browser you are using. It refreshes every 5 seconds.

Because it uses `localhost`, it shows the agent only when you open Omnilinker in a browser **on the computer where
the agent is installed**. On any other computer it shows **Local Sync Service Not Available**. That is expected and
does not mean the agent is down; use the [Agent tab](#agent-tab) instead. The install steps shown under that message
are generic. To install the agent, follow [Install the agent](/erp/install-agent).

When the agent is reachable, the tab shows:

* **Service Status**: the agent's state (**Idle**, **Syncing**, **Paused**, **Error**, **Starting** or
  **Stopping**), **Cloud Connection** and **ERP Connection** (**Connected** or **Disconnected**), **Last Sync** and
  **Next Sync** (or **Not Scheduled**).
* **Last Error**, when there is one.
* **Sync Now**, **Pause** (while syncing), **Resume** (while paused) and **Refresh**. These act on the agent on this
  computer.
* **Outbox Statistics**: events **Pending**, **Sent**, **Failed** and **Retrying** in the agent's local queue.
* **Entity Statistics**: per entity type, **Total**, **Synced**, **Pending** and **Failed** events in the queue.
* **Recent Activity**: the agent's 10 latest log entries, with **Timestamp**, **Level** and **Message**.
* **Service Version**: the agent's version.

The tab expects the local API on port 5555. If `LocalApiPort` was changed, it cannot reach the agent. See the
[configuration reference](/erp/configuration-reference).

## Sync logs

A sync log entry is created in Omnilinker for each change it processes from the agent. Each entry has:

| Field                    | Meaning                                                                                                     |
| ------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Entity type              | **Product**, **Brand**, **Price Level**, **Product Price**, **Warehouse**, **Stock** or bundle composition. |
| Direction                | **From ERP** for changes coming from your ERP.                                                              |
| Operation                | **Create**, **Update** or **Delete**.                                                                       |
| Status                   | See the table below.                                                                                        |
| Entity identifier        | A readable identifier such as the SKU, when available.                                                      |
| ERP entity ID            | The record's ID in the ERP.                                                                                 |
| Error message            | Why the entry failed or was skipped.                                                                        |
| Retries                  | How many times **Retry** was used on the entry.                                                             |
| Change payload           | The data received from the agent.                                                                           |
| Started at, completed at | When Omnilinker started and finished processing the change.                                                 |

**Statuses**

| Status         | Meaning                                                       |
| -------------- | ------------------------------------------------------------- |
| **Pending**    | Waiting to be processed.                                      |
| **Processing** | Being processed (shown as **In Progress** in the tables).     |
| **Completed**  | Applied in Omnilinker.                                        |
| **Failed**     | Could not be applied. The error message says why.             |
| **Skipped**    | Deliberately not applied. The error message holds the reason. |

The tables show no status badge for **Skipped** entries. Look at the error message to tell them apart.

Common reasons for **Skipped**. The reason is stored as a code:

| Code                                                                                                                                  | Meaning                                                     | What to do                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `ErpIntegration:Skip:ProductNotMapped`                                                                                                | The product is not linked to a catalog product yet.         | Wait for the product itself to sync, or check [field mappings](/erp/field-mappings). |
| `ErpIntegration:Skip:PriceLevelNotMapped`                                                                                             | The ERP price level is not mapped to a catalog price level. | Map it on the **Mappings** tab. See [Reference items](/erp/reference-items).         |
| `ErpIntegration:Skip:WarehouseNotMapped`                                                                                              | The ERP warehouse is not mapped to an Omnilinker warehouse. | Map it on the **Mappings** tab.                                                      |
| `ErpIntegration:Skip:DerivedPriceLevel`                                                                                               | A derived price level. These are never mapped.              | Nothing.                                                                             |
| `ErpIntegration:Skip:BundleComponentsNotMapped`, `ErpIntegration:Skip:BundleNotABundle`, `ErpIntegration:Skip:BundleNestedNotAllowed` | A bundle composition could not be applied.                  | See [Wapro](/erp/providers/wapro).                                                   |
| "Conflict resolution: incoming data is not newer"                                                                                     | Omnilinker already has newer data for this record.          | Nothing.                                                                             |

When Omnilinker cannot process a change from the ERP because of an error, it does not record a **Failed** entry.
It rejects the change, and the agent sends it again later. Those errors appear in the agent's log, not here. See
[Troubleshooting](/erp/troubleshooting).

### Sync Logs page

**ERP Integration** > **Sync Logs** lists the entries of all your connections, newest first, 20 per page.

* **Connection**: **All Connections** or one connection.
* **Status**: **All Statuses** or one status.

The columns are **Timestamp**, **Connection**, **Entity Type**, **Operation**, **Status**, **Error** and
**Actions**. Hover over the **Error** badge to read the message.

### Sync Logs tab

A connection's **Sync Logs** tab shows only that connection's entries and has more tools.

The summary cards show **Total Operations** (all time), **Completed** with the **Success Rate**, **Failed**
(click it to show only failed entries) and **In Progress** (pending and processing).

Filters and tools:

* **STATUS**: **All**, **Completed**, **Failed**, **Pending** or **Processing**.
* A time range: **Last 24 hours**, **Last 7 days**, **Last 30 days**, **Last 90 days** or **All time** (the default).
* **Search Entity ID...**: finds entries by entity identifier or ERP entity ID.
* **Export CSV** (download icon): downloads the entries that match the filters as a CSV file.
* **Clean Up** (requires the Delete Sync Logs permission): deletes entries older than a number of days, 30 by
  default. Click **Preview** to see how many will be deleted, then **Delete Logs**. This cannot be undone.

The columns are **Type**, **Operation**, **Entity ID**, **Status**, **Retries**, **Time** and **Actions**. For an
entry with an error message, click the error icon to open **Sync Log Details**, with the full **Error Message**, the
**Change Payload** and buttons to copy them.

Select entries with the check boxes to use **Retry Selected** (for failed entries) or **Delete Selected** (requires
the Delete Sync Logs permission).

### Retry

**Retry** is available on **Failed** entries (requires the Trigger Manual Sync permission), at most 3 times per
entry. It sets the entry back to **Pending** and adds one to **Retries**.

<Warning>
  Retry does not reprocess the change at present. The entry stays **Pending**. To get a change applied again, change
  the record in the ERP so the agent sends it again.
</Warning>

## Related pages

<CardGroup cols={2}>
  <Card title="Tray app" icon="monitor" href="/erp/tray-app">
    Watch and control the agent on the machine it runs on.
  </Card>

  <Card title="Troubleshooting" icon="life-buoy" href="/erp/troubleshooting">
    Fix an offline agent, rejected keys and changes that do not arrive.
  </Card>
</CardGroup>
