Skip to main content

Stream health monitoring covers two concerns: lifecycle events (is the stream active or idle?) and ingest quality (is the bitrate stable? are segments being delivered?). Use webhooks for the former and API polling for the latter.

Stream lifecycle

A stream has two observable states: Check status via API:
const response = await client.stream.get(streamId);
const stream = response.stream;

console.log('Active:', stream.isActive);
console.log('Last seen:', stream.lastSeen); // ISO timestamp
Subscribe to lifecycle webhooks for event-driven notifications:
await client.webhook.create({
  name: 'stream-lifecycle',
  url: 'https://your-server.com/webhooks/stream',
  events: ['stream.started', 'stream.idle'],
});

Ingest health metrics

The stream object includes ingest metrics when the stream is active:
const response = await client.stream.get(streamId);
const stream = response.stream;

// Available when stream.isActive === true
console.log('Video codec:', stream.videoSpec?.codec);       // e.g. "h264"
console.log('Video bitrate:', stream.videoSpec?.bitrate);   // bits per second
console.log('Frame rate:', stream.videoSpec?.fps);          // frames per second
console.log('Resolution:', `${stream.videoSpec?.width}x${stream.videoSpec?.height}`);
Low or unstable bitrate values indicate encoder problems (network congestion, CPU throttling, or misconfigured output settings) rather than Livepeer issues.

Interpreting health signals

SignalHealthy rangeAction if outside range
Video bitrateWithin 10% of encoder targetCheck encoder network/CPU; reduce output quality
Frame rateWithin 2 FPS of encoder targetCheck encoder CPU load
isActive flip to falseShould not happen mid-streamCheck encoder network; inspect stream.idle webhook payload
For viewer-side health (buffer length, rebuffering rate), instrument the @livepeer/react Player events or integrate your own player analytics.

Setting up alerts

Combine webhooks with your alerting stack (PagerDuty, Grafana, Datadog):
// Webhook handler -- alert on unexpected stream.idle events
app.post('/webhooks/stream', async (req, res) => {
  const { event, payload } = req.body;

  if (event === 'stream.idle') {
    const stream = payload;
    // Stream went idle -- was this expected?
    if (stream.isScheduled) {
      await alertOncall(`Scheduled stream ${stream.name} went idle unexpectedly`);
    }
  }

  res.sendStatus(200);
});

Webhooks

Full webhook setup and signature verification.

Create a Livestream

Stream creation and RTMP ingest configuration.
Last modified on April 7, 2026