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

# Realtime browser events

> Route incoming XMPP messages to a live browser tab through Neuron's event channel

The Agent API does not expose a generic server-to-server webhook registration endpoint. It can route matching incoming XMPP messages to a live browser tab through Neuron's client-event system. Use this for interactive applications; use [message polling](/neuron-api/api-reference/messaging/pop-messages) or your own durable queue consumer for background processing.

<Warning>
  Browser events are interactive, not a durable server-to-server webhook. Test delivery, cookies, allowed origins, disconnects, and reconnection on the target Neuron.
</Warning>

## 1. Load the event client

Include `/Events.js` from the Neuron so the page receives a tab ID and maintains its event channel. When the page and API use different hosts, declare the event server in the page metadata as required by that deployment and configure the Agent client host with `AgentAPI.IO.SetHost(host, secure)`.

Cross-origin deployments also need correct CORS, cookie, and TLS configuration. Do not relax origins globally to make the event channel work.

## 2. Register a handler

After the event client has assigned a tab ID, register the most specific match you need:

```http theme={null}
POST /Agent/Xmpp/RegisterEventHandler HTTP/1.1
Authorization: Bearer <jwt>
Content-Type: application/json

{
  "localName": "alert",
  "namespace": "urn:example:alerts:1",
  "type": "normal",
  "function": "onAlert",
  "tabId": "<current-tab-id>"
}
```

All match fields are optional. A specific local name and namespace wins over a broader fallback. `function` names the browser callback. Leaving it empty unregisters that match.

```js theme={null}
window.onAlert = event => {
  // Validate the event shape and escape any rendered message content.
  console.log("Alert received", event);
};
```

When a message matches a live registration, Neuron pushes it to the tab instead of storing it as an offline message. Therefore, browser delivery is not durable.

## 3. Design for disconnects

* register again when a page reloads or receives a new tab ID;
* make handlers idempotent because reconnect races can cause repeat work;
* poll [Pop messages](/neuron-api/api-reference/messaging/pop-messages) after reconnect when missing a message is unacceptable;
* use the narrowest local-name, namespace, and stanza-type match;
* unregister handlers no longer needed by sending the same selector with an empty `function`.

<Info>The older documentation called this a webhook. It is a browser event bridge tied to a Neuron session and tab, not a public callback URL.</Info>
