The Studio API manages the full livestream lifecycle: creation, ingest, transcoding, and delivery. You push video via RTMP; Livepeer handles transcoding to adaptive bitrate HLS.
Prerequisites
API key from Livepeer Studio under Settings > API Keys
SDK installed: npm install livepeer / pip install livepeer / go get github.com/livepeer/livepeer-go
An RTMP encoder: OBS Studio, ffmpeg, or a custom stream producer
Step 1 — Create a stream
import { Livepeer } from 'livepeer' ;
const client = new Livepeer ({ apiKey: process . env . LIVEPEER_API_KEY });
const response = await client . stream . create ({
name: 'my-livestream' ,
record: false , // set true to save recordings automatically
});
const stream = response . stream ;
console . log ( 'RTMP ingest URL:' , stream . rtmpIngestUrl );
console . log ( 'Stream key:' , stream . streamKey );
console . log ( 'Playback ID:' , stream . playbackId );
from livepeer import Livepeer
import os
client = Livepeer( api_key = os.environ[ 'LIVEPEER_API_KEY' ])
response = client.stream.create( request = {
'name' : 'my-livestream' ,
'record' : False ,
})
stream = response.stream
print ( 'RTMP ingest URL:' , stream.rtmp_ingest_url)
print ( 'Stream key:' , stream.stream_key)
print ( 'Playback ID:' , stream.playback_id)
import (
" context "
livepeer " github.com/livepeer/livepeer-go "
" github.com/livepeer/livepeer-go/models/components "
)
client := livepeer . New ( livepeer . WithSecurity ( os . Getenv ( "LIVEPEER_API_KEY" )))
name := "my-livestream"
record := false
response , err := client . Stream . Create ( context . Background (),
components . NewStreamPayload {
Name : name ,
Record : & record ,
},
)
if err != nil {
log . Fatal ( err )
}
fmt . Println ( "RTMP ingest URL:" , response . Stream . RTMPIngestURL )
fmt . Println ( "Playback ID:" , response . Stream . PlaybackID )
The response includes:
rtmpIngestUrl — push your stream here
streamKey — the key portion of the RTMP URL, for encoders that take URL and key separately
playbackId — use this to construct the HLS playback URL
Step 2 — Push your stream
OBS Studio:
Open Settings > Stream
Set Service to Custom
Set Server to rtmp://rtmp.livepeer.com/live (or the full rtmpIngestUrl from step 1)
Set Stream Key to the streamKey value
Click Start Streaming
ffmpeg (for testing):
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset veryfast -b:v 3000k \
-c:a aac -b:a 128k \
-f flv rtmp://rtmp.livepeer.com/live/ < your-stream-ke y >
Step 3 — Play back the stream
Construct the HLS URL using your playbackId:
https://livepeercdn.studio/hls/<playbackId>/index.m3u8
Use the @livepeer/react Player component for the simplest integration:
import * as Player from '@livepeer/react/player' ;
export const LivePlayer = ({ playbackId } : { playbackId : string }) => (
< Player.Root src = { `https://livepeercdn.studio/hls/ ${ playbackId } /index.m3u8` } >
< Player.Container >
< Player.Video />
< Player.Controls />
</ Player.Container >
</ Player.Root >
);
Or use any HLS player (HLS.js, Video.js, native Safari):
// HLS.js
const hls = new Hls ();
hls . loadSource ( `https://livepeercdn.studio/hls/ ${ playbackId } /index.m3u8` );
hls . attachMedia ( videoElement );
Checking stream status
A stream has two relevant states: idle (no active ingest) and active (receiving video).
const stream = await client . stream . get ( streamId );
console . log ( 'Status:' , stream . stream . isActive ? 'active' : 'idle' );
Use webhooks to receive event notifications instead of polling:
// Create a webhook for stream status events
await client . webhook . create ({
name: 'stream-status' ,
url: 'https://your-server.com/webhooks/livepeer' ,
events: [ 'stream.started' , 'stream.idle' ],
});
See the Webhooks guide for full setup.
Related pages
Access Control Gate your stream with JWTs or webhook-based authorisation.
Webhooks Receive notifications for stream.started, stream.idle, and asset events.
Playback HLS and WebRTC playback options and player integration.
Monitor Stream Health Check ingest health, bitrate, and segment delivery.
Last modified on April 7, 2026