RFC 9725

WebRTC-HTTP Ingestion Protocol (WHIP)

πŸ“… published March 2025, from ietf

RFC 9725 Β· Part 1 of 7 πŸ’–

WebRTC-HTTP Ingestion Protocol (WHIP) πŸŽ€

okay bestie, let's get the title block sorted first πŸ‘€

  • RFC number: 9725 πŸ¦‹
  • Authors: S. Garcia Murillo (Millicast) and A. Gouaillard (CoSMo Software) πŸ‘‘
  • Category: Standards Track ✨
  • Date: March 2025 🌸
  • ISSN: 2070-1721
  • Publisher: Internet Engineering Task Force (IETF)
  • Updates: RFCs 8840 and 8842 πŸ’…
  • Obsoletes: nothing listed in the title block 🧚

Abstract ✨

so this doc describes a simple HTTP-based protocol that lets WebRTC-based ingestion of content into streaming services and/or Content Delivery Networks (CDNs) actually happen. it's giving streamlined 🌈

This document updates RFCs 8840 and 8842. 🫢

Status of This Memo πŸ“œ

this is an Internet Standards Track document, periodt πŸ’…

it's a product of the Internet Engineering Task Force (IETF). it represents the consensus of the IETF community, and it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check out Section 2 of RFC 7841 πŸ”

info about the current status of this doc, any errata, and how to give feedback is at https://www.rfc-editor.org/info/rfc9725 πŸ“¬

Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. πŸ”’

this document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as in effect on the date of publication. please actually read these, because they spell out your rights and restrictions with respect to this document, no skipping πŸ™ˆ

also, Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Revised BSD License βš–οΈ

Table of Contents πŸ—‚οΈ

   1.  Introduction
   2.  Terminology
   3.  Overview
   4.  Protocol Operation
     4.1.  HTTP Usage
     4.2.  Ingest Session Setup
     4.3.  ICE Support
       4.3.1.  HTTP PATCH Request Usage
       4.3.2.  Trickle ICE
       4.3.3.  ICE Restarts
     4.4.  WebRTC Constraints
       4.4.1.  SDP Bundle
       4.4.2.  Single MediaStream
       4.4.3.  No Partially Successful Answers
       4.4.4.  DTLS Setup Role and SDP "setup" Attribute
       4.4.5.  Trickle ICE and ICE Restarts
     4.5.  Load Balancing and Redirections
     4.6.  STUN/TURN Server Configuration
       4.6.1.  Congestion Control
     4.7.  Authentication and Authorization
       4.7.1.  Bearer Token Authentication
     4.8.  Simulcast and Scalable Video Coding
     4.9.  Protocol Extensions
   5.  Security Considerations
   6.  IANA Considerations
     6.1.  Link Relation Type: ice-server
     6.2.  URN Sub-namespace for WHIP (urn:ietf:params:whip)
     6.3.  WebRTC-HTTP Ingestion Protocol (WHIP) URNs Registry
     6.4.  WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs
           Registry
     6.5.  Registering WHIP URNs and WHIP Extension URNs
       6.5.1.  Registration Procedure
       6.5.2.  Guidance for the Designated Expert
       6.5.3.  Registration Template
   7.  References
     7.1.  Normative References
     7.2.  Informative References
   Acknowledgements
   Authors' Addresses

1. Introduction ✨

okay so the IETF RTCWEB Working Group standardized the JavaScript Session Establishment Protocol (JSEP) [RFC9429], which handles the setup, management, and teardown of a multimedia session 🎬 it also covers how to negotiate media flows with the offer/answer model using the Session Description Protocol (SDP) [RFC3264], including the formats for data sent over the wire (like media types, codec parameters, and encryption). the tea is that WebRTC intentionally does not specify a signaling transport protocol at the application level πŸ«–

the catch: not having a standardized signaling mechanism has kept WebRTC from being adopted as an ingestion protocol in the broadcast and streaming industry πŸ“Ί that world takes a streamlined production pipeline for granted. for example, cables carrying raw media to hardware encoders get plugged in, and then the encoded media gets pushed to any streaming service or Content Delivery Network (CDN) using an ingestion protocol πŸ”Œ

WebRTC can work with standard signaling protocols like SIP [RFC3261] or Extensible Messaging and Presence Protocol (XMPP) [RFC6120], but those aren't designed for broadcasting and streaming services, and there's no sign of adoption in that industry either πŸ™ƒ the Real-Time Streaming Protocol (RTSP) [RFC7826] is based on RTP, but it doesn't support the SDP offer/answer model [RFC3264] for negotiating the characteristics of the media session 😬

so this document proposes a simple HTTP-based protocol that supports WebRTC as a media ingestion method. it is:

  • easy to implement πŸ’…
  • as easy to use as popular IP-based broadcast protocols πŸ“‘
  • fully compliant with WebRTC and RTCWEB specs βœ…
  • enabling ingestion on both classical media platforms and WebRTC end-to-end platforms, achieving the lowest possible latency ⚑
  • lowering the requirements on both hardware encoders and broadcasting services to support WebRTC πŸ“
  • usable in both web browsers and standalone encoders 🌸

2. Terminology πŸ“š

ok the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. πŸ”₯ so if you don't see them in caps, they're just regular words, no drama πŸ’œ

3. Overview πŸ¦‹

the WebRTC-HTTP Ingestion Protocol (WHIP) is designed to facilitate a one-time exchange of Session Description Protocol (SDP) offers and answers using HTTP POST requests πŸ“¨ this exchange is a fundamental step in establishing an Interactive Connectivity Establishment (ICE) and Datagram Transport Layer Security (DTLS) session between the WHIP client (the encoder or media producer) and the media server (the broadcasting ingestion endpoint) 🀝

once the ICE/DTLS session is up, unidirectional media data starts flowing from the WHIP client to the media server πŸŽ₯ important bit: SDP renegotiations are not supported in WHIP. that means no changes to the m= sections after the initial SDP offer/answer exchange over HTTP POST is done, and only ICE-related info can be updated via HTTP PATCH requests as defined in Section 4.3 πŸ™…β€β™€οΈ

here's the diagram for the core operation of WHIP when starting and ending an ingest session πŸ‘‡

 +-------------+    +---------------+ +--------------+ +---------------+
 | WHIP client |    | WHIP endpoint | | Media server | | WHIP session  |
 +--+----------+    +---------+-----+ +------+-------+ +--------|------+
    |                         |              |                  |
    |                         |              |                  |
    |HTTP POST (SDP offer)    |              |                  |
    +------------------------>+              |                  |
    |201 Created (SDP answer) |              |                  |
    +<------------------------+              |                  |
    |          ICE/STUN REQUEST              |                  |
    +--------------------------------------->+                  |
    |          ICE/STUN RESPONSE             |                  |
    |<---------------------------------------+                  |
    |          DTLS SETUP                    |                  |
    |<======================================>|                  |
    |          RTP/RTCP FLOW                 |                  |
    +<-------------------------------------->+                  |
    | HTTP DELETE                                               |
    +---------------------------------------------------------->+
    | 200 OK                                                    |
    <-----------------------------------------------------------x

               Figure 1: WHIP Session Setup and Teardown

the elements in Figure 1 are:

  • WHIP client: the WebRTC media encoder or producer. it's the WHIP client because it encodes media and delivers it to a remote media server πŸŽ€
  • WHIP endpoint: the ingest server that receives the initial WHIP request πŸšͺ
  • WHIP endpoint URL: the URL of the WHIP endpoint that's responsible for creating the WHIP session πŸ”—
  • Media server: the WebRTC media server (or consumer) that's responsible for establishing the media session with the WHIP client and receiving the media content it produces 🎞️
  • WHIP session: the server handling the HTTP resource the WHIP endpoint allocated for an ongoing ingest session 🧚
  • WHIP session URL: the URL of the WHIP resource the WHIP endpoint allocated for a specific media session. to modify the session (like ICE operations or terminating it), the WHIP client can send requests to the WHIP session using this URL πŸ› οΈ

Figure 1 shows the communication flow between a WHIP client, WHIP endpoint, media server, and WHIP session ✨ this flow is the whole setup-and-teardown process for an ingest session. it involves negotiation, ICE for Network Address Translation (NAT) traversal, DTLS and the Secure Real-time Transport Protocol (SRTP) for security, and RTP/RTCP for media transport πŸ” step by step:

  • the WHIP client kicks things off by sending an HTTP POST with an SDP offer to the WHIP endpoint πŸš€
  • the WHIP endpoint replies with a "201 Created" message containing an SDP answer πŸ’Œ
  • the WHIP client and media server establish ICE and DTLS sessions for NAT traversal and secure communication 🀝
  • RTP and RTCP flows get set up for media transmission from the WHIP client to the media server, secured by the SRTP profile 🎢
  • the WHIP client sends an HTTP DELETE to terminate the WHIP session πŸ‘‹
  • the WHIP session responds with a "200 OK" to confirm the termination πŸ’–

4. Protocol Operation βš™οΈ

4.1. HTTP Usage 🌐

okay this part is about errors and GET requests, so pay attention πŸ‘€

following the guidelines in [BCP56], WHIP clients MUST NOT match error codes returned by the WHIP endpoints and resources to a specific error cause indicated in this specification. πŸ™…β€β™€οΈ WHIP clients MUST be able to handle all applicable status codes by gracefully falling back to the generic n00 semantics of a given status code on unknown error codes πŸ›Ÿ WHIP endpoints and resources could convey finer-grained error information by a problem details JSON object in the response message body of the failed request, as per [RFC9457] 🧾

the WHIP endpoints and sessions are origin servers as defined in Section 3.6 of [RFC9110]. they handle the requests and provide responses for the underlying HTTP resources. those HTTP resources don't have any representation defined in this specification, so the WHIP endpoints and sessions MUST return a 2xx successful response with no content when a GET request is received. 🫢

4.2. Ingest Session Setup πŸŽ€

okay bestie, setting up an ingest session is the main event πŸ’– First, the WHIP client MUST generate an SDP offer following the JSEP rules for an initial offer (see Section 5.2.1 of [RFC9429]). Then it sends an HTTP POST request (as per Section 9.3.3 of [RFC9110]) to the configured WHIP endpoint URL ✨

The HTTP POST request MUST have a content type of application/sdp, and it carries the SDP offer as the body. Then the WHIP endpoint MUST generate an SDP answer using the JSEP rules for an initial answer (see Section 5.3.1 of [RFC9429]) πŸ¦‹ It sends back a 201 Created response with a content type of application/sdp, the SDP answer as the body, and a Location header field pointing to the brand new WHIP session.

But if the POST has a content type that isn't application/sdp, or the SDP is malformed, the WHIP endpoint MUST reject the HTTP POST request with an appropriate 4xx error response πŸ™…β€β™€οΈ

Since WHIP only does ingestion with unidirectional media, the WHIP client SHOULD use the sendonly attribute in the SDP offer. It MAY use sendrecv instead, but inactive and recvonly MUST NOT be used. The WHIP endpoint MUST use recvonly in the SDP answer 🌸

Figure 2 shows an HTTP POST from a WHIP client to a WHIP endpoint, plus the 201 Created response with the Location header pointing to the new WHIP session. Serving looks ✨

   POST /whip/endpoint HTTP/1.1
   Host: whip.example.com
   Content-Type: application/sdp
   Content-Length: 1101

   v=0
   o=- 5228595038118931041 2 IN IP4 127.0.0.1
   s=-
   t=0 0
   a=group:BUNDLE 0 1
   a=extmap-allow-mixed
   a=ice-options:trickle ice2
   m=audio 9 UDP/TLS/RTP/SAVPF 111
   c=IN IP4 0.0.0.0
   a=rtcp:9 IN IP4 0.0.0.0
   a=ice-ufrag:EsAw
   a=ice-pwd:bP+XJMM09aR8AiX1jdukzR6Y
   a=fingerprint:sha-256 DA:7B:57:DC:28:CE:04:4F:31:79:85:C4:31:67:EB:
      27:58:29:ED:77:2A:0D:24:AE:ED:AD:30:BC:BD:F1:9C:02
   a=setup:actpass
   a=mid:0
   a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
   a=sendonly
   a=msid:d46fb922-d52a-4e9c-aa87-444eadc1521b ce326ecf-a081-453a-8f9f-
      0605d5ef4128
   a=rtcp-mux
   a=rtcp-mux-only
   a=rtpmap:111 opus/48000/2
   a=fmtp:111 minptime=10;useinbandfec=1
   m=video 0 UDP/TLS/RTP/SAVPF 96 97
   a=mid:1
   a=bundle-only
   a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
   a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
   a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
   a=sendonly
   a=msid:d46fb922-d52a-4e9c-aa87-444eadc1521b 3956b460-40f4-4d05-acef-
      03abcdd8c6fd
   a=rtpmap:96 VP8/90000
   a=rtcp-fb:96 ccm fir
   a=rtcp-fb:96 nack
   a=rtcp-fb:96 nack pli
   a=rtpmap:97 rtx/90000
   a=fmtp:97 apt=96

   HTTP/1.1 201 Created
   ETag: "xyzzy"
   Content-Type: application/sdp
   Content-Length: 1053
   Location: https://whip.example.com/session/id

   v=0
   o=- 1657793490019 1 IN IP4 127.0.0.1
   s=-
   t=0 0
   a=group:BUNDLE 0 1
   a=extmap-allow-mixed
   a=ice-lite
   a=ice-options:trickle ice2
   m=audio 9 UDP/TLS/RTP/SAVPF 111
   c=IN IP4 0.0.0.0
   a=rtcp:9 IN IP4 0.0.0.0
   a=ice-ufrag:38sdf4fdsf54
   a=ice-pwd:2e13dde17c1cb009202f627fab90cbec358d766d049c9697
   a=fingerprint:sha-256 F7:EB:F3:3E:AC:D2:EA:A7:C1:EC:79:D9:B3:8A:35:
      DA:70:86:4F:46:D9:2D:CC:D0:BC:81:9F:67:EF:34:2E:BD
   a=candidate:1 1 UDP 2130706431 198.51.100.1 39132 typ host
   a=setup:passive
   a=mid:0
   a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
   a=recvonly
   a=rtcp-mux
   a=rtcp-mux-only
   a=rtpmap:111 opus/48000/2
   a=fmtp:111 minptime=10;useinbandfec=1
   m=video 0 UDP/TLS/RTP/SAVPF 96 97
   c=IN IP4 0.0.0.0
   a=mid:1
   a=bundle-only
   a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
   a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
   a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
   a=recvonly
   a=rtpmap:96 VP8/90000
   a=rtcp-fb:96 ccm fir
   a=rtcp-fb:96 nack
   a=rtcp-fb:96 nack pli
   a=rtpmap:97 rtx/90000
   a=fmtp:97 apt=96
       Figure 2: Example of the SDP Offer/Answer Exchange Done via an
                                 HTTP POST

Once the session is up, consent freshness (per [RFC7675]) SHALL be used to detect non-graceful disconnection by full ICE implementations, and DTLS teardown handles session termination by either side πŸ”₯

To end a WHIP session on purpose, the WHIP client MUST send an HTTP DELETE request to the WHIP session URL that came back in the Location header field of the original HTTP POST 🧹 Once the DELETE lands, the WHIP session gets removed and its resources are freed on the media server, which also tears down the ICE and DTLS sessions πŸ’…

A media server ending a session MUST follow the procedures in Section 5.2 of [RFC7675] for immediate revocation of consent πŸ™ˆ

The WHIP endpoints MUST support OPTIONS requests for Cross-Origin Resource Sharing (CORS) as defined in [FETCH]. The 200 OK response to any OPTIONS request SHOULD include an Accept-Post header with a media type value of application/sdp (as per [W3C.REC-ldp-20150226]) 🌈


4.3. ICE Support 🧊

ICE [RFC8445] is the protocol that handles the messy business of NAT traversal. NATs get in the way of direct communication between devices on different local networks, which is a real problem for real-time apps 😭 ICE makes connectivity feel seamless by finding and negotiating efficient communication paths 🫢

Trickle ICE [RFC8838] is the glow-up here. It shares potential communication paths bit by bit instead of all at once, which cuts down latency and gets you connected faster ⚑

ICE restarts are clutch when the network gets wobbly or disrupted. They let devices re-establish communication paths without a full renegotiation, so latency stays low and real-time comms stay reliable πŸ’œ

Trickle ICE and ICE restart support are RECOMMENDED for both WHIP sessions and clients ✨

4.3.1. HTTP PATCH Request Usage 🩹

The WHIP client MAY perform Trickle ICE or ICE restarts by sending an HTTP PATCH request (as per [RFC5789]) to the WHIP session URL. That HTTP PATCH request MUST contain a body with an SDP fragment whose media type is application/trickle-ice-sdpfrag, as specified in [RFC8840], which carries the relevant ICE information 🧚 If the HTTP PATCH request sent to the WHIP session URL has a content type other than application/trickle-ice-sdpfrag, or the SDP fragment is malformed, the WHIP session MUST reject the HTTP PATCH with an appropriate 4xx error response.

If the WHIP session supports either Trickle ICE or ICE restarts, but not both, it MUST return a 422 Unprocessable Content error response for the HTTP PATCH requests that aren't supported (see Section 15.5.21 of [RFC9110]) πŸ™…β€β™€οΈ

The WHIP client MAY send overlapping HTTP PATCH requests to one WHIP session. Because of that, the WHIP session may receive those PATCH requests out of order πŸ˜΅β€πŸ’« So if the WHIP session supports ICE restarts, it MUST generate a unique strong entity-tag that identifies the ICE session (as per Section 8.8.3 of [RFC9110]). The initial value of the entity-tag for the initial ICE session MUST be returned in an ETag header field in the 201 Created response to the initial POST request to the WHIP endpoint πŸ”‘

WHIP clients SHOULD NOT use entity-tag validation when matching a specific ICE session isn't required, for example when sending a DELETE request to terminate a session. WHIP sessions MUST ignore any entity-tag value sent by the WHIP client when ICE session matching isn't required, such as in the HTTP DELETE request 🧼

Missing or outdated ETags in PATCH requests from WHIP clients will be answered by WHIP sessions as per Section 13.1.1 of [RFC9110] and Section 3 of [RFC6585]. A missing entity-tag gets a 428 Precondition Required response, and a non-matching entity-tag gets a 412 Precondition Failed response 🌸

4.3.2. Trickle ICE ✨

Okay so with Trickle ICE, the WHIP client gets a choice about its first offer πŸ’… The initial offer MAY be sent after the full ICE gathering is done, with the complete list of ICE candidates. Or it MAY only include local candidates (or even an empty list!) as per [RFC8445]. To speed up setup πŸƒβ€β™€οΈ, when using Trickle ICE the WHIP client SHOULD send the SDP offer (with either locally gathered candidates or an empty list) as soon as possible.

To keep things simple 🫢, the WHIP session cannot signal extra ICE candidates to the WHIP client after the SDP answer has been sent. The WHIP endpoint SHALL gather all the ICE candidates for the media server before responding to the client's request, and the SDP answer SHALL contain the full list of ICE candidates of the media server.

Here's the tricky bit πŸ™ˆ. The WHIP client needs the WHIP session URL for the ICE session so it can send a PATCH request with new ICE candidates. That means it MUST wait and buffer any candidates it gathers until the "201 Created" HTTP response to the initial POST request arrives. To cut down on HTTP traffic and processing time, the WHIP client SHOULD send a single aggregated HTTP PATCH request with all the buffered ICE candidates once that response comes back. And if the WHIP session supports ICE restarts, the client also needs the entity-tag for the ICE session to send a PATCH request with new candidates. So it MUST also wait and buffer any gathered candidates until it receives the HTTP response carrying the new entity-tag value for the last PATCH request that performed an ICE restart.

WHIP clients building the HTTP PATCH body with the SDP fragment, and WHIP sessions processing it, MUST follow the guidelines in Section 4.4 of [RFC8840] with the following extra considerations:

  • As per [RFC9429], only "m=" sections not marked as bundle-only can gather ICE candidates. So since the "max-bundle" policy is in use, the SDP fragment will contain only the offerer-tagged "m=" line of the bundle group.
  • The WHIP client MAY exclude ICE candidates from the HTTP PATCH body if the WHIP session has already confirmed them with a successful HTTP response to a previous HTTP PATCH request.

WHIP sessions and clients that support Trickle ICE MUST make use of entity-tags and conditional requests, as explained in Section 4.3.1. Ooh, this part matters a lot πŸ”₯.

When a WHIP session gets a PATCH request that adds new ICE candidates without doing an ICE restart, it MUST return a "204 No Content" response with no body, and it MUST NOT include an ETag header in that response. If the WHIP session doesn't support a candidate's transport, or it can't resolve the connection address, it MUST silently discard that candidate and keep processing the rest of the request normally. Not me being chill about this πŸ’€.

Figure 3 shows a Trickle ICE example πŸ¦‹. The WHIP client sends a PATCH request with updated ICE candidate info, and the WHIP session replies with a successful response.

PATCH /session/id HTTP/1.1
Host: whip.example.com
If-Match: "xyzzy"
Content-Type: application/trickle-ice-sdpfrag
Content-Length: 576

a=group:BUNDLE 0 1
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:0
a=ice-ufrag:EsAw
a=ice-pwd:P2uYro0UCOQ4zxjKXaWCBui1
a=candidate:1387637174 1 udp 2122260223 192.0.2.1 61764 typ host
   generation 0 ufrag EsAw network-id 1
a=candidate:3471623853 1 udp 2122194687 198.51.100.2 61765 typ host
   generation 0 ufrag EsAw network-id 2
a=candidate:473322822 1 tcp 1518280447 192.0.2.1 9 typ host tcptype
   active generation 0 ufrag EsAw network-id 1
a=candidate:2154773085 1 tcp 1518214911 198.51.100.2 9 typ host
   tcptype active generation 0 ufrag EsAw network-id 2
a=end-of-candidates

HTTP/1.1 204 No Content

Figure 3: Example of a Trickle ICE Request and Response

4.3.3. ICE Restarts ♻️

As defined in [RFC8839], an ICE restart kicks off a new SDP offer/answer exchange. But WHIP doesn't support renegotiating non-ICE-related SDP info. So a WHIP client won't send a new offer when an ICE restart happens. Instead, the WHIP client and WHIP session only swap the relevant ICE info through an HTTP PATCH request, as defined in Section 4.3.1. They MUST assume that the previously negotiated non-ICE-related SDP information still applies after the ICE restart. Main character energy πŸ‘‘.

