Skip to main content
The ERP Sync agent runs a small HTTP API on the computer where it is installed. You can use it to check the agent’s status, read its recent log entries, and pause, resume or trigger syncing from a script or a monitoring tool. This is the agent’s local API. It is not Omnilinker’s cloud API and it is not reachable from the internet. For calling Omnilinker itself, see the Developers section.

Base URL

The port comes from the LocalApiPort setting in the agent’s appsettings.json (default 5555). Leave it at the default: the tray app’s fallback connection and the web app’s Local Service tab always use port 5555. See the configuration reference. The API uses plain HTTP. It is served by the Windows service, so it is available only while the service is running.

Access and security

  • Localhost only. The agent listens on the loopback addresses only (127.0.0.1 and ::1). Other computers on your network cannot connect to it, and it needs no firewall rule. A request that names any host other than localhost or a loopback address is refused with 403 Forbidden.
  • One required header. Every request to a route under /api must carry the header X-Omnilinker-Local: 1. Without it, the agent answers 403 Forbidden with an empty body. /health does not check the header; sending it there does no harm.
  • Browsers: Omnilinker only. A web page cannot add that header without asking the agent first (a CORS preflight). The agent agrees only for Omnilinker’s own address, https://omnilinker.pl, and its subdomains, over HTTPS. That is how the web app’s Local Service tab, open in a browser on the agent computer, reads the API. Requests from any other website are refused with 403.
  • No authentication. Programs on the computer, such as the tray app, PowerShell or curl, send the header and need no API key, password or token.
Anyone who can run a program on the agent computer can call the API. They can read the agent’s status and log entries, and pause, resume or trigger syncing. The API does not check the Omnilinker ERP Sync Operators group that the tray app uses. It never returns the API key, the ERP password or the connection string, and it cannot change the agent’s settings. Still, treat access to the agent computer as access to the agent: limit who can sign in to it.

Conventions

  • Request and response bodies are JSON. Property names are camelCase.
  • Times are in UTC, in ISO 8601 format, for example 2026-09-27T08:15:02.1234567Z.
  • Enumerations are returned as numbers, not names. The tables on this page list the values.
  • Control routes return 400 Bad Request with a command response when the agent refuses the command.
  • 403 Forbidden with an empty body means the request was refused before it reached the agent: the X-Omnilinker-Local header is missing, the host is not localhost, or a browser sent it from another website.
  • The examples use PowerShell. In Windows PowerShell 5.1, curl is an alias for Invoke-WebRequest. Type curl.exe to use curl.

Routes

No other routes exist.

Health

GET /health

Runs the agent’s health checks and returns the overall result as plain text: Healthy, Degraded or Unhealthy. The HTTP status is 200 OK for Healthy and Degraded, and 503 Service Unavailable for Unhealthy. /health returns Unhealthy until the agent has connected to the ERP database, for example right after the service starts or before the setup wizard has run. Use /api/sync/health to check only that the service is running.

GET /api/sync/health

Returns 200 OK whenever the API is answering. It does not check the ERP or Omnilinker.
string
Always healthy.
string
The agent’s current time, UTC.

Status

GET /api/sync/status

Returns the agent’s full status. The tray app’s status window and the web app’s Local Service tab show the same data.
integer
The agent’s state.
boolean
Whether the agent’s last request to Omnilinker succeeded.
boolean
Whether the agent is connected to the ERP database.
string | null
When the last sync cycle finished successfully.
string | null
When the next cycle is expected, if known.
integer
Errors since the last successful cycle.
string | null
The last error message, for example Waiting for cloud configuration.
string | null
Why a cycle is delayed, for example Product polling delayed (HashCheck in progress).
integer[]
Fixes the tray app offers for the last error. 1 test ERP connection, 2 test cloud connection, 3 check settings, 4 retry now, 5 view logs, 6 check network, 7 contact support, 8 view details, 9 skip item.
object
Events in the agent’s outbox, with pending, sent, failed and retrying. The same numbers as /api/sync/outbox/stats.
object
Outbox counts per entity type, keyed by type name (for example Product, Brand, PriceLevel, Price, Warehouse, Stock). Each value has total, synced, pending and failed. Only events still in the local outbox are counted: sent events are removed after 24 hours (1 hour during the initial sync).
string
The agent’s version.
boolean
Not used: always false. The agent updates itself, but does not report a waiting update here.
string | null
Not used: always null.
object | null
The same object as /api/sync/hash/status.
object | null
While a hash check runs: productsChecked, totalProducts, brandsChecked, totalBrands, elapsed, estimatedTimeRemaining and itemsPerSecond.
object | null
currentPending, healthLevel (0 normal, fewer than 50 pending; 1 elevated, 50 to 199; 2 backlogged, 200 or more), trend (0 steady, 1 growing, 2 draining), trendItemsPerMinute and trendDescription.
object[]
Operations running now, such as polling or publishing, with their item counts and progress.
object[]
The most recently completed operations, with completedAt, itemCount, duration, success and errorMessage.
object
Health of four components: erpConnection, cloudApi, database and credentials. Each has a level (0 healthy, 1 warning, 2 critical), a message and the time of the last check. overallHealth is the worst of the four, and issueCount counts those that are not healthy.
The objects under currentOperations, recentActivity and systemHealth also carry display fields used by the tray app. Do not rely on their exact shape; it can change between agent versions.
A shortened response:

GET /api/sync/config

Returns a few facts about the agent. It does not return its settings or credentials.
string
The agent’s version.
boolean
Whether syncing is paused.
string
The agent’s state as a name, for example Idle (unlike /api/sync/status, which returns a number).

Control

These routes take no parameters and no request body.

Command response

Every control route, and POST /api/sync/hash/trigger, returns this object:
boolean
Whether the agent accepted the command.
string
What happened, or why the command was refused.

POST /api/sync/now

Asks the agent to look for changes now. POST /api/sync/trigger does exactly the same. The request is picked up at the agent’s next polling cycle, within PollingIntervalSeconds (60 seconds by default). With hash scan change detection it starts a hash check.

POST /api/sync/pause

Pauses syncing. The agent stops detecting new changes until you resume. Always returns 200 with Sync paused.
  • Events already in the outbox are still sent to Omnilinker while the agent is paused.
  • A pause is not kept when the service restarts.

POST /api/sync/resume

Resumes syncing. Always returns 200 with Sync resumed.

Logs

GET /api/sync/logs

Returns the newest entries of the agent’s own sync log, newest first. These are the entries the tray app’s log viewer shows. They are not the Omnilinker sync log entries described in Monitoring, and not the service’s log files.
integer
default:"50"
How many entries to return. At most 500; larger values return 500.
string
Minimum level: Debug, Info, Warning, Error or Critical (or 0 to 4). Returns entries at this level and above.
string
Only entries of this category, for example ErpPolling, HashCheck or ChangeConsumption. Exact match.
string
Only entries for this entity type. Exact match.
The response is an array of log entries:
integer
The entry’s ID.
string
When the entry was written.
integer
0 Debug, 1 Info, 2 Warning, 3 Error, 4 Critical.
string
The message.
string | null
Extra details, if any.
string | null
The component that wrote the entry.
string | null
The entity type concerned, if any.
string | null
The entity concerned, if any.
string | null
The exception, for errors.

Outbox

GET /api/sync/outbox/stats

The agent queues every change in a local outbox and sends it to Omnilinker in batches. This route counts the events in the outbox by state.
integer
Waiting to be sent, including events that failed an attempt and will be tried again.
integer
Sent successfully and not yet cleaned up. Sent events are removed after 24 hours (1 hour during the initial sync).
integer
Failed on every attempt (MaxRetryAttempts, 5 by default). The agent does not send these again.
integer
Being sent right now. Despite the name, this is not a count of events waiting for a retry: those are in pending.
A pending count that keeps growing means the agent cannot send to Omnilinker. See Troubleshooting.

Hash check

A hash check compares the ERP data with what the agent last sent, to find changes. It is how the agent detects changes with hash scan change detection. See Wapro.

GET /api/sync/hash/status

boolean
Whether hash checks are enabled in the connection’s sync configuration. With WFM_INT change tracking, a weekly reconciliation check always runs and this is true.
boolean
Whether a hash check is running now.
boolean
Whether hash checks are paused on their own (from the tray app).
string | null
When the last hash check finished.
string | null
When the next one is due.
integer
Products compared in the last check. lastProductsChanged, lastBrandsChecked and lastBrandsChanged work the same way.
integer
Products in the hash store. totalStoredBrandHashes is the same for brands.
string | null
The last hash check error.

GET /api/sync/hash/stats

integer
Products in the hash store.
integer
Brands in the hash store.
string | null
When the store was last updated by a hash check.

POST /api/sync/hash/trigger

Starts a hash check now, without waiting for its interval.

Named pipe

The tray app talks to the service mainly over a Windows named pipe, OmnilinkerErpSync, and falls back to this HTTP API when the service does not answer on the pipe. The pipe is an internal interface between the two parts of the agent, not a public API: its commands can change between agent versions. Use the HTTP routes on this page for scripts and monitoring.
  • Who can connect: SYSTEM, administrators, and people signed in to the computer, at the console or over Remote Desktop.
  • What they can do: anyone connected can read the status, logs and settings. Commands that change the agent, its ERP database or its credentials, or that pause it, need a member of Omnilinker ERP Sync Operators or an administrator whose tray app runs elevated. Others get the error “Only an administrator of this PC can do that.” (code Pipe:NotAllowed). See Who can change the agent.
  • Which service: the tray app talks only to the Windows service. It does not trust another program that opens a pipe with the same name.