livqenoDocs

Live StreamingStreams & Lifecycle

Streams & Lifecycle

Create, start, read, update, and end a stream. Status only moves forward.

A stream is the record for one live event, like "Launch Day, Friday 6pm". This page covers everything your backend does with it: create, start, read, update, and end.

Where this fits: all of these calls run on your backend with your API key (or in your terminal with the CLI). Your app never calls them. It only joins a stream with the credentials from Hosts and Viewers.

Create a stream

Create one stream per event. A common pattern: create it when the host schedules the event in your app, save stream.id next to your own event record, and start it later.

const stream = await livqeno.liveStreams.create({ title: 'Launch Day', hostIdentity: 'alice' });

This one call does three things:

  1. Creates the RTC room, where the video will happen.
  2. Creates the chat conversation. See Live chat.
  3. Records hostIdentity (here alice) as the stream's HOST.

It does not give Alice credentials to join yet. Call addHost for that, when she's ready to go on.

The new stream's status is CREATED, and your backend gets the live_stream.created webhook.

Lifecycle

CREATED → STARTING → LIVE → ENDING → ENDED

Only two calls change the status:

CallMovesWhen to call itWhat else happens
startCREATED → LIVE (STARTING is skipped)The host clicks Go live.Sends live_stream.started. Checks the "1 live stream at a time" limit. Starts the 240-minute clock.
endLIVE → ENDED (ENDING is skipped)The host clicks End, or your event is over.Closes the room and disconnects everyone. Sends live_stream.ended.

Hosts and viewers can already join while the stream is CREATED. That's useful for a "backstage" check: the host joins, tests the camera, and only then you call start. The status tells your app whether to show the stream as live. It doesn't open or close the room by itself.

If a stream stays LIVE for 240 minutes, Livqeno ends it for you.

await livqeno.liveStreams.start(streamId);
await livqeno.liveStreams.end(streamId);

Read a stream

Read a stream to show it in your app, for example a "Live now" list or an event page with the current viewer count:

const stream = await livqeno.liveStreams.get(streamId);
const all = await livqeno.liveStreams.list({ status: 'LIVE' }); // no live viewer counts — one GET per stream for that
{
  "id": "stream_jRoD1T3EXh0PMJRGG4zYzQ",
  "status": "LIVE",
  "conversationId": "conv_0iojWXJCtXZUUkDR7THBmQ",
  "chatRootMessageId": "msg_Efm2zArYJTSRUr88BV5bZg",
  "hosts": [{ "identity": "alice", "role": "HOST" }],
  "viewerCount": 12,
  "peakViewerCount": 47,
  "startedAt": "2026-08-19T08:21:13.792Z",
  "endedAt": null
}
  • viewerCount is how many viewers are connected right now. It's worked out live each time you call get(), so it isn't stored. See Analytics.
  • hosts lists who can broadcast, with their role.
  • conversationId is the stream's chat. You rarely need it directly, because stream.chat in your app is already connected to it.

Update a stream

Update a stream to fix its details, for example when the host renames the event. You can change: title, description, category, tags, language, visibility, and metadata.

You can't change status this way. Use start() and end().

await livqeno.liveStreams.update(streamId, { title: 'Launch Day (Part 2)' });

Once a stream has ENDED, updates fail with RAVEN_STREAM_INVALID_STATE. An ended stream can't be changed.

Common errors

ErrorCauseFix
RAVEN_STREAM_NOT_FOUNDWrong id, or the stream is in another project or environment.Use an id from create() or list().
RAVEN_STREAM_INVALID_STATEA wrong lifecycle move, or updating an ENDED stream.Check status first. Status only moves forward.

Production tips

  • Don't poll get() too often. Each call asks the media server who is connected. Poll only as often as your UI needs, for example every 10–30 seconds for a viewer count.
  • list() doesn't include live viewer counts (viewerCount: null), so a "Live now" list stays fast. Use get() on a single stream if you need its count.
  • Use webhooks instead of polling for status. live_stream.started and live_stream.ended tell your backend the moment a stream changes. See Stream events.

Next steps

You have a stream. Now give people a way in: