Go live from OBS to the browser in under a second with WHIP
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.