Wialon Has No Webhooks — Poll This Way

Siarhei Havarunou – CEO

Wialon cannot push events to your URL. Three replacements that work: avl_evts polling, notification actions, and a flespi bridge for real push.

Wialon has no webhooks — polling avl_evts, notification requests and a flespi bridge

Every integration architect asks it in the first week: “what is the Wialon webhook URL for trip events?” There is no such URL. Wialon has no general-purpose event webhook: nothing registers a callback and receives the stream, and no API call subscribes your endpoint to an item or a type. What does exist is narrower and per-rule — one notification, one condition, one HTTP request — and it is Option B below rather than a substitute for a stream. Everything here is a replacement for the webhook you wanted, ordered from simplest to most capable. Pick by latency need, not by fashion.

Why the absence is structural, not an oversight

Wialon’s event model is scoped to a session, not to an endpoint. You log in, tell the session which items you care about, and the server accumulates changes for that session until you come and collect them. Nothing in that design has a place to put your URL: there is no durable subscription object to attach it to, no delivery queue behind it, and no retry machinery to drive it. A webhook is a promise to deliver later; a session is a promise to remember until you ask.

That is worth understanding before you architect around it, because it tells you exactly what the replacements can and cannot do. Anything built on the session inherits the session’s lifetime — five idle minutes and it is gone. Anything built on notifications inherits the notification’s shape — one rule, one condition, fire and forget. Real durable push has to come from a platform that was built with a delivery queue, which is the third option and the only one that costs a second system.

Option A: poll avl_evts (seconds of latency, zero setup)

The session you already hold can report its own changes. Subscribe with core/update_data_flags, then poll the avl_evts channel — at most 10 requests per 10 seconds per session, on a session that does nothing else. avl_evts is a path of its own, {host}/avl_evts?sid=<sid>, not an svc against ajax.html; w.events() below wraps it:

w.call("core/update_data_flags", {
    "spec": [{"type": "type", "data": "avl_unit", "flags": 1, "mode": 0}],
})
while True:
    for e in w.events().get("events", []):
        queue.put(e)  # queue, never process inline
    time.sleep(1)

What it sees. New messages from the hardware, property edits made in the UI or by another integration, and deletions. Each event names the item and the kind of change, and the response carries the server’s clock — use that rather than your own, so a drifting machine does not produce events that appear to arrive before they happened.

What it does not see. History. avl_evts starts from the moment you subscribed, so a restart is a gap unless something else fills it. That something else is a batch read of messages/load_interval for the interval your process was down, and the fact that you need it anyway is the strongest argument for building the batch path first and the event path second.

How it fails. Three ways, all worth writing code against before the first deployment. The session dies after five idle minutes, so a loop that pauses — a long GC, a blocked queue, a deploy — comes back to error 1, and the answer is one re-login and one resubscribe, not a retry loop. The subscription is replaced rather than merged when mode is 0, which is a feature: resubscribing after a reconnect is a single idempotent call instead of a diff. And the ten-per-ten-seconds ceiling is a whole budget, so this session must do nothing else — an extraction sharing it will start collecting error 10 at the worst possible time.

When it is right. One account, one process, latency measured in seconds, and an operator who can tolerate a gap after a restart. That covers most dashboards and most alerting.

Option B: notification actions (minutes of latency, server-side)

Wialon notifications can do more than email a dispatcher. A notification action can fire an HTTP request at a URL you control when its trigger condition meets — geofence entry, speeding, sensor value, driver message. It is the closest thing to a webhook Wialon has, and treating it as one causes four specific problems.

  1. It is per-rule, not per-event-stream. You configure one notification per condition per resource. Ten conditions means ten notifications, each maintained in the UI or via resource/update_notification (see the notifications reference). There is no “send me everything” rule, and building one out of forty narrow rules produces a configuration surface nobody will maintain a year from now.
  2. Delivery carries no documented guarantee. Wialon does not publish a retry policy for a request your endpoint refuses, so design for at-most-once: make the endpoint idempotent, and reconcile anything you cannot afford to lose against the API on a schedule.
  3. Payloads are templates, not schemas. You format the request from macros rather than receiving a typed object. Version it yourself — put a version marker in the URL path so that the day a macro’s meaning shifts, you can tell old traffic from new without guessing.
  4. Nothing signs the request. There is no shared-secret header and no signature to verify, so your endpoint must authenticate the caller some other way: a long random component in the path, an allowlist of source addresses, or both. An unauthenticated endpoint that accepts “vehicle 14 entered the depot” is an endpoint that anyone who learns the URL can lie to.

