This document defines a set of ECMAScript APIs in WebIDL to allow data to be sent and received from another browser or device implementing the QUIC protocol. This specification is being developed in conjunction with a protocol specification developed by the IETF QUIC Working Group.


This specification extends the WebRTC [[WEBRTC]], ORTC [[ORTC]] and WebTransport [[WEBTRANSPORT]] specifications to enable the use of QUIC [[QUIC-TRANSPORT]] to exchange arbitrary data with remote peers using NAT-traversal technologies such as ICE, STUN, and TURN. Since QUIC can be multiplexed on the same port as RTP, RTCP, DTLS, STUN and TURN, this specification is compatible with all the functionality defined in [[WEBRTC]] and [[ORTC]] including communication using audio/video media and SCTP data channels.

This specification defines an interface to QUIC streams as well as datagrams [[QUIC-DATAGRAM]]. By utilizing a QUIC stream per message, it is possible to implement support for message-based communications (such as RTCDataChannel) on top.

This specification extends the WebTransport API under development within the W3C WebTransport WG. Since the WebTransport specification is a work-in-progress, the API is likely to change significantly going forward.

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

Implementations that use ECMAScript to implement the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[WEBIDL-1]], as this specification uses that specification and terminology.


The EventHandler interface, representing a callback used for event handlers, and the ErrorEvent interface are defined in [[!HTML51]].

The concepts queue a task, fires a simple event and networking task source are defined in [[!HTML51]].

The terms event, event handlers and event handler event types are defined in [[!HTML51]].

When referring to exceptions, the terms throw and create are defined in [[!WEBIDL-1]].

The terms fulfilled, rejected, resolved, pending and settled used in the context of Promises are defined in [[!ECMASCRIPT-6.0]].

The RTCIceTransport and RTCCertificate interfaces and the RTCDtlsFingerprint dictionary are defined in [[!WEBRTC]] and [[!ORTC]]. The WebTransport interface is defined in [[!WEBTRANSPORT]] Section 7. The WebTransportState enum is defined in [[!WEBTRANSPORT]] Section 7.5. The OutgoingStream interface is defined in [[!WEBTRANSPORT]] Sections 8. The IncomingStream interface is defined in [[!WEBTRANSPORT]] Sections 9.

RTCQuicTransport Interface

The RTCQuicTransport is a specialization of WebTransport focused on peer-to-peer use cases and includes information relating to use of a QUIC transport with an ICE transport.


A RTCQuicTransport instance is constructed using an RTCIceTransport and an optional sequence of RTCCertificate objects. An RTCQuicTransport object in the "closed" or "failed" states can be garbage-collected when it is no longer referenced.

The QUIC negotiation occurs between transport endpoints determined via ICE. Multiplexing of QUIC with STUN, TURN, DTLS, RTP and RTCP is supported within [[QUIC-TRANSPORT]].

A newly constructed RTCQuicTransport MUST listen and respond to incoming QUIC packets before start() is called. However, to complete the negotiation it is necessary to verify the remote fingerprint by computing fingerprints for the selected remote certificate using the digest algorithms provided in remoteParameters.fingerprints[].algorithm. If a calculated fingerprint and algorithm matches a fingerprint and algorithm included in remoteParameters.fingerprints[], the remote fingerprint is verified. After the QUIC handshake exchange completes (but before the remote fingerprint is verified) incoming media packets may be received. A modest buffer MUST be provided to avoid loss of media prior to remote fingerprint validation (which can begin after start() is called).

Interface Definition

interface RTCQuicTransport : WebTransport {
    constructor(RTCIceTransport transport, optional sequence<RTCCertificate> certificates);
    readonly        attribute RTCIceTransport          transport;
    RTCQuicParameters     getLocalParameters ();
    RTCQuicParameters?    getRemoteParameters ();
    sequence<RTCCertificate> getCertificates ();
    sequence<ArrayBuffer> getRemoteCertificates ();
    undefined                  start (RTCQuicParameters remoteParameters);


When RTCQuicTransport.constructor() is invoked, the user agent MUST run the following steps:
  1. Let transport be the first argument.
  2. If transport is in the "closed" state, throw an InvalidStateError and abort these steps.
  3. If transport has been used to construct another RTCQuicTransport whose [[\WebTransportState]] slot is not "closed", throw an InvalidStateError and abort these steps.
  4. Let certificates be the second argument if provided, null otherwise.
  5. If certificates is non-null and is non-empty, check that the expires attribute of each RTCCertificate object is in the future. If a certificate has expired, throw an InvalidAccessError and abort these steps.
  6. Let quictransport be a newly constructed RTCQuicTransport object.
  7. Let quictransport have a [[\OutgoingStreams]] internal slot representing a sequence of OutgoingStream objects, initialized to empty.
  8. Let quictransport have a [[\IncomingStreams]] internal slot representing a sequence of IncomingStream objects, initialized to empty.
  9. Let quictransport have a [[\WebTransportState]] internal slot, initialized to "connecting".
  10. Let quictransport have a [[\ReceivedDatagrams]] internal slot representing a queue of Uint8Array, initialized to empty.
  11. Let quictransport have a [[\ReceiveDatagramsPromise]] internal slot representing a Promise<sequence<Uint8Array>>?, initialized to null.
  12. Let quictransport have a [[\Certificates]] internal slot.
  13. If certificates is non-null and is non-empty, initialize the [[\Certificates]] internal slot to certificates.
  14. If certificates is null or is empty, generate a certificate using the default key generation algorithm and store it in the [[\Certificates]] internal slot.
  15. Return quictransport.
Parameter Type Nullable Optional Description
transport RTCIceTransport
certificates sequence<RTCCertificate>


transport of type RTCIceTransport, readonly

The associated RTCIceTransport instance. When the RTCIceTransport's state attribute changes values, the user agent MUST run the following steps:

  1. Let transport be the associated RTCIceTransport instance.
  2. If transport is not in the "closed" state, abort these steps.
  3. Let quicTransport be the RTCQuicTransport.
  4. Set quicTransport's [[\WebTransportState]] to "closed".



getLocalParameters() obtains the QUIC parameters of the local RTCQuicTransport upon construction. If multiple certificates were provided in the constructor, then multiple fingerprints will be returned, one for each certificate. getLocalParameters().role always returns the default role of a newly constructed RTCQuicTransport; for a browser this will be auto.

No parameters.
Return type: RTCQuicParameters

getRemoteParameters() obtains the remote QUIC parameters passed in the start() method. Prior to calling start(), null is returned.

No parameters.
Return type: RTCQuicParameters, nullable

getCertificates() returns the value of the RTCQuicTransport's [[\Certificates]] internal slot.

No parameters.
Return type: sequence<RTCCertificate>

getRemoteCertificates() returns the certificate chain in use by the remote side, with each certificate encoded in binary Distinguished Encoding Rules (DER) [[!X690]]. getRemoteCertificates() returns an empty list prior to selection of the remote certificate, which is completed once WebTransportState transitions to connected.

No parameters.
Return type: sequence<ArrayBuffer>

Start QUIC transport negotiation with the parameters of the remote QUIC transport, including verification of the remote fingerprint. During connection establishment, use of this API must be indicated by selecting the ALPN token "q2q" in the crypto handshake. Only a single QUIC transport can be multiplexed over an ICE transport. Therefore if a RTCQuicTransport object quicTransportB is constructed with an RTCIceTransport object iceTransport previously used to construct another RTCQuicTransport object quicTransportA, then if quicTransportB.start() is called prior to having called quicTransportA.stop(), then throw an InvalidStateError.

If start is called after a previous start call, or if state is closed, throw an InvalidStateError.

If all of the values of remoteParameters.fingerprints[j].algorithm are unsupported, where j goes from 0 to the number of fingerprints, throw a NotSupportedError.

Parameter Type Nullable Optional Description
remoteParameters RTCQuicParameters
Return type: void

RTCQuicParameters Dictionary

The RTCQuicParameters dictionary includes information relating to QUIC configuration.

dictionary RTCQuicParameters {
             RTCQuicRole                  role = "auto";
             required sequence<RTCDtlsFingerprint> fingerprints;

Dictionary RTCQuicParameters Members

role of type RTCQuicRole, defaulting to "auto"

The QUIC role, with a default of auto.

fingerprints of type sequence<RTCDtlsFingerprint>

Sequence of fingerprints, at least one fingerprint for each certificate (with one computed with the digest algorithm used in the certificate signature).

RTCQuicRole Enum

RTCQuicRole indicates the role of the QUIC transport.

enum RTCQuicRole {
Enumeration description

The QUIC role is determined based on the resolved ICE role: the ICE controlled role acts as the QUIC client and the ICE controlling role acts as the QUIC server.


The QUIC client role.


The QUIC server role.

QUIC role determination

To diagnose QUIC role issues, an application may wish to determine the desired and actual QUIC role of an RTCQuicTransport. For a browser implementing ORTC, a RTCQuicTransport object assumes a QUIC role of auto upon construction. This implies that the QUIC role is determined by the ICE role. Since getLocalParameters().role always returns the role assigned to an RTCQuicTransport object upon construction (auto for a browser), the getLocalParameters method cannot be used to determine the desired or actual role of an RTCQuicTransport.

An application can determine the desired role of an RTCQuicTransport from the value of remoteParameters.role passed to RTCQuicTransport.start(remoteParameters). If remoteParameters.role is server then the desired role of the RTCQuicTransport is client. If remoteParameters.role is client then the desired role of the RTCQuicTransport is server.

The RTCQuicTransport.transport.onstatechange EventHandler can be used to determine whether an RTCQuicTransport transitions to the desired role. When RTCQuicTransport.transport.state transitions to connected, if RTCQuicTransport.transport.role is controlled then the role of the RTCQuicTransport is client. If RTCQuicTransport.transport.role is controlling then the role of the RTCQuicTransport is server.

Privacy and Security Considerations

This section is non-normative; it specifies no new behaviour, but instead summarizes information already present in other parts of the specification. The overall security considerations of the APIs and protocols used in WebRTC are described in [[RTCWEB-SECURITY-ARCH]].

Impact on same origin policy

The QUIC API enables data to be communicated between browsers and other devices, including other browsers.

This means that data can be shared between applications running in different browsers, or between an application running in the same browser and something that is not a browser. This is an extension to the Web model which has had barriers against sending data between entities with different origins.

This specification provides no user prompts or chrome indicators for communication; it assumes that once the Web page has been allowed to access data, it is free to share that data with other entities as it chooses. Peer-to-peer exchanges of data via QUIC can therefore occur without any user explicit consent or involvement.

Impact on local network

Since the browser is an active platform executing in a trusted network environment (inside the firewall), it is important to limit the damage that the browser can do to other elements on the local network, and it is important to protect data from interception, manipulation and modification by untrusted participants.

Mitigations include:

These measures are specified in the relevant IETF documents.

Persistent information

Utilizing the generateCertificate API in [[!WEBRTC]], it is possible to generate and store certificates that can subsequently be reused in constructing RTCQuicTransport objects. These persistent certificates can therefore be used to identify a user.