When doing an ICE restart, the WHIP client MUST include the updated "ice-pwd" and "ice-ufrag" in the SDP fragment of the HTTP PATCH request body, along with the new set of gathered ICE candidates, as defined in [RFC8840]. Same deal as Section 4.3.2: as per [RFC9429], only "m=" sections not marked as bundle-only can gather ICE candidates, so with the "max-bundle" policy in use, the SDP fragment will contain only the offerer-tagged "m=" line of the bundle group. A WHIP client sending a PATCH request to perform an ICE restart MUST contain an If-Match header field with a field-value of "*", as per Section 13.1.1 of [RFC9110].

[RFC8840] says an agent MUST discard any received requests containing "ice-pwd" and "ice-ufrag" attributes that don't match the current ICE Negotiation Session. But a WHIP session that receives updated "ice-pwd" and "ice-ufrag" attributes MUST treat the request as an ICE restart instead. If it's supported, the WHIP session SHALL return a "200 OK" with an "application/trickle-ice-sdpfrag" body, containing the new ICE username fragment and password, plus a new set of ICE candidates for the WHIP session. Also, the "200 OK" response for a successful ICE restart MUST contain the new entity-tag for the new ICE session in an ETag response header field, and it MAY contain a new set of ICE candidates for the media server. Slay πŸ’–.

As defined in Section 4.4.1.1.1 of [RFC8839], the candidates after an ICE restart may include some, none, or all of the previous candidates for that data stream, or a totally new set. So after a successful ICE restart, both the WHIP client and the WHIP session MUST replace the previous set of remote candidates with the new set exchanged in the HTTP PATCH request and response. Any remote ICE candidate that isn't in the new set gets discarded. Both the WHIP client and the WHIP session MUST also make sure the HTTP PATCH request and response bodies include the same "ice-options," "ice-pacing," and "ice-lite" attributes as those used in the SDP offer or answer.

If the WHIP session can't satisfy the ICE restart request, the resource MUST return an appropriate HTTP error code, and it MUST NOT terminate the session right away. It keeps the existing ICE session instead. The WHIP client MAY retry the ICE restart, or it can end the session by sending an HTTP DELETE request instead. Either way, the session MUST be terminated if ICE consent expires as a result of the failed ICE restart, as per Section 5.1 of [RFC7675]. Yikes, that's a hard stop 😭.

Under unstable network conditions, ICE restart HTTP PATCH requests and responses might arrive out of order. To handle that, when the client performs an ICE restart, it MUST discard any previous ICE username fragment and password, and ignore any further HTTP PATCH response from a pending HTTP PATCH request. WHIP clients MUST apply only the ICE information from the response to the last request they sent. If the ICE info at the WHIP client doesn't match the info at the WHIP session (because a request arrived out of order), the Session Traversal Utilities for NAT (STUN) requests will carry invalid ICE information and get dropped by the receiving side. If the WHIP client notices this situation, it MUST send a new ICE restart request to the server.

Figure 4 shows a Trickle ICE restart example 🌸. The WHIP client sends a PATCH request with updated ICE info, including a new username fragment and password, plus newly gathered ICE candidates. In response, the WHIP session gives back the ICE info for the session after the restart, including the updated username fragment and password, as well as the previous ICE candidates.

PATCH /session/id HTTP/1.1
Host: whip.example.com
If-Match: "*"
Content-Type: application/trickle-ice-sdpfrag
Content-Length: 82

a=ice-options:trickle ice2
a=group:BUNDLE 0 1
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:0
a=ice-ufrag:ysXw
a=ice-pwd:vw5LmwG4y/e6dPP/zAP9Gp5k
a=candidate:1387637174 1 udp 2122260223 192.0.2.1 61764 typ host
   generation 0 ufrag EsAw network-id 1
a=candidate:3471623853 1 udp 2122194687 198.51.100.2 61765 typ host
   generation 0 ufrag EsAw network-id 2
a=candidate:473322822 1 tcp 1518280447 192.0.2.1 9 typ host tcptype
   active generation 0 ufrag EsAw network-id 1
a=candidate:2154773085 1 tcp 1518214911 198.51.100.2 9 typ host
   tcptype active generation 0 ufrag EsAw network-id 2

HTTP/1.1 200 OK
ETag: "abccd"
Content-Type: application/trickle-ice-sdpfrag
Content-Length: 252

a=ice-lite
a=ice-options:trickle ice2
a=group:BUNDLE 0 1
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=mid:0
a=ice-ufrag:289b31b754eaa438
a=ice-pwd:0b66f472495ef0ccac7bda653ab6be49ea13114472a5d10a
a=candidate:1 1 udp 2130706431 198.51.100.1 39132 typ host
a=end-of-candidates

Figure 4: Example of an ICE Restart Request and Response

4.4. WebRTC Constraints πŸŽ€

To keep WHIP simple to implement in both clients and media servers, WHIP puts specific restrictions on WebRTC usage. The following subsections explain these restrictions in detail.

4.4.1. SDP Bundle 🧚

Both the WHIP client and the WHIP endpoint SHALL support [RFC9143] and use the "max-bundle" policy defined in [RFC9429]. The WHIP client and the media server MUST support multiplexed media associated with the BUNDLE group, as per Section 9 of [RFC9143]. On top of that, per [RFC9143], the WHIP client and media server SHALL use RTP/RTCP multiplexing for all bundled media. To cut down on the network resources the media server needs, both the WHIP client and the WHIP endpoint MUST include the "rtcp-mux-only" attribute in each bundled "m=" section, as per Section 3 of [RFC8858]. Bundle bestie energy 🫧.

4.4.2. Single MediaStream 🌈

WHIP only supports a single MediaStream, as defined in [RFC8830], so every "m=" section MUST contain a "msid" attribute with the same value. The MediaStream MUST contain at least one MediaStreamTrack of any media kind, and it MUST NOT have two or more MediaStreamTracks for the same media (audio or video). It's possible future revisions of this spec will allow more than one MediaStream or more than one MediaStreamTrack of each kind. So for forward compatibility, if the WHIP endpoint doesn't support the number of audio and/or video MediaStreamTracks, or the number of MediaStreams, it MUST reject the HTTP POST request with a "422 Unprocessable Content" or "400 Bad Request" error response. The WHIP endpoint MAY also return a problem statement with further error details about the failed request, as recommended in Section 4.1. πŸ“

4.4.3. No Partially Successful Answers πŸ™ˆ

Okay so bestie, this is a big one. πŸ’… The WHIP endpoint SHOULD NOT reject individual m= sections (see Section 5.3.1 of [RFC9429]) when something goes wrong while it's processing one of them. Instead, it SHOULD reject the whole HTTP POST request with a 422 Unprocessable Content or 400 Bad Request error response. Why? 😭 Because a half-working ingest session is super misleading for end users, and nobody wants that drama. ✨ The WHIP endpoint MAY also send back a problem statement, as recommended in Section 4.1, to spill the tea on the error details. 🫢

4.4.4. DTLS Setup Role and SDP "setup" Attribute πŸŽ€

Here's the vibe: when a WHIP client sends an SDP offer, it SHOULD add an SDP setup attribute with the value actpass, as defined in [RFC8842]. 🌸 BUT, if the WHIP client only does the DTLS client role, it MAY use the setup attribute with the value active instead. 🧚 And if the WHIP endpoint doesn't support an SDP offer with active, it SHOULD reject the request with a 422 Unprocessable Content or 400 Bad Request error response. πŸ’€

NOTE: [RFC8842] says the offerer must insert a setup attribute with actpass. πŸ€“ However, the WHIP client always talks to a media server that's expected to do the DTLS server role, so the client might decide to only support the DTLS client role. Makes total sense, right? πŸ’–

4.4.5. Trickle ICE and ICE Restarts πŸ¦‹

The media server SHOULD support full ICE, unless it's connected to the Internet with an IP address that every authorized WHIP client can reach. In that case, it MAY support only ICE lite. ✨ The WHIP client MUST implement and use full ICE. No cap. πŸ”₯

