Skip to main content

Ingress API

Use LiveKit's ingress service to import live streams from non-WebRTC sources into LiveKit rooms.

API

The Ingress API is available within the server SDKs and the CLI:

CreateIngress

WHIP / RTMP example

To provision an ingress with the Ingress service, use the CreateIngress API. It returns an IngressInfo object that describes the created ingress, along with connection settings. These parameters can also be queried at any time using the ListIngress API

Create a file at ingress.json with the following content:

{
"input_type": 0 for RTMP, 1 for WHIP
"name": "Name of the ingress goes here",
"room_name": "Name of the room to connect to",
"participant_identity": "Unique identity for the room participant the Ingress service will connect as",
"participant_name": "Name displayed in the room for the participant",
"enable_transcoding": true // Transcode the input stream. Can only be false for WHIP,
}

Then create the ingress using lk:

export LIVEKIT_URL=https://my-livekit-host
export LIVEKIT_API_KEY=livekit-api-key
export LIVEKIT_API_SECRET=livekit-api-secret
lk ingress create ingress.json
import { IngressClient, IngressInfo, IngressInput } from 'livekit-server-sdk';
const livekitHost = 'https://my-livekit-host';
const ingressClient = new IngressClient(livekitHost, 'api-key', 'secret-key');
const ingress = {
name: 'my-ingress',
roomName: 'my-room',
participantIdentity: 'my-participant',
participantName: 'My Participant',
// Transcode the input stream. Can only be false for WHIP.
enableTranscoding: false,
};
// Use IngressInput.WHIP_INPUT to create a WHIP endpoint
await ingressClient.createIngress(IngressInput.RTMP_INPUT, ingress);
ctx := context.Background()
ingressClient := lksdk.NewIngressClient(
"https://my-livekit-host",
"livekit-api-key",
"livekit-api-secret",
)
t := true
ingressRequest := &livekit.CreateIngressRequest{
InputType: livekit.IngressInput_RTMP_INPUT, // Or livekit.IngressInput_WHIP_INPUT
Name: "my-ingress",
RoomName: "my-room",
ParticipantIdentity: "my-participant",
ParticipantName: "My Participant",
// Transcode the input stream. Can only be false for WHIP.
EnableTranscoding: &t,
}
info, err := ingressClient.CreateIngress(ctx, ingressRequest)
ingressID := info.IngressId
ingressClient = LiveKit::IngressServiceClient.new(url, api_key: "yourkey", api_secret: "yoursecret")
info = ingressClient.create_ingress(
:RTMP_INPUT, # Or WHIP_INPUT
name: "my-ingress",
room_name: "my-room",
participant_identity: "my-participant",
participant_name: "My Participant",
)
puts info.ingress_id

URL Input example

With URL Input, ingress will begin immediately after CreateIngress is called. URL_INPUT ingress can't be reused.

Create a file at ingress.json with the following content:

{
"input_type": "URL_INPUT", // or 2
"name": "Name of the ingress goes here",
"room_name": "Name of the room to connect to",
"participant_identity": "Unique identity for the room participant the Ingress service will connect as",
"participant_name": "Name displayed in the room for the participant",
"url": "HTTP(S) or SRT url to the file or stream"
}

Then create the ingress using lk:

export LIVEKIT_URL=https://my-livekit-host
export LIVEKIT_API_KEY=livekit-api-key
export LIVEKIT_API_SECRET=livekit-api-secret
lk ingress create ingress.json
import { IngressClient, IngressInfo, IngressInput } from 'livekit-server-sdk';
const livekitHost = 'https://my-livekit-host';
const ingressClient = new IngressClient(livekitHost, 'api-key', 'secret-key');
const ingress = {
name: 'my-ingress',
roomName: 'my-room',
participantIdentity: 'my-participant',
participantName: 'My Participant',
url: 'https://domain.com/video.m3u8', // or 'srt://domain.com:7001'
};
await ingressClient.createIngress(IngressInput.URL_INPUT, ingress);
ctx := context.Background()
ingressClient := lksdk.NewIngressClient(
"https://my-livekit-host",
"livekit-api-key",
"livekit-api-secret",
)
ingressRequest := &livekit.CreateIngressRequest{
InputType: livekit.IngressInput_URL_INPUT,
Name: "my-ingress",
RoomName: "my-room",
ParticipantIdentity: "my-participant",
ParticipantName: "My Participant",
Url: "https://domain.com/video.m3u8", // or 'srt://domain.com:7001'
}
info, err := ingressClient.CreateIngress(ctx, ingressRequest)
ingressID := info.IngressId
ingressClient = LiveKit::IngressServiceClient.new(url, api_key: "yourkey", api_secret: "yoursecret")
info = ingressClient.create_ingress(
:URL_INPUT,
name: "my-ingress",
room_name: "my-room",
participant_identity: "my-participant",
participant_name: "My Participant",
url: "https://domain.com/video.m3u8", # or 'srt://domain.com:7001'
)
puts info.ingress_id

