# Live events

The same events as the [webhooks](https://developers.dzbot.de/sdk/webhooks), straight into a browser or a running process — for a live kill feed on your website or a toast when a player's order was delivered. No URL of your own needed.

## Subscribe

```
const subscription = dzbot.events.subscribe(['log.player_kill', 'order.delivered'], (event) => {
  if (isEvent(event, 'order.delivered')) toast(`Order ${event.payload.order.code} is on its way`)
}, { onError: console.warn })

// later
subscription.close()
```

It reconnects by itself and renews its access before it runs out. In Node it needs Node 22+ (or pass `{ eventSource: (url) => new EventSource(url) }` from the `eventsource` package).

## What you receive

Exactly what the key or the signed-in user may read on the server. A player without admin rights still receives the events about themselves — their own orders, tickets and wallet transactions. Names you may not read are left out; `onOpen(topics)` tells you what the connection covers.

## Without the SDK

```
POST https://api.dzbot.de/api/developer/live   { "events": ["log.player_kill"] }
→ { "hubUrl": "https://api.dzbot.de/.well-known/mercure", "token": "…", "topics": ["urn:dzbot:events:server:12:log.player_kill"], "expiresAt": "…" }

new EventSource(hubUrl + '?topic=' + encodeURIComponent(topics[0]) + '&authorization=' + token)
```

The stream is [Mercure](https://mercure.rocks) (server-sent events). Every message's `data` is the event as JSON, its `id` the event id. A token lives five minutes and the hub ends the connection when it runs out: ask for a new one before `expiresAt`, open the new connection, then close the old one and skip event ids you already saw. A revoked sign-in or key gets no new token, so it stops receiving within minutes. The SDK does all of this for you. Events sent while no connection is open are not replayed; use webhooks where every event must arrive.

---

Web page: https://developers.dzbot.de/sdk/live · All pages: https://developers.dzbot.de/llms.txt