Trickle ICE and ICE restart support is OPTIONAL for both WHIP clients and media servers, as explained in Section 4.3. 🌈

4.5. Load Balancing and Redirections πŸ“

Okay, so WHIP endpoints and media servers might not live on the same server, which means it's totally possible to load balance incoming requests across different media servers. πŸ‘‘

WHIP clients SHALL support HTTP redirections as per Section 15.4 of [RFC9110]. πŸ’… But here's the tea: to keep POST requests from getting redirected as GET requests, the status codes 301 Moved Permanently and 302 Found MUST NOT be used. πŸ™ˆ The preferred way to load balance is the 307 Temporary Redirect status code, as described in Section 15.4.8 of [RFC9110]. πŸ¦‹ Redirections don't have to be supported for PATCH and DELETE requests, bestie. πŸ’œ

In case of high load, WHIP endpoints MAY return a 503 Service Unavailable response. This tells the client the server can't handle the request right now because of a temporary overload or scheduled maintenance (see Section 15.6.4 of [RFC9110]), and it'll likely get better after some delay. ⭐ The WHIP endpoint might also send a Retry-After header field, which says the minimum time the user agent ought to wait before making a follow-up request (see Section 10.2.3 of [RFC9110]). ⏳

4.6. STUN/TURN Server Configuration πŸ§šβ€β™€οΈ

The WHIP endpoint MAY return STUN/TURN server configuration URLs and credentials that the client can use, in the 201 Created response to the HTTP POST request to the WHIP endpoint URL. πŸŽ€

Each STUN/TURN server gets referenced using the Link header field ([RFC8288]) with a rel attribute value of ice-server. The Link target URI is the server URI defined in [RFC7064] and [RFC7065]. The credentials are encoded in the Link target attributes like this:

  • username: If the Link header field represents a Traversal Using Relays around NAT (TURN) server, this attribute specifies the username to use with that TURN server. 🫢
  • credential: This attribute is a long-term authentication password, as described in Section 9.2 of [RFC8489]. πŸ”

Figure 5 shows the Link headers included in a 201 Created response, with the ICE server URLs and their credentials. ✨

Link: <stun:stun.example.net>; rel="ice-server"
Link: <turn:turn.example.net?transport=udp>; rel="ice-server";
      username="user"; credential="myPassword"
Link: <turn:turn.example.net?transport=tcp>; rel="ice-server";
      username="user"; credential="myPassword"
Link: <turns:turn.example.net?transport=tcp>; rel="ice-server";
      username="user"; credential="myPassword"

       Figure 5: Example of a STUN/TURN Server's Configuration
NOTE: The naming of both the rel value ice-server and the target attributes follows what the RTCConfiguration dictionary uses in Section 4.2.1 of the W3C WebRTC recommendation (see [W3C.REC-webrtc-20250313]). 🌈 The rel value ice-server isn't prefixed with urn:ietf:params:whip:, so other specs can reuse it to configure STUN/TURN servers too. Sharing is caring! πŸ’–
NOTE: Depending on the ICE agent implementation, the WHIP client might need to call the setConfiguration method before calling the setLocalDescription method with the local SDP offer. This avoids needing an ICE restart to apply the updated STUN/TURN server configuration during the next ICE gathering phase. 🧠

Some WebRTC implementations can't update the STUN/TURN server configuration after the local offer has been created, as specified in Section 4.1.18 of [RFC9429]. 😬 To support these clients, the WHIP endpoint MAY also include the STUN/TURN server configuration in the responses to OPTIONS requests sent to the WHIP endpoint URL before the POST request goes out. However, this method is NOT RECOMMENDED for WHIP clients to use. And if the client's WebRTC implementation supports it, the WHIP client SHOULD wait for the information to come back in the response to the HTTP POST request instead. 🌸

Generating TURN server credentials might mean sending a request to an external provider. That can add latency to OPTIONS request processing and increase the work the server has to do. πŸ₯Ί So, to avoid that, the WHIP endpoint SHOULD NOT return the STUN/TURN server configuration if the OPTIONS request is a CORS preflight request as defined in [FETCH]. That means the OPTIONS request doesn't include an Access-Control-Request-Method with a POST value, and the Access-Control-Request-Headers HTTP header doesn't contain the Link value. πŸ¦‹

The WHIP clients MAY also support configuring the STUN/TURN server URIs with long-term credentials from either the broadcasting service or an external TURN provider, overriding the values the WHIP endpoint gave them. πŸ‘‘

4.6.1. Congestion Control πŸ’¨

[RFC8836] defines the congestion control requirements for interactive real-time media in WebRTC. πŸŽ€ These requirements assume the data has to arrive continuously within a super tight time window (no more than hundreds of milliseconds end-to-end). If the latency target is higher, some of the [RFC8836] requirements could be relaxed to allow more flexible implementations. 🌈

4.7. Authentication and Authorization πŸ”

All WHIP endpoints, sessions, and clients MUST support HTTP authentication as per Section 11 of [RFC9110]. πŸ’– Also, to make sure everything interoperates, bearer token authentication (defined in the next section) MUST be supported by all WHIP entities. ✨ That doesn't stop anyone from supporting additional HTTP authentication schemes, as defined in Section 11.6 of [RFC9110]. 🌸

4.7.1. Bearer Token Authentication 🎟️

WHIP endpoints and sessions MAY require the HTTP request to be authenticated with an HTTP Authorization header field carrying a bearer token, as specified in Section 2.1 of [RFC6750]. WHIP clients MUST implement this authentication and authorization mechanism and send the HTTP Authorization header field in all HTTP requests sent to either the WHIP endpoint or session. The only exception is preflight OPTIONS requests for CORS. πŸ™Œ

The nature, syntax, and semantics of the bearer token, plus how to hand it to the client, are outside the scope of this document. πŸ€·β€β™€οΈ Tokens that could be used include, but aren't limited to, JSON Web Tokens (JWTs) as per [RFC8725] and a shared secret stored in a database. Tokens are typically given to the end user alongside the WHIP endpoint URL and configured on the WHIP clients, kind of like how Real Time Messaging Protocol (RTMP) URLs and Stream Keys get distributed. πŸ”‘

WHIP endpoints and sessions could also do authentication and authorization by encoding an authentication token within the URLs for the WHIP endpoints or sessions instead. 🧩 If the WHIP client isn't configured to use a bearer token, the HTTP Authorization header field MUST NOT be sent in any request. 🚫

4.8. Simulcast and Scalable Video Coding πŸ“Ί

Simulcast as per [RFC8853] MAY be supported by both media servers and WHIP clients through negotiation in the SDP offer/answer. 🎬

If the client supports simulcast and wants to turn it on for ingesting, it MUST negotiate that support in the SDP offer following the procedures in Section 5.3 of [RFC8853]. πŸ’… A server accepting a simulcast offer MUST create an answer following the procedures in Section 5.3.2 of [RFC8853]. ✨

It's possible for both media servers and WHIP clients to support Scalable Video Coding (SVC). πŸ¦‹ However, since there's no universal negotiation mechanism for SVC in SDP, the encoder must consider the negotiated codec(s), the intended usage, and SVC support in available decoders when configuring SVC. 🧠

4.9. Protocol Extensions πŸŽ€

Okay bestie, WHIP is going to get new features someday, so there's a whole standard way to register them and announce them. ✨

Any protocol extensions supported by the WHIP sessions MUST be advertised to the WHIP client in the "201 Created" response to the initial HTTP POST request sent to the WHIP endpoint. The WHIP endpoint MUST return one Link header field for each extension it supports. The extension "rel" attribute value holds the extension URN, and the URL points to the HTTP resource that will receive requests related to that extension. πŸ”—

