A webhook that "does not work" in Bitrix24 (Alaio) is two very different failures wearing the same word, and neither fix helps the other: an outbound event never arrives at your handler, or an inbound call comes back with an error instead of data. A dead sync, a bot that stopped posting, an accounting system that missed yesterday's deals — each is one of those two in costume. Name which one you have, then walk the checks below in order.

Outbound or inbound: which half is broken?

An inbound webhook is a URL with a key that your service calls to reach the portal; an outbound one is the reverse, the portal calling you when an event fires. If your logs show a request going out and an error string coming back, the problem is inbound and the error names it. If they show nothing at all, the problem is outbound — and there is no error anywhere, which is what makes it slow to diagnose. How both are created is covered in the webhooks guide; this page is about what to do when they go quiet.

Why does an outbound webhook never reach my handler?

Events do not travel from the portal straight to your URL. They are queued on a separate delivery server, which then sends the POST, and three properties of that server explain most of the silence. The handler has to be reachable from the public internet: an address on localhost or inside a private network receives nothing, and a firewall that only admits known partners has the same effect. It has to answer fast: the queue watches response time and calls slow handlers less often, stretching the interval between attempts, so a heavy handler degrades into an unreliable one without ever failing outright. And the payload is deliberately thin — mostly the entity id and the event name — so a handler written to expect full field values reads an empty structure. Fetch the fields with a separate REST call.

Did the event I subscribed to actually fire?

The next most common cause is a healthy subscription to the wrong event. Update events fire on every change to the entity, including the changes your own automation makes, which shows up as duplicate deliveries and occasionally as a loop. Handlers registered in the portal's developer resources section and handlers registered by an application through event.bind live in different lists, so the subscription you are staring at may not be the one that runs — and an application's bindings disappear when it is removed or updated. The check costs a minute: trigger the action by hand and watch your access log for an incoming POST.

My handler was down — can I get the event back?

No, and this is the property most integration designs get wrong. If your server does not respond or returns an error, the queue server records the failure and does not resend the event. There are no retries and no dead letter queue: a ten-second redeploy silently costs every event in that window.

Two answers exist. For the inbound direction, bind the subscription as an offline event — the portal holds events in a queue that your service pulls at its own pace with event.offline.get, so downtime delays delivery instead of destroying it. For calls that start inside the portal, send them from a workflow: Reliable webhook retries failed attempts on an interval you set, lets you declare which status codes count as success, reports how many attempts it took, and notifies chosen users if delivery ultimately fails.

Why does an inbound webhook return an error?

Here you get a code, so read it rather than the sentence next to it. A scope error means the key was created without the permission the method needs, and scopes are fixed at creation — reissue the key. An access error usually means the key is fine but its owner is not: a webhook acts with the rights of the employee who created it, so a deactivated owner, or one who cannot see the pipeline, fails with a perfectly valid token. QUERY_LIMIT_EXCEEDED is the rate limiter, not a broken key (query limit exceeded). The full map: REST API error codes.

How do I test a webhook without guessing?

Log the raw request body before parsing it: half of "the webhook is broken" turns out to be a handler that received the POST and crashed on its own parsing. Verify the caller too — an application token arrives with event calls, and comparing it against the stored value is both the security check and a quick way to tell whether the POST came from the portal at all.

To test the other direction from inside the portal, put HTTP request GET/POST in a workflow: it sends a request to your endpoint and returns the response body, the status code and a Y/N flag, so you learn whether the endpoint answers the portal's network at all, and Extract value from JSON by path pulls one field out of the answer for a readable log line. If the workflow that should have sent the request never started, the trail moves to automation rules not running.

What next

Silence means outbound, an error string means inbound: that one split saves most of the time. After that, design for the constraint rather than around it — events are never resent, so anything that must not be lost goes through an offline subscription inbound and Reliable webhook outbound, both ordinary blocks in workflow automation in Bitrix24. The rest of them live in the robot catalog; if the one you need is missing, describe the task and we build it free for the shared library.