Skip to main content
Egress pushes your room out to a streaming destination; ingress does the inverse. It pulls an external producer into a scheduled video room as a synthetic participant, so a broadcast encoder joins the room the way a person would: with a tile in the grid, a name in the roster, and a track in every composite, recording, and egress. Use it for hybrid town halls with a house camera run through vMix, field reporters pushing from a hardware encoder, or an OBS scene that shares the room with interactive WebRTC speakers. This guide covers the three ingress types on POST /api/v1/video/rooms-scheduled/{id}/ingress (createVideoRoomsScheduledByIdIngress in the video API reference): rtmp for standard broadcast encoders, whip for WebRTC-native uplinks, and url for sources Orbit should pull server-side.

What an ingress gives you

Creating an ingress returns the credentials your encoder needs, once:
  • RTMP ingress: point any RTMP-capable encoder at stream_url with stream_key as the stream key. Orbit remuxes the push into the room’s WebRTC media.
  • WHIP ingress: stream_url is a WHIP (WebRTC-HTTP Ingestion Protocol) endpoint and stream_key is the bearer token for it. The media stays WebRTC end to end.
  • URL ingress: you hand Orbit a public http(s):// or rtmp(s):// source (an HLS playlist, DASH manifest, or RTMP stream) and the media plane pulls it; no encoder configuration at all. url is required for type: "url" and rejected for the other two types.
The source joins under a server-generated participant_identity prefixed ingress_, so your roster always tells an ingested feed apart from a human participant. name (your internal label, e.g. “Main Stage OBS”) and participant_name (the tile label attendees see) are optional at create time. The stream_key is shown only in the create response and is never stored or retrievable afterwards. It stays valid until you delete the ingress or the room ends. If you lose it, delete the ingress and create a new one.

Prerequisites

  • A scheduled room id. Ingress endpoints hang off /api/v1/video/rooms-scheduled/{id}, the same surface as HLS/DASH egress and RTMP simulcast. Ad-hoc rooms are not supported.
  • A host-tier credential. Creating, listing, and deleting ingress requires an owner or admin role and an API key with the video:write scope. A key without that scope gets a 403.
  • An encoder. For RTMP: OBS Studio 27 or newer, vMix, any hardware RTMP encoder, or an IP camera with RTMP push. For WHIP: a WHIP-capable client such as Larix Broadcaster or OBS with a WHIP output, or a command-line WHIP publisher for scripted feeds.
  • A public source, for url ingress. The pull URL must be reachable from the public internet; private, loopback, and link-local addresses are rejected at validation.

Create an ingress

Store ingress_id (you need it for teardown) and copy stream_url and stream_key into your encoder before closing the response; the key cannot be fetched again. If the call fails:
  • 403 means the caller lacks the owner/admin role or the video:write scope.
  • 404 means the id is not a scheduled room in this tenant.
  • 422 means the body failed validation: url is only accepted with type: "url", must start with http(s):// or rtmp(s)://, and must be a public address.
  • 503 means the video media plane is not configured for your tenant yet.

Push from OBS over RTMP

  1. Create the ingress with "type": "rtmp" as above.
  2. In OBS, open Settings → Stream and set:
    • Service: Custom
    • Server: the stream_url from the create response
    • Stream key: the stream_key from the create response
  3. In Settings → Output, send H.264 video and AAC audio, constant bitrate, with a 2-second keyframe interval (4,500 to 6,000 kbps suits 1080p30). Orbit transcodes RTMP pushes by default (enable_transcoding defaults to true for RTMP), but a clean H.264+AAC input keeps quality up and re-encodes cheaper.
  4. Press Start Streaming.
Verify the feed landed:
  • OBS’s status dock shows a live bitrate and frame rate instead of “disconnected.”
  • The room gains a participant tile labelled with your participant_name.
  • GET /api/v1/video/rooms-scheduled/{id}/ingress (listVideoRoomsScheduledByIdIngress) lists the ingress with its id, type, and creation time, without ever echoing the key.
If OBS reports a connection refusal, re-check that the server field holds stream_url exactly (no trailing slash, no key appended) and that the key was copied from the same create response.

Push over WHIP

Create the ingress with "type": "whip". The response is the same shape; for WHIP clients the two values map to:
  • WHIP endpoint URL: stream_url
  • Authorization header: Bearer <stream_key>
Configure those in your WHIP client (Larix Broadcaster, an OBS WHIP output, or a scripted WHIP publisher) and start the broadcast. Because WHIP carries WebRTC media natively, enable_transcoding defaults to false and nothing is remuxed: expect glass-to-glass latency well under a second, where an RTMP push typically adds a few seconds of pipeline delay. Pick WHIP when the feed joins an interactive scene and lip-sync with WebRTC speakers matters; pick RTMP when the source is broadcast hardware that only speaks RTMP. You can set enable_transcoding explicitly on either type if your source deviates from those defaults.

Pull an existing source with url

When the feed already lives somewhere public (a partner’s HLS stream, a camera’s RTMP push URL, a DASH manifest), skip the encoder entirely:
Orbit’s media plane fetches the source and publishes it into the room; the create response still returns an ingress_id and participant_identity, but the stream_key is empty because there is nothing to authenticate on your side.

Mix ingress with interactive participants

Ingress and WebRTC participants coexist without configuration. Speakers, moderators, and panelists join with ordinary access tokens (see video room access tokens); the ingested source arrives as one more publisher. Because its identity starts with ingress_, host tools can single it out: spotlight it in a layout, feature it in the speaker composite, or leave it as a grid tile. Recordings, HLS/DASH egresses, and RTMP simulcast all include it exactly as they include human publishers. If the encoder stops pushing, the rest of the room is unaffected: speakers keep talking and egresses keep writing. The ingress tile stops updating and the participant eventually leaves the roster. The feed does not resume on its own; start the encoder again against the same stream_url and stream_key, or delete the ingress and create a fresh one. Ingress creation and teardown are recorded in the room’s activity trail, so video room history shows when each feed joined and left.

Teardown and explicit disconnect

Delete an ingress by handle when the feed is done:
The call returns 204 and is idempotent: deleting an already-deleted ingress is safe, so retry logic and double-clicks never error. GET /api/v1/video/rooms-scheduled/{id}/ingress lists what is still active (deleteVideoRoomsScheduledByIdIngressByIngressId removes one). When the room ends, any remaining ingresses are reaped with it. Tear ingresses down as soon as the feed is finished. A live ingress consumes media-plane capacity and, when paired with recording or egress, storage and bandwidth, until it stops.

Pair ingress with HLS/DASH distribution

A common topology for hybrid events: ingest the external feed with this guide, then serve the passive audience over HLS or DASH from your CDN while a handful of hosts stay interactive on WebRTC. The HLS/DASH egress guide covers the distribution half; the composite it broadcasts already includes your ingress source. If the destination is a third-party platform instead, use RTMP simulcast. When a feed misbehaves (frozen tile, audio drift, dropped frames), the diagnostics surface is the same as for any participant: video room media diagnostics reports per-participant bitrate, codec, and packet stats, and the ingress participant is listed there under its ingress_ identity.