Extensions are optional for both WHIP clients and servers 🫢. WHIP clients MUST ignore any Link target attribute with an unknown "rel" attribute value, and WHIP sessions MUST NOT require the usage of any extension. Nobody gets forced into anything, periodt πŸ’….

Each protocol extension MUST register a unique "rel" attribute value that starts with the prefix urn:ietf:params:whip:ext in the "WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs" registry (Section 6.4).

Here's an example, just to vibe-check the idea. Imagine an extension for server-to-client communication using server-sent events, as specified in Section 9.2 of [HTML]. The URL for the server-sent event resource for the ingested stream could come back in the initial HTTP "201 Created" response, with a Link header field whose "rel" attribute is urn:ietf:params:whip:ext:example:server-sent-events. (This document doesn't actually specify that extension. It's only here as an example πŸ™ˆ.)

In this theoretical case, the "201 Created" response to the HTTP POST request would look like this:

Figure 6 shows that same "201 Created" response, so you can see which WHIP extension the session supports, as signaled in the Link header. ✨

HTTP/1.1 201 Created
Content-Type: application/sdp
Location: https://whip.example.com/session/id
Link: <https://whip.example.com/session/id/sse>;
      rel="urn:ietf:params:whip:ext:example:server-sent-events"

Figure 6: Example of a WHIP Extension


5. Security Considerations πŸ”

Okay, this part is serious, so let's be serious 🫢. This document specifies a new protocol on top of HTTP and WebRTC, which means security protocols and considerations from related specifications apply to WHIP too. Those include:

  • WebRTC security considerations: See [RFC8826]. HTTPS SHALL be used in order to preserve the WebRTC security model. πŸ”’
  • Transport Layer Security (TLS): See [RFC8446] and [RFC9147].
  • HTTP security: See Section 11 of [RFC9112] and Section 17 of [RFC9110].
  • URI security: See Section 7 of [RFC3986].

On top of that, WHIP has a thin new attack surface specific to the REST API methods it uses. Watch out, bestie πŸ‘€:

  • HTTP POST flooding and resource exhaustion: An attacker who has valid authentication credentials for ingesting a WHIP stream could make multiple HTTP POST requests to the WHIP endpoint. That forces the endpoint to process the incoming SDP and allocate resources so it can set up the DTLS/ICE connection. The malicious client doesn't need to initiate the DTLS/ICE connection at all, but the WHIP session still has to wait for the DTLS/ICE connection timeout before it can release those resources. If the connection rate is high enough, the servers handling the requests could run out of resources and be unable to process legitimate incoming ingests 😭. To prevent this, WHIP endpoints SHOULD implement a rate limit and avalanche control mechanism for incoming initial HTTP POST requests.
  • Insecure Direct Object References (IDORs) for WHIP session URLs: If the URLs the WHIP endpoint returns for the location of WHIP sessions are easy to guess, an attacker could send multiple HTTP DELETE requests and terminate all the WHIP sessions currently running πŸ’€. To prevent this, WHIP endpoints SHOULD generate URLs with enough randomness, using a cryptographically secure pseudorandom number generator following the best practices in "Randomness Requirements for Security" [RFC4086]. They should also implement a rate limit and avalanche control mechanism for HTTP DELETE requests. The security considerations for Universally Unique IDentifiers (UUIDs) in Section 8 of [RFC9562] apply to generating WHIP session URLs.
  • HTTP PATCH flooding: Similar to HTTP POST flooding, a malicious client could also cause resource exhaustion by sending multiple HTTP PATCH requests to the WHIP session. The WHIP sessions can limit the impact, though, by not allocating new ICE candidates and reusing the existing ones when doing ICE restarts. To prevent this, WHIP endpoints SHOULD implement a rate limit and avalanche control mechanism for incoming HTTP PATCH requests.

6. IANA Considerations 🌸

Per this specification, IANA has added a new link relation type and a new URN sub-namespace for WHIP. IANA has also created registries to manage entries within the urn:ietf:params:whip and urn:ietf:params:whip:ext namespaces.

The link relation type below has been registered by IANA in the "Link Relation Types" registry per Section 4.2 of [RFC8288]:

Relation Name:  ice-server

Description:  Conveys the STUN and TURN servers that can be used by
      an ICE agent to establish a connection with a peer.

Reference:  RFC 9725

6.2. URN Sub-namespace for WHIP (urn:ietf:params:whip) πŸ¦‹

IANA has added a new entry in the "IETF URN Sub-namespace for Registered Protocol Parameter Identifiers" registry, following the template in [RFC3553]:

Registry name:  whip

Specification:  RFC 9725

Repository:  <https://www.iana.org/assignments/whip>

Index value:  An IANA-assigned positive integer that identifies the
      registration.  The first entry added to this registry uses the
      value 1, and this value is incremented for each subsequent entry
      added to the registry.

To manage this sub-namespace, IANA has created two registries inside a new registry group called "WebRTC-HTTP Ingestion Protocol (WHIP)":

  • "WebRTC-HTTP Ingestion Protocol (WHIP) URNs" registry (Section 6.3)
  • "WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs" registry (Section 6.4)

6.3. WebRTC-HTTP Ingestion Protocol (WHIP) URNs Registry πŸ“‡

The "WebRTC-HTTP Ingestion Protocol (WHIP) URNs" registry is used to manage entries within the urn:ietf:params:whip namespace. The registration procedure is "Specification Required" [RFC8126]. The registry contains the following fields: URN, Name, Reference, IANA Registry Reference, and Change Controller. This document is listed as the reference.

The registry has a single initial entry:

URN:  urn:ietf:params:whip:ext

Name:  WebRTC-HTTP Ingestion Protocol (WHIP) extension URNs

Reference:  Section 6.4 of RFC 9725

IANA Registry Reference:  See "WebRTC-HTTP Ingestion Protocol (WHIP)
      Extension URNs" on <https://www.iana.org/assignments/whip>

Change Controller:  IETF

6.4. WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs Registry 🌈

The "WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs" registry is used to manage entries within the urn:ietf:params:whip:ext namespace. The registration procedure is "Specification Required" [RFC8126]. The registry contains the following fields: URN, Name, Reference, IANA Registry Reference, and Change Controller. This document is listed as the reference.

A WHIP extension URN is used as a value in the "rel" attribute of the Link header, as defined in Section 4.9, to signal which WHIP extensions the WHIP endpoint supports. WHIP extension URNs have an "ext" type.

6.5. Registering WHIP URNs and WHIP Extension URNs πŸ“

This section defines the process for registering new URNs in the "WebRTC-HTTP Ingestion Protocol (WHIP) URNs" registry (Section 6.3) and the "WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs" registry (Section 6.4).

6.5.1. Registration Procedure ✨

The IETF has created a mailing list, <wish@ietf.org>, which can be used for public discussion of proposals before registration. Using the mailing list is strongly encouraged πŸ’œ. A designated expert (DE) [RFC8126], appointed by the IESG, will monitor the <wish@ietf.org> mailing list and review registrations.

Registration of new entries in the WHIP registries defined in this document MUST be documented in a permanent and readily available public specification. That spec has to be detailed enough that independent implementations can interoperate, and the DE has to review it as per Section 4.6 of [RFC8126]. A Standards Track RFC is REQUIRED for registering new value data types that modify existing properties. A Standards Track RFC is also REQUIRED for registering WHIP extension URNs that modify WHIP extensions previously documented in an existing RFC.

The registration procedure begins when a completed registration template, defined in Section 6.5.3, is sent to <iana@iana.org>. Decisions made by the DE can be appealed to an Applications and Real-Time (ART) Area Director, and then to the IESG. The normal appeals procedure described in RFC 2026 [BCP9] is to be followed.

