livqenoDocs

Live StreamingOverview

Live Streaming Overview

One host broadcasts to many viewers, with a chat attached. Built on Livqeno RTC and Chat.

Live Streaming lets one host broadcast video to many viewers. Viewers can't broadcast. They watch, chat, and send reactions. Think of a webinar, a live class, a product launch, or a creator going live to their followers.

Where this fits: you already have a project and an API key (API credentials). Your backend creates the stream and makes a credential for each person. Your app joins with that credential. Webhooks tell your backend when the stream starts, ends, and who joined.

How it's built

A live stream is not a separate system. It's two things you may already know, created together:

  • one RTC room, where the video happens. The hosts are the participants who can publish (send camera and mic).
  • one chat conversation, where viewers talk and react.

One call, POST /v1/live-streams, creates both. You don't run a media server or a chat server, and you don't wire them together yourself.

RTCChatLive Streaming
Main objectRoomConversationLiveStream (one room + one conversation)
Who can publishAnyone your token allows (publish: true)—Only hosts and co-hosts. Never viewers.
CredentialRTC tokenChat tokenBoth, made together, per person

New to words like publish, SFU, or token? See the Glossary.

What happens during a stream

Say alice runs a launch event and carol watches:

Your backendholds the API key
Livqeno
Your appsAlice hosts, Carol watches
1create stream (host: alice)
room + chat created
2addHost(alice)
host credential
send to Alice's app
3Alice joins, turns on camera
4start()
status: LIVE
5createViewerToken(carol)
viewer credential
send to Carol's app
6Carol joins, watches, chats, reacts
7end()
room closed, everyone disconnected
One live stream, from creation to end.

All the steps in the left column run on your backend with your API key. The apps only ever receive a credential.

Lifecycle

A stream's status only moves forward:

CREATED → STARTING → LIVE → ENDING → ENDED

What actually happens today:

  • start() moves the stream from CREATED straight to LIVE. STARTING is skipped.
  • end() moves it from LIVE to ENDED and closes the room. Everyone still connected is disconnected.
  • ENDED is final. You can't restart or replay a stream. For the next event, create a new stream.
  • Any other move fails with RAVEN_STREAM_INVALID_STATE.

Details: Streams & lifecycle.

Roles

Every person in a stream has one of three roles. Your backend picks the role by which call it makes, not by a field the app sends:

RoleMade byCan publish video/audioChat scopeTypical person
HostCreating the stream, or addHost with HOSTYesADMINThe presenter.
Co-hostaddHost (the default role)YesMODERATORA guest speaker or a second presenter.
ViewercreateViewerTokenNeverMEMBEREveryone in the audience.

A viewer's RTC token always has publish: false. The viewer-token request has no role field, so a viewer can't ask for more.

Free tier

Live Streaming has its own free allowance. It's separate from RTC minutes and chat messages, so using one never uses up another.

  • 100 host-hours per account.
    • Counted from the time hosts and co-hosts are actually connected. Gaps while reconnecting don't count.
    • Each host counts on their own. Two co-hosts streaming for one hour = 2 host-hours.
  • Viewers are free. They never use host-hours or RTC minutes, no matter how many there are or how long they watch.

There are also three limits:

LimitDefaultWhat happens when you hit it
Live streams at once1 per account (across all projects and environments)Starting a second stream fails with 403 RAVEN_STREAM_CONCURRENCY_LIMIT_EXCEEDED until the first one ends.
Viewers per stream100The 101st viewer token fails with 403 RAVEN_STREAM_VIEWER_LIMIT_EXCEEDED.
Stream length240 minutesThe stream ends automatically.

So on the free tier, plan for one event at a time, up to 100 viewers, up to 4 hours long. A paid plan lifts these limits. Full details: Usage.

Chat and reactions

  • Every stream gets a chat conversation as soon as it's created. You don't create it yourself.
  • stream.chat.sendMessage works just like normal Chat.
  • stream.react('❤️') adds a reaction to a hidden first message in that conversation. It's the same reactions feature chat already has, so many hearts from many viewers add up to one count.

See Live chat and Reactions.

Webhooks

Your backend can be told about these events, for example to post "We're live!" to social media, or to log who attended:

live_stream.created, .started, .ended, .host_joined, .host_left, .viewer_joined, .viewer_left, plus .restream_active/.restream_failed and .ingress_connected/.ingress_disconnected/.ingress_failed if you use restream or encoder ingest.

They're signed and delivered like every other Livqeno webhook. See Webhooks and Stream events.

Not available yet

  • No cloud recording.
  • No AI moderation or captions.
  • The viewer count is live only, with no history. See Analytics.
  • You can't make host or viewer credentials from the dashboard or CLI. This is on purpose. See SDK support.
  • Flutter's livqeno_live package isn't fully tested yet. Its credential parsing has unit tests, but LivqenoLiveStream.join(), leave() and react() haven't been tested end to end. Treat it as unverified.

Next steps

  1. Quickstart: run a full stream, host and viewer, in two browser tabs.
  2. Streams & lifecycle: create, start, update, and end streams from your backend.
  3. Hosts & co-hosts and Viewers: give each person the right credential.
  4. Live chat and Reactions: make the audience part of the show.
  5. SDK support: check what your platform can do.
  6. Restream and OBS & encoder ingest: send the stream on to YouTube or Twitch, or broadcast into it from OBS.

Video runs on Livqeno RTC. Comments and reactions run on Livqeno Chat. Live Streaming connects the two.