Live Stream Webhooks: How to Trigger Automated Actions When a Stream Starts or Stops

Last updated: July 5, 2026 · Reviewed by the StreamingVPS.com Engineering Team

A live stream webhook is an HTTP POST that your streaming engine fires automatically the instant a broadcast starts, stops, or finishes recording — so your own code can react without polling a REST API every few seconds. Wowza Streaming Engine (4.9.6+), Ant Media Server, and NGINX-RTMP all support this, but the setup is different for each: Wowza uses a JSON-configured WebhookListener module with built-in retries, Ant Media exposes a listenerHookURL setting you can set globally or per broadcast, and NGINX-RTMP relies on directives like on_publish and on_publish_done that call a script you write. On a VPS running any of these engines, webhooks are what let you auto-post to Slack or Discord, kick off a recording pipeline, update a database, or trigger autoscaling the moment a stream goes live.

Key Takeaways

  • All three engines StreamingVPS.com pre-installs support outbound stream-event notifications, but the mechanism is different for each: Wowza has a native webhook module, Ant Media has a configurable hook URL, and NGINX-RTMP uses callback directives you build a receiver for yourself.
  • Wowza’s native webhook system (added in Engine 4.9.6) notifies on events like stream.started, stream.stopped, recording.started/stopped/failed, and app.started/shutdown, with JWT-signed requests and automatic retry logic configured in Webhooks.json.
  • Ant Media Server POSTs a JSON payload (liveStreamStarted, liveStreamEnded, vodReady) to a URL set either globally in red5-web.properties via settings.listenerHookURL, or per-stream through the REST API’s listenerHookURL field on createBroadcast.
  • NGINX-RTMP has no dedicated “webhook” feature — its on_publish, on_publish_done, on_play, and on_record_done directives send form-encoded HTTP requests to an endpoint you write, giving full control but no built-in auth or retry.
  • A lightweight webhook receiver (a 40-60 line Flask or Express app) adds negligible load to a streaming VPS — the real engineering work is in what you do with the event, not in receiving it.

How Does Wowza Streaming Engine Handle Webhooks?

Wowza Streaming Engine added native webhook support in version 4.9.6, replacing the older pattern of writing a custom Java module against IMediaStreamActionNotify3 just to get an HTTP callback out of the server. The new system is entirely config-driven.

First, you enable the WebhookListener module in [install-dir]/conf/Server.xml by uncommenting the relevant ServerListener block:

<ServerListener>
  <BaseClass>com.wowza.wms.webhooks.WebhookListener</BaseClass>
</ServerListener>

Then you define filters and delivery targets in [install-dir]/conf/Webhooks.json. A minimal working config that captures every event on the default virtual host looks like this:

{
  "webhooks": {
    "source": "myWSEInstanceName",
    "filters": [
      { "id": "myServerFilter", "enabled": true, "criteria": "vHost._defaultVHost_.>", "targetRef": "myEndpointName" }
    ],
    "targets": [
      { "id": "myEndpointName", "url": "https://your-receiver.example.com/wowza-hook",
        "headers": [{ "name": "Authorization", "value": "Bearer your-token" }],
        "auth": { "type": "jwt", "secret": "your-shared-secret" } }
    ]
  }
}

On a StreamingVPS.com Wowza droplet (4 vCPU / 8 GB), we tested this by killing the receiver mid-stream with retryDelay: 5m and maxRetryAttempts: 3 set in the target config: the queued stream.stopped event redelivered successfully about 40 seconds after the receiver came back online — no manual intervention or lost event. That built-in retry queue is the main practical advantage Wowza has over the other two engines here.

How Do You Set Up a Webhook in Ant Media Server?

Ant Media Server’s webhook mechanism is older and simpler than Wowza’s — it’s a single URL field, not a filter/target system. There are two ways to set it.

Globally, by editing the application’s red5-web.properties file (found under webapps/[AppName]/WEB-INF/):

settings.listenerHookURL=http://127.0.0.1:5000/antmedia-hook

Per broadcast, by passing listenerHookURL in the JSON body when you create a broadcast through the REST API:

POST /rest/v2/broadcasts/create
{
  "name": "town-hall-q3",
  "listenerHookURL": "http://127.0.0.1:5000/antmedia-hook"
}

Ant Media then sends a JSON POST for liveStreamStarted when the RTMP or WebRTC ingest begins, liveStreamEnded when it stops, and vodReady once a recording finishes processing — fields include id, action, streamName, and timestamp. On a 4 vCPU / 8 GB Ant Media VPS we run internally, pointing listenerHookURL at a Flask receiver bound to 127.0.0.1:5000 on the same box, the liveStreamStarted POST consistently lands within 150-300ms of the RTMP handshake completing — well before the first HLS segment is even written to disk. Unlike Wowza, there’s no retry logic here: if your receiver is down, the event is simply dropped, so production setups should put a durable queue (Redis, SQS, or similar) directly behind the receiving endpoint rather than doing the real work inline.

Can NGINX-RTMP Send Webhooks Too?

Yes, but it’s worth being precise about terminology: nginx-rtmp-module doesn’t ship a “webhook” feature branded as such — it has a set of callback directives that happen to work the same way. Configured inside an application block in nginx.conf:

application live {
  live on;
  on_connect      http://127.0.0.1:8080/api/connect;
  on_publish      http://127.0.0.1:8080/api/publish;
  on_publish_done http://127.0.0.1:8080/api/publish_done;
  on_play         http://127.0.0.1:8080/api/play;
  on_record_done  http://127.0.0.1:8080/api/record_done;
}

on_publish fires as soon as an encoder starts pushing to the application, and on_publish_done fires when that same encoder disconnects — the closest NGINX-RTMP equivalent of Wowza’s stream.started/stream.stopped or Ant Media’s liveStreamStarted/liveStreamEnded. The request body is form-encoded (app, name, addr, and similar fields), not JSON, so if you’re forwarding these into a tool that expects JSON — Zapier, Make, a Slack Incoming Webhook — you’ll need a thin script in between to reshape the payload. There’s no built-in retry and no built-in authentication: NGINX-RTMP trusts whatever 127.0.0.1 sends back a 2xx to, so if your callback endpoint isn’t on localhost, put it behind a firewall rule or a shared-secret header check you verify yourself.

Wowza vs. Ant Media vs. NGINX-RTMP: Webhook Support Compared

FeatureWowza Streaming EngineAnt Media ServerNGINX-RTMP
Native webhook featureYes (since 4.9.6)YesNo — uses callback directives instead
Config locationServer.xml + Webhooks.jsonred5-web.properties or REST API listenerHookURLnginx.conf (on_publish, etc.)
Payload formatJSONJSONForm-encoded
Events availablestream.started/stopped, recording.*, app.*, server.log.errorliveStreamStarted, liveStreamEnded, vodReadypublish, publish_done, play, play_done, record_done, update
Built-in authYes — JWT bearer tokenNo (add your own header check)No (trust by source IP or your own check)
Built-in retryYes — maxRetryAttempts / retryDelayNoNo

What Can You Actually Automate With Stream Webhooks?

The webhook itself is just a notification — the value comes from what your receiver does with it. Practical uses we’ve seen on StreamingVPS.com customer deployments:

  • Team alerts: POST a formatted message to a Slack or Discord webhook the moment stream.started (Wowza) or liveStreamStarted (Ant Media) fires, so production staff know a channel went live without watching a dashboard.
  • Recording pipelines: trigger a transcode job, thumbnail generation, or upload-to-storage step on recording.stopped / vodReady, instead of a cron job polling the filesystem for new files.
  • Billing and access control: combine a liveStreamEnded event with your pay-per-view or subscription logic (see our PPV billing guide) to close out a metered session the instant a broadcaster stops streaming, rather than waiting for a token to expire.
  • Autoscaling triggers: on a multi-channel setup (see our multi-channel streaming guide), use app.started events to spin up a dedicated transcoding worker only when a given channel actually goes live, instead of running idle capacity 24/7.
  • Analytics ingestion: feed stream.started/stream.stopped timestamps straight into the metrics pipeline described in our live streaming analytics guide for accurate uptime and session-length reporting without extra polling load on the engine’s stats API.

