Connect external media with HTTP, WHIP, WHEP, and HLS
Use this guide when a camera encoder, production tool, or custom player must connect to an active MediaSFU room. Your application server creates the short-lived connection. The browser or SDK continues to run the room itself.
You need a room that is already running, an application-server route that can make authenticated MediaSFU requests, and a deliberate cleanup step. Do not put service credentials, ingest tokens, or playback tokens in a browser, mobile app, source repository, or log.
Choose the result you want
| You want to... | Use | What your server creates |
|---|---|---|
| Send an external camera or encoder into a room | WHIP ingest | an external session |
| Watch an approved external session in a WebRTC player | WHEP playback | a playback resource |
| Give a large audience an HLS stream from a room member or external video session | HLS broadcast | a broadcast resource |
The HTTP control routes live under /v1/meetings/:meetingID. They require an authorized server-to-server request and the appropriate MediaSFU operation. Treat meetingID, session IDs, playback IDs, broadcast IDs, and returned tokens as scoped resources, not as permanent public links.
1. Create an external session
Your application server sends this request after it has authorized the person or system that will publish media. This is a request shape, not a browser call and not a place to paste credentials.
const request = {
method: 'POST',
path: '/v1/meetings/sabcdefgh/external-sessions',
body: {
displayName: 'Studio camera',
ingest: { protocol: 'whip', tracks: ['video'] },
},
};
When WHIP is enabled for the environment, the response provides an ingest URL and a separate short-lived token. Give those values directly to the WHIP-capable publisher through your secure runtime path. Do not append the token to the URL yourself.
For ordinary MediaSFU WebRTC publishing, the same endpoint supports
mediasfu-webrtc; track creation then belongs to the authenticated MediaSFU
publisher, not to an HTTP tracks request.
Poll the individual session until it is active and exposes the expected
tracks before creating a viewer or broadcast. Use the returned track IDs to
pause, resume, close, or request a video keyframe. An HTTP request cannot create
a media track on behalf of a publisher.
2. Create a WHEP playback resource
Choose an active external session and the tracks the player needs.
const request = {
method: 'POST',
path: '/v1/meetings/sabcdefgh/playbacks',
body: {
sourceSessionID: 'ems_aaaaaaaaaaaaaaaaaaaaaaaa',
tracks: ['audio', 'video'],
},
};
The server returns a WHEP endpoint and a short-lived playback token. Supply them to a WHEP client using that client's documented authorization mechanism. The endpoint is not an HLS URL and the token must not be added to the page URL.
A MediaSFU-aware WHEP player first reads the endpoint's payload profile, aligns
the dynamic RTP payload types in its receive-only SDP offer, and then posts the
offer. Treat 406 PAYLOAD_TYPE_MISMATCH as a configuration error; do not play
mismatched media. WHEP creates one interactive consumer per viewer, so use it
for a bounded realtime audience rather than mass passive playback.
3. Create an HLS broadcast
An HLS broadcast can use one room member or an external video session as its source. The server selects the available rendition ladder and returns a protected playback URL only while the short-lived token is available.
const request = {
method: 'POST',
path: '/v1/meetings/sabcdefgh/broadcasts',
body: { sourceSessionID: 'ems_aaaaaaaaaaaaaaaaaaaaaaaa' },
};
Wait until the broadcast reports an active state before offering playback. A broadcast request can be declined when the feature is disabled, the room has ended, no meeting controller is available, the selected source has no video, or the account is not entitled to the feature.
The returned rendition list is authoritative. MediaSFU can create the source's quality and lower qualities, but it does not upscale an SD source to HD. This path uses signed CMAF/fMP4 HLS with complete segments; it is not partial-segment Low-Latency HLS. Put an approved CDN in front of the origin for a large public audience.
Combine HTTP control with an SDK room
An active external session appears to SDK viewers as a scoped room participant. Use the normal MediaSFU SDK participant and media flow for interactive viewers. When an HTTP-only publisher also needs bounded collaboration state, its server can use:
GET /v1/meetings/:meetingID/external-sessions/:sessionID/participant-statefor participant media state, recent chat, polls, breakout assignment, and whiteboard assignment;POST /v1/meetings/:meetingID/external-sessions/:sessionID/participant-actionsto submit an allowed poll vote, chat message, or participant request.
The server derives the actor from the owned external session. Do not accept a sender identity from the browser request body. Use an SDK socket instead of polling when the product needs push updates or frequent collaboration changes.
For example, an authorized application server can submit a poll vote without inventing a participant name:
const request = {
method: 'POST',
path: '/v1/meetings/sabcdefgh/external-sessions/'
+ 'ems_aaaaaaaaaaaaaaaaaaaaaaaa/participant-actions',
body: {
action: 'poll.vote',
pollID: 'poll-001',
choice: 0,
},
};
Check state and clean up
Fetch the individual resource to show progress in your operator UI. When the event ends, send DELETE to the exact resource you created:
const cleanup = {
method: 'DELETE',
path: '/v1/meetings/sabcdefgh/broadcasts/emb_bbbbbbbbbbbbbbbbbbbbbbbb',
body: { reason: 'event_finished' },
};
The corresponding cleanup routes are:
/v1/meetings/:meetingID/external-sessions/:sessionID/v1/meetings/:meetingID/playbacks/:playbackID/v1/meetings/:meetingID/broadcasts/:broadcastID
Delete dependent WHEP playbacks and broadcasts before deleting their source session. Repeated cleanup is safe to treat as complete. Still remove each temporary token and resource identifier from your own runtime storage when your application is finished with it.
What this guide does not promise
WHIP, WHEP, HLS broadcast, SRT, RTMP, and RTMPS are independently enabled platform features. This guide does not provide a public configuration recipe for turning them on, a permanent stream URL, a browser-only credential flow, a generic external-media SDK method, or a synchronized WebRTC-plus-HLS timeline guarantee. Ask your MediaSFU platform administrator to enable and authorize the protocols your deployment is entitled to use.
Release checklist
- Keep all authorization and MediaSFU credentials on your application server.
- Request only the audio and video tracks your tool needs.
- Display the resource state before declaring an ingest or broadcast ready.
- Handle disabled, unauthorized, expired, unavailable-controller, and capacity responses.
- Stop the external session, playback, or broadcast on cancellation and at event end.
- Remove temporary tokens from application memory, logs, analytics, and support screenshots.