From the Streaming CDN team. The original, kept up to date, is at streaming-cdn.ewin888.com/guides/obs-whip-webrtc-live-streaming.
WHIP (WebRTC-HTTP Ingestion Protocol) lets an encoder publish over WebRTC with a single HTTP request. OBS Studio supports it natively, so a stream can go from OBS to viewers' browsers over WebRTC end to end, in the low hundreds of milliseconds, instead of the several seconds that segment-based delivery such as HLS adds.
1. The publish URL
OBS publishes to your ingest domain, a publish point and a stream name:
https://<ingest-hostname>/<publish-point>/<stream-name>
# example
https://push.example.com/live/camera-01
- The publish point defaults to
/live; the value configured in the console is authoritative. - The stream name is the last path segment and is case-sensitive. Streams published at the same time on one ingest domain need different names.
- Viewers watch through a playback domain bound to the ingest domain the stream was published to.
2. Before you publish
- The ingest domain has active DNS and TLS.
- If source IP allowlisting is on, add the publisher's public egress IP (a private LAN address is not enough).
- If Stream Key authentication is on, create a key for this exact ingest domain. The secret is shown once.
- Use a current OBS Studio release that includes WHIP.
3. OBS settings
Open Settings → Stream and enter:
| OBS field | Value |
|---|---|
| Service | WHIP |
| Server | The full WHIP URL, including publish point and stream name |
| Bearer Token | The ingest domain's Stream Key (empty only when Stream Key authentication is off) |
OBS sends the Bearer Token as Authorization: Bearer <stream-key>. Treat Stream Keys as passwords: never put them in public URLs, screenshots, repositories or shared OBS profiles.
4. Recommended output for low latency
| Setting | Value | Why |
|---|---|---|
| Video encoder | H.264 (hardware or software) | Broad browser support |
| Rate control | CBR | Predictable bandwidth |
| 720p bitrate | 1.5–2.5 Mbps | Adjust for motion and source quality |
| 1080p bitrate | 3–6 Mbps | Adjust for motion and source quality |
| Keyframe interval | 1 second | Faster first frame and recovery |
| H.264 profile | Main or Baseline | Avoids unsupported decoder features |
| B-frames | 0 | Lower latency |
| Audio | Enabled, not muted | WHIP negotiates the audio track |
5. Check that it works
- OBS changes from Connecting to Live.
- The console's Live streams list shows the stream name with active tracks.
- Open
https://<playback-hostname>/<publish-point>/<stream-name>and check video and audio.
6. When it does not work
| Symptom | Likely cause | What to do |
|---|---|---|
401 invalid_stream_key |
Missing, expired, revoked or wrong-domain key | Create a key for the active ingest domain and paste it into Bearer Token |
403 publisher_ip_denied |
The publisher's public IP is not allowed | Add the real public egress IP, or turn the allowlist off while testing |
429 Too Many Requests |
A duplicate publisher, or a concurrency limit | Stop the old publisher or use a different stream name |
| OBS stays on Connecting | Firewall, outbound UDP/DTLS, DNS or TLS | Check DNS/TLS, allow outbound UDP, read the OBS log |
| Live with no picture | Hidden or muted source, incompatible output | Check the OBS preview and mixer; use H.264 and a one-second keyframe interval |
Publishing from a web page instead
A browser page can publish too: WHIP with fetch() and a send-only RTCPeerConnection. Because that request is cross-origin, list the page's origin under the ingest domain's browser publishing origins (CORS) in the console. Encoders such as OBS never ask for CORS and are unaffected.
Streaming CDN delivers live video to browsers over WebRTC, with chat and votes on real-time data channels, adaptive quality, recording and playback protection. Learn more.
Top comments (0)