Once the registration procedure concludes successfully, IANA will create or modify the corresponding record in the "WebRTC-HTTP Ingestion Protocol (WHIP) URNs Registry" or "WebRTC-HTTP Ingestion Protocol (WHIP) Extension URNs" registry.

An RFC specifying one or more new WHIP extension URNs MUST include the completed registration template(s), which MAY be expanded with additional information. These completed templates are meant to go in the body of the document, not in the IANA Considerations section. The RFC MUST include the syntax and semantics of any extension-specific attributes that may be provided in a Link header field advertising the extension.

6.5.2. Guidance for the Designated Expert 🧐

The DE is expected to do the following:

  • Ascertain the existence of suitable documentation (a specification) as described in [RFC8126], and verify that the document is permanently and publicly available. Specifications should be documented in an Internet-Draft.
  • Check the clarity of purpose and use of the requested registration.
  • Verify that any request for one of these registrations has been made available for review and comments by posting the request to the <wish@ietf.org> mailing list.
  • Ensure that any other request for a code point does not conflict with work that is active or already published by the IETF.

6.5.3. Registration Template πŸŽ€

A WHIP extension URN is defined by completing the following template:

URN:  A unique URN (e.g., "urn:ietf:params:whip:ext:example:server-
      sent-events")

Name:  A descriptive name (e.g., "Sender Side events")

Reference:  A formal reference to the publicly available
      specification

IANA Registry Reference:  The registry related to the new URN

Change Controller:  For Standards Track documents, this is "IETF".
      Otherwise, this is the name of the person or body that has change
      control over the specification.

7. References πŸ“š

7.1. Normative References ✨

okay so these are the normative references, aka the docs this spec straight up leans on to work πŸ’… you need every single one of them to actually build this, no cap 🫢

[FETCH]    WHATWG, "Fetch", WHATWG Living Standard,
           <https://fetch.spec.whatwg.org>.  Commit snapshot:
           <https://fetch.spec.whatwg.org/commit-snapshots/
           edfa8d100cf1ecfde385f65c172e0e8d018fcd98/>.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <https://www.rfc-editor.org/info/rfc2119>.

[RFC3264]  Rosenberg, J. and H. Schulzrinne, "An Offer/Answer Model
           with Session Description Protocol (SDP)", RFC 3264,
           DOI 10.17487/RFC3264, June 2002,
           <https://www.rfc-editor.org/info/rfc3264>.

[RFC3553]  Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An
           IETF URN Sub-namespace for Registered Protocol
           Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, June
           2003, <https://www.rfc-editor.org/info/rfc3553>.

[RFC3986]  Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
           Resource Identifier (URI): Generic Syntax", STD 66,
           RFC 3986, DOI 10.17487/RFC3986, January 2005,
           <https://www.rfc-editor.org/info/rfc3986>.

[RFC4086]  Eastlake 3rd, D., Schiller, J., and S. Crocker,
           "Randomness Requirements for Security", BCP 106, RFC 4086,
           DOI 10.17487/RFC4086, June 2005,
           <https://www.rfc-editor.org/info/rfc4086>.

[RFC5789]  Dusseault, L. and J. Snell, "PATCH Method for HTTP",
           RFC 5789, DOI 10.17487/RFC5789, March 2010,
           <https://www.rfc-editor.org/info/rfc5789>.

[RFC6585]  Nottingham, M. and R. Fielding, "Additional HTTP Status
           Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012,
           <https://www.rfc-editor.org/info/rfc6585>.

[RFC6750]  Jones, M. and D. Hardt, "The OAuth 2.0 Authorization
           Framework: Bearer Token Usage", RFC 6750,
           DOI 10.17487/RFC6750, October 2012,
           <https://www.rfc-editor.org/info/rfc6750>.

[RFC7064]  Nandakumar, S., Salgueiro, G., Jones, P., and M. Petit-
           Huguenin, "URI Scheme for the Session Traversal Utilities
           for NAT (STUN) Protocol", RFC 7064, DOI 10.17487/RFC7064,
           November 2013, <https://www.rfc-editor.org/info/rfc7064>.

[RFC7065]  Petit-Huguenin, M., Nandakumar, S., Salgueiro, G., and P.
           Jones, "Traversal Using Relays around NAT (TURN) Uniform
           Resource Identifiers", RFC 7065, DOI 10.17487/RFC7065,
           November 2013, <https://www.rfc-editor.org/info/rfc7065>.

[RFC7675]  Perumal, M., Wing, D., Ravindranath, R., Reddy, T., and M.
           Thomson, "Session Traversal Utilities for NAT (STUN) Usage
           for Consent Freshness", RFC 7675, DOI 10.17487/RFC7675,
           October 2015, <https://www.rfc-editor.org/info/rfc7675>.

[RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
           2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
           May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8288]  Nottingham, M., "Web Linking", RFC 8288,
           DOI 10.17487/RFC8288, October 2017,
           <https://www.rfc-editor.org/info/rfc8288>.

[RFC8445]  Keranen, A., Holmberg, C., and J. Rosenberg, "Interactive
           Connectivity Establishment (ICE): A Protocol for Network
           Address Translator (NAT) Traversal", RFC 8445,
           DOI 10.17487/RFC8445, July 2018,
           <https://www.rfc-editor.org/info/rfc8445>.

[RFC8446]  Rescorla, E., "The Transport Layer Security (TLS) Protocol
           Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
           <https://www.rfc-editor.org/info/rfc8446>.

[RFC8489]  Petit-Huguenin, M., Salgueiro, G., Rosenberg, J., Wing,
           D., Mahy, R., and P. Matthews, "Session Traversal
           Utilities for NAT (STUN)", RFC 8489, DOI 10.17487/RFC8489,
           February 2020, <https://www.rfc-editor.org/info/rfc8489>.

[RFC8725]  Sheffer, Y., Hardt, D., and M. Jones, "JSON Web Token Best
           Current Practices", BCP 225, RFC 8725,
           DOI 10.17487/RFC8725, February 2020,
           <https://www.rfc-editor.org/info/rfc8725>.

[RFC8826]  Rescorla, E., "Security Considerations for WebRTC",
           RFC 8826, DOI 10.17487/RFC8826, January 2021,
           <https://www.rfc-editor.org/info/rfc8826>.

[RFC8830]  Alvestrand, H., "WebRTC MediaStream Identification in the
           Session Description Protocol", RFC 8830,
           DOI 10.17487/RFC8830, January 2021,
           <https://www.rfc-editor.org/info/rfc8830>.

[RFC8838]  Ivov, E., Uberti, J., and P. Saint-Andre, "Trickle ICE:
           Incremental Provisioning of Candidates for the Interactive
           Connectivity Establishment (ICE) Protocol", RFC 8838,
           DOI 10.17487/RFC8838, January 2021,
           <https://www.rfc-editor.org/info/rfc8838>.

[RFC8839]  Petit-Huguenin, M., Nandakumar, S., Holmberg, C., KerΓ€nen,
           A., and R. Shpount, "Session Description Protocol (SDP)
           Offer/Answer Procedures for Interactive Connectivity
           Establishment (ICE)", RFC 8839, DOI 10.17487/RFC8839,
           January 2021, <https://www.rfc-editor.org/info/rfc8839>.

[RFC8840]  Ivov, E., Stach, T., Marocco, E., and C. Holmberg, "A
           Session Initiation Protocol (SIP) Usage for Incremental
           Provisioning of Candidates for the Interactive
           Connectivity Establishment (Trickle ICE)", RFC 8840,
           DOI 10.17487/RFC8840, January 2021,
           <https://www.rfc-editor.org/info/rfc8840>.

[RFC8842]  Holmberg, C. and R. Shpount, "Session Description Protocol
           (SDP) Offer/Answer Considerations for Datagram Transport
           Layer Security (DTLS) and Transport Layer Security (TLS)",
           RFC 8842, DOI 10.17487/RFC8842, January 2021,
           <https://www.rfc-editor.org/info/rfc8842>.

[RFC8853]  Burman, B., Westerlund, M., Nandakumar, S., and M. Zanaty,
           "Using Simulcast in Session Description Protocol (SDP) and
           RTP Sessions", RFC 8853, DOI 10.17487/RFC8853, January
           2021, <https://www.rfc-editor.org/info/rfc8853>.

[RFC8858]  Holmberg, C., "Indicating Exclusive Support of RTP and RTP
           Control Protocol (RTCP) Multiplexing Using the Session
           Description Protocol (SDP)", RFC 8858,
           DOI 10.17487/RFC8858, January 2021,
           <https://www.rfc-editor.org/info/rfc8858>.

[RFC9110]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
           Ed., "HTTP Semantics", STD 97, RFC 9110,
           DOI 10.17487/RFC9110, June 2022,
           <https://www.rfc-editor.org/info/rfc9110>.

[RFC9112]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
           Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112,
           June 2022, <https://www.rfc-editor.org/info/rfc9112>.

[RFC9143]  Holmberg, C., Alvestrand, H., and C. Jennings,
           "Negotiating Media Multiplexing Using the Session
           Description Protocol (SDP)", RFC 9143,
           DOI 10.17487/RFC9143, February 2022,
           <https://www.rfc-editor.org/info/rfc9143>.

[RFC9147]  Rescorla, E., Tschofenig, H., and N. Modadugu, "The
           Datagram Transport Layer Security (DTLS) Protocol Version
           1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022,
           <https://www.rfc-editor.org/info/rfc9147>.

[RFC9429]  Uberti, J., Jennings, C., and E. Rescorla, Ed.,
           "JavaScript Session Establishment Protocol (JSEP)",
           RFC 9429, DOI 10.17487/RFC9429, April 2024,
           <https://www.rfc-editor.org/info/rfc9429>.

[RFC9562]  Davis, K., Peabody, B., and P. Leach, "Universally Unique
           IDentifiers (UUIDs)", RFC 9562, DOI 10.17487/RFC9562, May
           2024, <https://www.rfc-editor.org/info/rfc9562>.

[W3C.REC-ldp-20150226]
           Arwe, J., Ed., Speicher, S., Ed., and A. Malhotra, Ed.,
           "Linked Data Platform 1.0", W3C Recommendation, 26
           February 2015,
           <https://www.w3.org/TR/2015/REC-ldp-20150226/>.  Latest
           version available at: <https://www.w3.org/TR/ldp/>.

7.2. Informative References πŸ“š

Okay bestie, here are the receipts 🧾 These are the informative references, the extra reading that backs up the spec. Nothing here is required, but they're the good stuff ✨

[BCP56] is Best Current Practice 56, which you can find at <https://www.rfc-editor.org/info/bcp56>. At the time of writing, this BCP is made up of the following:

Nottingham, M., "Building Protocols with HTTP", BCP 56, RFC 9205, DOI 10.17487/RFC9205, June 2022, <https://www.rfc-editor.org/info/rfc9205>.

[BCP9] is Best Current Practice 9, found at <https://www.rfc-editor.org/info/bcp9>. At the time of writing, this BCP is made up of the following 🌸

Bradner, S., "The Internet Standards Process -- Revision 3", BCP 9, RFC 2026, DOI 10.17487/RFC2026, October 1996, <https://www.rfc-editor.org/info/rfc2026>.

Dusseault, L. and R. Sparks, "Guidance on Interoperation and Implementation Reports for Advancement to Draft Standard", BCP 9, RFC 5657, DOI 10.17487/RFC5657, September 2009, <https://www.rfc-editor.org/info/rfc5657>.

Housley, R., Crocker, D., and E. Burger, "Reducing the Standards Track to Two Maturity Levels", BCP 9, RFC 6410, DOI 10.17487/RFC6410, October 2011, <https://www.rfc-editor.org/info/rfc6410>.

Resnick, P., "Retirement of the "Internet Official Protocol Standards" Summary Document", BCP 9, RFC 7100, DOI 10.17487/RFC7100, December 2013, <https://www.rfc-editor.org/info/rfc7100>.

Kolkman, O., Bradner, S., and S. Turner, "Characterization of Proposed Standards", BCP 9, RFC 7127, DOI 10.17487/RFC7127, January 2014, <https://www.rfc-editor.org/info/rfc7127>.

Dawkins, S., "Increasing the Number of Area Directors in an IETF Area", BCP 9, RFC 7475, DOI 10.17487/RFC7475, March 2015, <https://www.rfc-editor.org/info/rfc7475>.

Halpern, J., Ed. and E. Rescorla, Ed., "IETF Stream Documents Require IETF Rough Consensus", BCP 9, RFC 8789, DOI 10.17487/RFC8789, June 2020, <https://www.rfc-editor.org/info/rfc8789>.

Rosen, B., "Responsibility Change for the RFC Series", BCP 9, RFC 9282, DOI 10.17487/RFC9282, June 2022, <https://www.rfc-editor.org/info/rfc9282>.

[HTML] is the WHATWG HTML Living Standard, which lives at <https://html.spec.whatwg.org/>. The commit snapshot is <https://html.spec.whatwg.org/commit-snapshots/09db56ba9343c597340b2c7715f43ff9b10826f6/>.

[RFC3261] is Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, DOI 10.17487/RFC3261, June 2002, <https://www.rfc-editor.org/info/rfc3261>.

[RFC6120] is Saint-Andre, P., "Extensible Messaging and Presence Protocol (XMPP): Core", RFC 6120, DOI 10.17487/RFC6120, March 2011, <https://www.rfc-editor.org/info/rfc6120>.

[RFC7826] is Schulzrinne, H., Rao, A., Lanphier, R., Westerlund, M., and M. Stiemerling, Ed., "Real-Time Streaming Protocol Version 2.0", RFC 7826, DOI 10.17487/RFC7826, December 2016, <https://www.rfc-editor.org/info/rfc7826>.

[RFC8126] is Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

[RFC8836] is Jesup, R. and Z. Sarker, Ed., "Congestion Control Requirements for Interactive Real-Time Media", RFC 8836, DOI 10.17487/RFC8836, January 2021, <https://www.rfc-editor.org/info/rfc8836>.

[RFC9457] is Nottingham, M., Wilde, E., and S. Dalal, "Problem Details for HTTP APIs", RFC 9457, DOI 10.17487/RFC9457, July 2023, <https://www.rfc-editor.org/info/rfc9457>.

[W3C.REC-webrtc-20250313] is Jennings, C., Ed., Castelli, F., Ed., BostrΓΆm, H., Ed., and J. Bruaroey, Ed., "WebRTC: Real-Time Communication in Browsers", W3C Recommendation, 13 March 2025, <https://www.w3.org/TR/2025/REC-webrtc-20250313/>. The latest version is available at <https://www.w3.org/TR/webrtc/>.


Acknowledgements 🫢

The authors wanted to shout out Lorenzo Miniero, Juliusz Chroboczek, Adam Roach, Nils Ohlmeier, Christer Holmberg, Cameron Elliott, Gustavo Garcia, Jonas Birme, Sandro Gauci, Christer Holmberg, and everyone else in the WebRTC community πŸ’œ They gave comments, feedback, text, and improvement proposals on the document, and they built early implementations of the spec. Literally iconic behavior.


Authors' Addresses πŸ¦‹

Sergio Garcia Murillo Millicast Email: sergio.garcia.murillo@cosmosoftware.io

Alexandre Gouaillard CoSMo Software Email: alex.gouaillard@cosmosoftware.io

πŸ“¦ where this page comes from