How a live stream flows through ShortKit
- Create the stream with
POST /v1/live-streams. Choose a protocol —hlsfor standard latency orwebrtcfor sub-second delivery. You receive aplaybackId(for viewers) and broadcast credentials (rtmpUrl+streamKey) for your encoder. - Forward the credentials to your broadcaster. They paste them into their encoder of choice. The broadcast workflow is the same regardless of protocol.
- The broadcaster goes live. As soon as ShortKit receives video, the stream’s
statusflips fromidletoactive. The stream appears in your feed automatically — no separate publish step. - Viewers watch from your app. The SDK plays the live stream the same way it plays any video. A live badge and viewer count are available to overlay on top.
- The stream ends. Either the broadcaster disconnects (and stays disconnected longer than
reconnectWindowon HLS streams), or you callPOST /v1/live-streams/{id}/end. The status moves toendedand the recording stays in the feed as a regular video. - Optionally, create clips from the recording with
POST /v1/live-streams/{id}/clips. Each clip becomes its own content item.
Choosing a protocol
ShortKit supports two ingest and delivery protocols:
Specify
protocol when you create the stream:
rtmpUrl from the create response — there is no separate setup required for WebRTC. The protocol choice only affects how the stream is delivered to viewers; the ShortKit SDK handles playback automatically.
The protocol cannot be changed after creation. latencyMode and reconnectWindow apply only to hls streams and are ignored for webrtc streams.
Creating a stream
You create a stream from your backend using your secret key:Broadcasting to a stream
Once you have thertmpUrl and streamKey from the create response, point your encoder at them to start pushing video.
rtmpUrl already embeds the stream key, so for tools that take a single URL (such as ffmpeg), pass it directly:
For example, with a WebRTC stream whose
rtmpUrl is rtmps://ingest.shortkit.dev/x/AbCdEfGhIjKl:
- Server:
rtmps://ingest.shortkit.dev/x/ - Stream Key:
AbCdEfGhIjKl
hls or webrtc stream — the difference is entirely on the viewer delivery side.
Displaying live streams in the feed
Live streams render in the feed with no extra setup. The SDK’sContentItem exposes the following live-specific fields you can read in your custom overlay:
isLive—truewhile the broadcast is in progress,falseafter it endsliveStreamStatus—"idle","active", or"ended"(more on lifecycle)liveStreamId— the underlying live stream’s UUID (use this from your backend to address the stream itself, e.g. for creating clips)currentViewers— concurrent viewer count for the stream (0for non-live items)startedAt— ISO 8601 timestamp the broadcaster connected (useful for an elapsed-time display)
- Swift
- Kotlin
- React Native
currentViewers for as long as they’re watching. The mechanism is a live.viewer.heartbeat event the SDK fires every 30 seconds while a live item is the active playing item. You don’t need to call any tracking API or write your own heartbeat code; just render the field.
For a known set of streams (for example, those currently visible to a viewer in your UI), you can also poll Get Live Stream Status directly with your publishable key to react to status changes (active → ended) more promptly than the next feed refresh would surface them.
Surfacing a specific live stream in a custom feed
If you’re using custom feed mode and want to surface a known stream at a specific position, pass itsplaybackId as a video input — the SDK plays it like any other:
- Swift
- Kotlin
- React Native
Turning a stream into clips
You can carve short clips out of a stream while it’s stillactive (real-time clipping during the broadcast) or after it has ended. Specify start and end offsets in seconds from the beginning of the stream:
contentId and playbackId. The clip is processing for a few seconds to a few minutes, then becomes ready and shows up in the feed like any other video.
If you provide a callbackUrl, ShortKit will POST to it once each clip is ready — handy if you want to re-share clips into your app immediately without polling.
See the Create Clips reference for the full request and response shape.
Letting end users create clips
If you want to expose a “clip this moment” affordance directly in your client app, don’t ship your secret key with the app — secret keys grant full server-side access to your organization and are extractable from any shipped binary. Instead, expose your own backend endpoint (using whatever user-auth your app already does) that takes a clip request from your client and forwards it to ShortKit’s clip API with your secret key. That gives you a place to enforce per-user rate limits, attribution, and abuse controls before a clip is created. The client app already has everything it needs to construct the request: readliveStreamId and the marked time offsets from the live ContentItem, send them to your backend, and your backend handles the rest.
Ending a stream
End any stream — regardless of protocol — by calling:reconnectWindow you configured at creation time (default: 60 seconds). Use the explicit end call above when you want to close the stream immediately rather than waiting for the timeout.
Once ended, a stream cannot be restarted. Create a new live stream for the next broadcast.
For the full object shape, field descriptions, and all available endpoints, see the Live Stream API reference.