RTMP Push
Native Frame can fan a single live stream out to YouTube as a second egress, alongside normal Native Frame playback. Configure a YouTube destination on a stream and it'll automatically receive the live feed when the stream goes live. You can enable or disable a destination without deleting it, so you can pre-stage configurations ahead of time.
Works for both new and existing streams. If you already have a stream running, you can add a YouTube destination without recreating it — see Add to an existing stream.
What you'll need
- A Native Frame stream (existing or new).
- A YouTube channel with live streaming enabled.
- A YouTube stream key from YouTube Studio (instructions below).
Choose what gets pushed: source only vs source + overlay
When you add a YouTube destination to a stream that has an overlay configured, you pick what Native Frame forwards to YouTube:
- Source + overlay (default) — the full broadcast as your viewers see it: primary camera feed with all on-air graphics (scoreboards, lower thirds, sponsor logos) composited on top. Pick this if you want your YouTube stream to mirror what viewers see.
- Source only — just the primary camera source with no overlay graphics. Pick this if YouTube needs the raw feed — for example, you apply separate graphics downstream, or you want a clean recording to re-cut later.
If you don't pick, Native Frame defaults to Source + overlay. You can change the choice later by editing the destination from the stream's RTMP Push tab (pencil icon).
The Stream content picker only appears when the stream actually has an overlay set up. For streams with no overlay, the only thing to push is the source, so the modal omits the picker. Adding an overlay later makes the picker appear on subsequent adds.
Step 1 — Get your YouTube stream key
You need a stream key from YouTube before configuring restreaming on the Native Frame side. The stream key is the credential YouTube uses to authenticate the incoming RTMP feed.
YouTube owns this part of the flow and updates their Studio UI from time to time, so follow YouTube's official guide:
→ Get started with live streaming (support.google.com)
That page covers enabling live streaming on your channel, opening the Live Control Room in YouTube Studio, and locating your stream key.
If your YouTube channel has never streamed before, YouTube enforces a one-time eligibility check that takes up to 24 hours to clear. Plan ahead — you'll only hit this once per channel.
Anyone with the key can broadcast to your YouTube channel. Native Frame stores it so we can forward to YouTube; we do not log it. Don't paste it into chat, screenshots, or shared documents. If a key leaks, rotate it on YouTube's side and paste the new value in.
Step 2 — Create a new stream with restream enabled
If you're starting from a brand-new stream:
-
From the Streams page, click + Create new stream.

-
Fill in Stream Name and pick an Authentication type (Public Stream or JWT) as you normally would.
-
Scroll down to the Stream Destinations section.

-
Paste your YouTube stream key into the Stream key field under YouTube Live.

-
Click Create Stream.
The stream is created with the YouTube destination already attached, defaulting to Source + overlay (when an overlay is configured). The destination receives the live feed as soon as the stream starts broadcasting.
Add or change restream on an existing stream
If the stream already exists, the RTMP Push tab is where you add, change, or remove destinations.
-
From the Streams page, click the stream's name to open its details.

-
Open the RTMP Push tab.

Add a new YouTube destination
Click + Add Destination. The Add New Stream Destination modal opens.

Fill in:
- Stream key — paste your YouTube Live stream key from Step 1.
- Stream content — pick Source + overlay (default, recommended) or Source only. (Only appears if the stream has an overlay configured.)
Click Add Destination to save. If the stream isn't currently broadcasting, the destination is in place for the next broadcast. If the stream IS currently broadcasting, the YouTube push opens within a few seconds — no need to restart the broadcaster.
Change an existing destination
To edit a destination — rotate the stream key, flip between Source + overlay and Source only, or both — click the pencil (✎) icon on the row. The Edit Destination modal opens.

Update the Stream key and/or the Stream content picker as needed and click Save.
For any destination change — adding, removing, toggling, rotating the key, or flipping Source / Source + overlay — the running YouTube push picks up the change on the next status sync (typically within a few seconds). You do not need to disconnect and reconnect the broadcaster.
Step 3 — Enable or disable a destination
Each destination on the RTMP Push tab has an Enabled toggle. Use it to temporarily turn off restreaming without deleting the configuration.

- Enabled (toggle blue): destination is forwarded to YouTube. If a broadcast is running, the push opens within a few seconds.
- Disabled (toggle gray): destination is preserved but skipped. If a broadcast is running, the push stops within a few seconds.

Common reasons to disable rather than delete:
- Pre-staging a destination ahead of an event without going live yet.
- Temporarily pausing restreams without losing the stream key.
- Cycling the restream off for a private rehearsal and back on for the public broadcast.
The toggle saves immediately — no separate Save button.
Step 4 — Remove a destination entirely
-
Open the RTMP Push tab on the stream.
-
Click the trash (🗑) icon on the destination row, or open the Edit Destination modal (pencil icon) and click Remove Destination.