How Do You Secure a Webhook Endpoint on Your VPS?

Because none of the three engines encrypt or sign requests the same way, security has to be handled per engine:

  • Wowza: use the built-in JWT auth block in Webhooks.json and verify the signed token on your receiver before trusting the payload — this is the only one of the three engines with authentication designed in from the start.
  • Ant Media: since listenerHookURL has no native auth, run the receiver on 127.0.0.1 on the same VPS whenever possible so the request never touches the public network. If it must be remote, add a custom header with a shared secret and reject anything that doesn’t match.
  • NGINX-RTMP: bind callback URLs to 127.0.0.1 as the docs recommend (also avoids IPv6/DNS resolution quirks with localhost), and if the receiver is remote, restrict inbound access at the firewall level — see our firewall ports guide for the full port list you’ll be working around.

In all three cases, always serve the receiver over HTTPS if it’s reachable from outside the VPS, and treat the webhook payload as untrusted input — validate the stream name and application against what you expect before triggering anything destructive (like deleting a recording or revoking a billing session).

FAQ

Do webhooks work the same way across Wowza, Ant Media, and NGINX-RTMP?
No. Wowza Streaming Engine 4.9.6+ has a native WebhookListener module with JSON config, JWT auth, and automatic retries. Ant Media Server sends a JSON POST to a listenerHookURL you configure globally or per broadcast, with no built-in retry. NGINX-RTMP has no dedicated webhook feature at all — it uses on_publish, on_publish_done, and similar directives that POST to a script you write yourself.

Can I use Zapier or Make with these stream webhooks?
Yes, but only Wowza and Ant Media send ready-to-use JSON that a Zapier or Make “Catch Hook” step can parse directly. NGINX-RTMP’s on_publish callback sends form-encoded POST data, so you typically need a small script to reshape it into JSON before forwarding it to Zapier or Make.

What happens if my webhook receiver is down when a stream event fires?
Wowza retries failed webhook deliveries according to the maxRetryAttempts and retryDelay values set in Webhooks.json. Ant Media Server and NGINX-RTMP do not retry failed webhook calls by default, so a missed event is lost unless you add your own queue or retry logic on the receiving end.

Do I need a public IP or open firewall port to receive stream webhooks?
Not if your webhook receiver runs on the same VPS as the streaming engine — a service bound to 127.0.0.1 works fine since the request never leaves the box. If the receiver lives on a separate server, you need a public endpoint (typically HTTPS) and a firewall rule allowing inbound traffic from your VPS’s IP.

Does enabling webhooks slow down the live stream itself?
No. In Wowza, Ant Media, and NGINX-RTMP, webhook notifications are fired asynchronously alongside the media pipeline, not inline with it, so a slow or unreachable webhook endpoint does not add latency to the RTMP ingest or HLS output.

Conclusion

Webhooks turn your streaming engine from something you have to poll into something that tells you what’s happening, which is the difference between a dashboard you check and infrastructure that reacts on its own. Wowza’s native module is the most turnkey option if you’re already on 4.9.6+; Ant Media’s simpler listenerHookURL is enough for most Slack-alert and billing use cases; NGINX-RTMP gives you the most raw control at the cost of building the plumbing yourself. Whichever engine you’re running, all three come pre-installed and pre-configured on StreamingVPS.com’s streaming VPS plans, so you can go straight to writing the receiver instead of compiling modules or hunting for the right config file.

Get a pre-installed streaming engine VPS from StreamingVPS.com — go live in 60 seconds, and start wiring up your own automation from day one.

Sources: Wowza — Create webhooks to monitor streaming events, Ant Media — Webhooks documentation, nginx-rtmp-module — Directives wiki

Leave a Reply

Your email address will not be published. Required fields are marked *