ListIngress

lk ingress list

The optional --room option allows to restrict the output to the Ingress associated to a given room. The --id option can check if a specific ingress is active.

await ingressClient.listIngress('my-room');

The roomName parameter can be left empty to list all Ingress.

listRequest := &livekit.ListIngressRequest{
RoomName: "my-room", // Optional parameter to restrict the list to only one room. Leave empty to list all Ingress.
}
infoArray, err := ingressClient.ListIngress(ctx, listRequest)
puts ingressClient.list_ingress(
# optional
room_name: "my-room"
)

UpdateIngress

The ingress configuration can be updated using the UpdateIngress API. This enables the ability to reuse the same ingress URL to publish to different rooms. Only reusable ingresses, such as RTMP or WHIP, can be updated.

Create a file at ingress.json with the fields to be updated.

{
"ingress_id": "Ingress ID of the ingress to update",
"name": "Name of the ingress goes here",
"room_name": "Name of the room to connect to",
"participant_identity": "Unique identity for the room participant the Ingress service will connect as",
"participant_name": "Name displayed in the room for the participant"
}

The only required field is ingress_id. Non-provided fields are left unchanged.

lk ingress update ingress.json
const update = {
name: 'my-other-ingress',
roomName: 'my-other-room',
participantIdentity: 'my-other-participant',
participantName: 'My Other Participant',
};
await ingressClient.updateIngress(ingressID, update);

Parameters left empty in the update object are left unchanged.

updateRequest := &livekit.UpdateIngressRequest{
IngressId: "ingressID", // required parameter indicating what Ingress to update
Name: "my-other-ingress",
RoomName: "my-other-room",
ParticipantIdentity: "my-other-participant",
ParticipantName: "My Other Participant",
}
info, err := ingressClient.UpdateIngress(ctx, updateRequest)

Non specified fields are left unchanged.

# only specified fields are updated, all fields are optional
puts ingressClient.update_ingress(
"ingress-id",
name: "ingress-name",
room_name: "my-room",
participant_identity: "my-participant",
participant_name: "My Participant",
audio: LiveKit::Proto::IngressAudioOptions.new(...),
video: LiveKit::Proto::IngressVideoOptions.new(...),
)

DeleteIngress

An ingress can be reused multiple times. When not needed anymore, it can be deleted using the DeleteIngress API:

lk ingress delete <INGRESS_ID>
await ingressClient.deleteIngress('ingress_id');
deleteRequest := &livekit.DeleteIngressRequest{
IngressId: "ingress_id",
}
info, err := ingressClient.DeleteIngress(ctx, deleteRequest)
puts ingressClient.delete_ingress("ingress-id")

Types

The Ingress service includes the following types.

ListIngressResponse

FieldTypeDescription
itemsarray<IngressInfo>List of ingress endpoints.
next_page_tokenTokenPaginationToken for the next page of results.

IngressInfo

Describes the ingress and its connection settings.

FieldTypeDescription
ingress_idstringUnique ingress ID.
namestringUser-provided identifier for the ingress.
stream_keystringStream key for the encoder (RTMP).
urlstringURL for the encoder (RTMP, WHIP) or source to pull from (URL input). Format depends on input type: rtmp:// for RTMP, http:// for URL.
input_typeIngressInputType of input.
enable_transcodingboolWhether transcoding is enabled.
audioIngressAudioOptionsAudio options.
videoIngressVideoOptionsVideo options.
room_namestringRoom the ingress publishes to.
participant_identitystringIdentity of the publishing participant.
participant_namestringDisplay name of the publishing participant.
participant_metadatastringMetadata associated with the publishing participant.
reusableboolWhether the ingress can be reused (e.g. for another room).
stateIngressStateCurrent state, including error or debug info (bitrate, resolution, bandwidth).
enabledboolWhen false, new connection attempts are rejected. Default is true.

IngressState

Describes current endpoint status, errors, and input media state.