There is also a timing subtlety that catches people: a notification has two independent timing layers — the trigger’s own condition and the schedule that says when the rule is active at all — and both must be satisfied before anything fires. A rule that looks correct and never fires is usually a rule whose schedule excludes the hours the fleet actually drives.

Use this when the event volume is low and each event matters individually: alarm button pressed, geofence violated, temperature out of range. Do not use it as a firehose — hundreds of speeding events an hour through per-rule HTTP calls is how you build a distributed system out of a notification panel.

Option C: flespi bridge (real push, second platform)

When you need genuine server-to-server push — persistent streams, channel-based routing, protocol translation — the answer is not in Wialon at all. flespi accepts the same trackers, exposes real streaming subscriptions with a delivery queue behind them, and coexists with Wialon on the same hardware: the device sends to a flespi channel, and flespi retransmits to Wialon in Wialon’s own protocol, so the fleet manager’s screens keep working while your platform gets a stream.

That is the architecture, and the cost of it is a boundary decision. Two platforms holding the same telemetry will disagree the first time one of them is unreachable, so each data class needs exactly one owner: raw messages from the device belong to the streaming side, while units, geofences, drivers and everything an operator edits belong to Wialon. Write that table down before the first device is repointed — the dual-stack guide is the full treatment.

This is the enterprise answer and it costs a second platform: a subscription, a channel topology, and someone who understands both sides. Do not reach for it when Option A would do.

Which one, in one table

NeedPickLatency
”Tell me within seconds, one account”A: avl_evts pollseconds
”Tell my URL about specific alarms”B: notification request~minutes
”Stream everything to my platform”C: flespi bridgereal-time
”Give me last month, completely”None of the above — batch syncscheduled

The most common failure is picking B for the fourth row: notifications are not a sync mechanism. History moves in batches, on a schedule, with rate-limit-safe extraction into your own database. Events tell you something happened; the database tells you everything that happened. Build both, confuse neither.

The latency you can actually promise

Before you choose, price the whole path rather than the transport. A tracker reports on its own interval — commonly tens of seconds when moving and minutes when parked, and configurable per device. Whatever you build on top inherits that floor. A one-second avl_evts loop over hardware reporting every sixty seconds is a one-second loop delivering sixty-second-old truth, and no amount of platform engineering changes that.

This matters commercially as well as technically. “Real-time tracking” sold against a customer’s expectation of GPS-navigation latency will fail acceptance testing no matter which option you picked. Write the device reporting interval into the specification next to the delivery latency, and the conversation becomes arithmetic instead of disappointment.

Three failures to design against, whichever you pick

Duplicates. Every option can deliver the same logical event twice — a retried batch, a resubscription that replays, a notification fired by two overlapping rules. Give each event a natural key (item id plus server timestamp plus event kind) and make the consumer idempotent. This is five lines of code at the start and a data-cleaning project later.

Gaps. Every option can miss events: the session died, the endpoint was down, the channel was reconfigured. The only real defence is a scheduled batch read that overlaps the live path — run it over a window wider than your worst outage and let idempotency absorb the overlap.

Order. Nothing here promises ordering across items, and an event-driven state machine that assumes “departure before arrival” will eventually see them reversed. Sort by the server’s timestamp inside a unit, and never assume anything about the relationship between two units.

What to build regardless of the option

A reconciliation job. Once a night, compare counts and key aggregates between Wialon and whatever you fed — messages per unit, trips per unit, events per rule — and alert when the difference passes a threshold you chose deliberately. Without it, a stopped integration is indistinguishable from a quiet week, and you find out at month-end close rather than on the morning it broke.

If the choice above is turning into architecture rather than a script, that is what the integration practice does: event design, delivery guarantees and reconciliation, quoted before anything is built.

More from Asset Track

Let's connect

  • “Our client needed a data pipeline. It came back working, plus a few Wialon fixes we had not asked for. That client trusts us more now.”
    Faiz K. Customer Manager · Trakpro Limited