The destination is deleted immediately. To add it back later, paste the YouTube stream key again.
Your stream key never changes
Adding, changing, enabling, disabling, or removing a YouTube destination does not change your Native Frame stream key. The stream key only carries your authentication credential; destination state is held server-side and applied by Native Frame's media layer when it sees a configuration change.
- No re-copying. Configure once in your encoder, change destinations freely afterwards.
- Changes propagate to the running broadcast within seconds. Native Frame's media orchestration polls the program service on a short cycle and reconciles the YouTube push connections as destinations are added, removed, toggled, or re-keyed — no broadcaster restart required.
Limits
- Up to 10 destinations per stream.
- YouTube is the only supported destination type in this release. Support for additional platforms will arrive in future updates.
Program API reference
Everything the dashboard does is backed by the Program Service HTTP API — see the Program API reference (the Streams section under Program). Use these if you'd rather drive restream configuration from your own backend.
Authentication: every endpoint requires a Bearer JWT in the Authorization header whose audience/role includes service-account; the projectID claim scopes the operation (you don't pass projectID in the body). The target stream must belong to the token's project, or the server returns 403.
The RtmpPushDestination shape
{
"type": "yt",
"key": "abcd-efgh-ijkl-mnop-qrst",
"enabled": true
}
| Field | Type | Required | Notes |
|---|---|---|---|
type | string enum | yes | Only "yt" is supported in this release. |
key | string | yes | The destination credential — for YouTube, the stream key from YouTube Studio. Treat as a secret. |
enabled | boolean | yes | Whether this destination is included when the stream goes live. Disabled destinations are stored but skipped. |
Maximum 10 destinations per stream; over-the-cap requests return 400.
Source vs source + overlay at the API layer
The Source + overlay vs Source only choice is realized by which stream carries the destination row. A stream has a kind field:
kind: "source"— the raw camera source. Patch destinations here for Source only.kind: "filtergraph"— a composition derived from a source (derivedFromIdpoints at the source). Patch destinations here for Source + overlay.
Find a source's filtergraph siblings with GET /program/api/v2/streams?derivedFromId={sourceStreamId} and pick the entry whose kind is "filtergraph".
A single (type, key) can be enabled: true on at most one stream in a given source/derivation family. Enabling the same YouTube key on both the source and its filtergraph derivation returns 409 Conflict. To move a key from one to the other atomically, use the bulk endpoint.
Reconcile destinations on a stream — PATCH /program/api/v2/streams/{id}/rtmp-push
Declarative reconcile: the request body is the complete desired set of destinations. The server upserts every entry, applies each enabled value as-is, and deletes any stored destination not present in the request. Idempotent.
{
"destinations": [
{ "type": "yt", "key": "abcd-efgh-ijkl-mnop-qrst", "enabled": true }
]
}
- Disable without deleting: send the same entry with
"enabled": false. - Remove everything: send
{ "destinations": [] }.
Response 200 OK echoes the post-reconcile rtmpPush array.
Move a destination across sibling streams — POST /program/api/v2/streams/rtmp-push-bulk
Reconciles destinations across multiple streams in a single transaction — use it for the source ↔ overlay swap (clear the key on one stream and set it on its sibling) with no intermediate 409.
{
"streams": [
{ "streamID": "<source-id>", "destinations": [] },
{ "streamID": "<overlay-id>", "destinations": [
{ "type": "yt", "key": "abcd-efgh-ijkl-mnop-qrst", "enabled": true }
]
}
]
}
Either every per-stream reconcile commits or none do.
Read current destination state — GET /program/api/v2/streams/{id}
Returns the full stream; the rtmpPush field carries the current destination list. Keys are returned in plaintext on read — the dashboard masks them in its UI, but the API returns the stored value. Treat the response as containing secrets.
Status codes
| Code | Meaning |
|---|---|
200 / 201 | Success. |
400 | Validation error — unknown type, missing key, exceeded 10-destination cap, malformed body, or (bulk) empty streams / duplicate streamID. |
401 | Missing or invalid JWT. |
403 | Stream belongs to a different project than the token's projectID. |
404 | Stream not found. |
409 | Sibling-stream collision — the (type, key) would be enabled on more than one stream in the same source/derivation family. |
500 | Internal error — retry-safe (writes are idempotent). |
- Changes propagate to running broadcasts within seconds — the broker reconciles YouTube push connections on its next status-sync cycle.
- The assembled
streamKeydoes not change when destinations change; encoders configured once stay valid. rtmpPushis persisted on the stream, not the broadcast session — destinations survive reconnects and restarts.