FieldTypeDescription
statusIngressState.StatusEndpoint status.
errorstringError or non-compliance description, if any.
videoInputVideoStateIncoming video state.
audioInputAudioStateIncoming audio state.
room_idstringID of the current or previous room published to.
started_atint64When the endpoint started publishing.
ended_atint64When the endpoint stopped publishing.
updated_atint64Last update timestamp.
resource_idstringResource identifier.
tracksarray<TrackInfo>Published track info.

IngressState.Status

Enum. Endpoint status values:

NameValueDescription
ENDPOINT_INACTIVE0Endpoint is inactive.
ENDPOINT_BUFFERING1Endpoint is buffering.
ENDPOINT_PUBLISHING2Endpoint is publishing.
ENDPOINT_ERROR3Endpoint encountered an error.
ENDPOINT_COMPLETE4Endpoint finished (e.g. stream ended).

InputVideoState

State of the incoming video input.

FieldTypeDescription
mime_typestringMIME type of the video.
average_bitrateuint32Average bitrate in bps.
widthuint32Frame width in pixels.
heightuint32Frame height in pixels.
frameratedoubleFrame rate.

InputAudioState

State of the incoming audio input.

FieldTypeDescription
mime_typestringMIME type of the audio.
average_bitrateuint32Average bitrate in bps.
channelsuint32Number of audio channels.
sample_rateuint32Sample rate in Hz.

IngressInput

Enum. Type of ingress input:

NameValueDescription
RTMP_INPUT0RTMP push input.
WHIP_INPUT1WHIP push input.
URL_INPUT2Pull from a URL. Only HTTP URLs supported (single media file or HLS stream).

IngressAudioOptions

FieldTypeDescription
namestringTrack name.
sourceTrackSourceTrack source.
encoding_optionsIngressAudioEncodingPreset or IngressAudioEncodingOptionsPreset or custom encoding options.

IngressVideoOptions

FieldTypeDescription
namestringTrack name.
sourceTrackSourceTrack source.
encoding_optionsIngressVideoEncodingPreset or IngressVideoEncodingOptionsPreset or custom encoding options.

IngressAudioEncodingPreset

Enum. Audio encoding presets:

NameValueDescription
OPUS_STEREO_96KBPS0OPUS, 2 channels, 96 kbps.
OPUS_MONO_64KBS1OPUS, 1 channel, 64 kbps.

IngressVideoEncodingPreset

Enum. Video encoding presets:

NameValueDescription
H264_720P_30FPS_3_LAYERS01280×720, 30 fps, 1900 kbps main layer, 3 layers total.
H264_1080P_30FPS_3_LAYERS11920×1080, 30 fps, 3500 kbps main layer, 3 layers total.
H264_540P_25FPS_2_LAYERS2960×540, 25 fps, 1000 kbps main layer, 2 layers total.
H264_720P_30FPS_1_LAYER31280×720, 30 fps, 1900 kbps, no simulcast.
H264_1080P_30FPS_1_LAYER41920×1080, 30 fps, 3500 kbps, no simulcast.
H264_720P_30FPS_3_LAYERS_HIGH_MOTION51280×720, 30 fps, 2500 kbps main layer, 3 layers, higher bitrate for high motion.
H264_1080P_30FPS_3_LAYERS_HIGH_MOTION61920×1080, 30 fps, 4500 kbps main layer, 3 layers, higher bitrate for high motion.
H264_540P_25FPS_2_LAYERS_HIGH_MOTION7960×540, 25 fps, 1300 kbps main layer, 2 layers, higher bitrate for high motion.
H264_720P_30FPS_1_LAYER_HIGH_MOTION81280×720, 30 fps, 2500 kbps, no simulcast, higher bitrate for high motion.
H264_1080P_30FPS_1_LAYER_HIGH_MOTION91920×1080, 30 fps, 4500 kbps, no simulcast, higher bitrate for high motion.

IngressAudioEncodingOptions

Custom audio encoding options.

FieldTypeDescription
audio_codecAudioCodecDesired audio codec to publish to the room.
bitrateuint32Bitrate in bps.
disable_dtxboolWhether to disable DTX.
channelsuint32Number of channels.

IngressVideoEncodingOptions

Custom video encoding options.

FieldTypeDescription
video_codecVideoCodecDesired video codec to publish to the room.
frame_ratedoubleFrame rate.
layersarray<VideoLayer>Simulcast layers. When empty, layers are typically set to 1/2 and 1/4 of dimensions.