01What is WebRTC?
WebRTC (Web Real-Time Communication) is the open standard that lets browsers and apps send audio, video and arbitrary data to each other in real time, with encryption built in and no plug-ins. The W3C defines the JavaScript APIs (getUserMedia, RTCPeerConnection, RTCDataChannel) and the IETF defines the protocols underneath; WebRTC 1.0 became a W3C Recommendation in January 2021. Every major browser ships it, and native libraries bring the same stack to Android, iOS and servers.
A session has three jobs. Signalling, exchanging a Session Description Protocol (SDP) offer and answer that describe codecs, media streams and the fingerprints of each side's encryption keys, is deliberately left to the application, which carries it over WebSocket, HTTPS or SIP. Connectivity is handled by ICE, which gathers candidate addresses (the device's own, the public address a STUN server reports, and a relay on a TURN server) and tests pairs until one gets through the NATs and firewalls between the peers. Media then flows as RTP packets encrypted with SRTP, using keys from a DTLS handshake; data channels run over SCTP on the same DTLS connection. Opus and G.711 are the mandatory audio codecs.
In business messaging WebRTC powers click-to-call widgets on websites, in-app calling and the WhatsApp Business Calling API. For a user-initiated call, Meta sends a calls webhook whose session holds an SDP offer; the business replies on POST /{PHONE_NUMBER_ID}/calls with pre_accept and then accept and its SDP answer, and audio flows over ICE, DTLS and SRTP with Opus. WhatsApp Calling over SIP is the alternative for contact centres. SIP is carrier-side signalling for VoIP, trunks and the PSTN; WebRTC is a complete media stack that leaves signalling open, and the two meet at gateways that translate between them.
Key takeaways
- WebRTC is the W3C and IETF standard for encrypted, real-time audio, video and data between browsers, apps and servers.
- Peers exchange an SDP offer and answer over a signalling channel the application builds itself; WebRTC does not define signalling.
- ICE finds a working network path using host, STUN (server-reflexive) and TURN (relay) candidates, so calls cross NATs and firewalls.
- Media is always encrypted with DTLS-SRTP; Opus is the usual audio codec.
- The WhatsApp Business Calling API uses WebRTC: the calls webhook carries an SDP offer and you answer it on the /calls endpoint.
02 · How it works, step by step
How does WebRTC work?
- Step 1
Capture media and create a peer connection
getUserMediareturns microphone (and camera) tracks, which are added to anRTCPeerConnectionconfigured with your STUN and TURN servers. - Step 2
Exchange the SDP offer and answer
One side calls
createOffer, sets it as its local description and sends it through your signalling channel; the other sets it as remote, callscreateAnswerand sends that back. - Step 3
ICE finds a path
Both sides gather host, server-reflexive (STUN) and relay (TURN) candidates, trickle them through signalling and run connectivity checks; the best working pair is selected.
- Step 4
DTLS sets up the keys
A DTLS handshake runs over the chosen path. The certificate fingerprints in each SDP prove the keys belong to the parties that signalled, and SRTP keys are derived from it.
- Step 5
Media flows and adapts
Opus frames travel as encrypted RTP. RTCP feedback and congestion control adjust bitrate to the network, and
getStatsexposes jitter, packet loss and round-trip time. - Step 6
Recover or hang up
On a network change, an ICE restart finds a new path without a new call. Ending the call closes the connection and, on WhatsApp, sends a
terminateaction.
03WebRTC in code
const pc = new RTCPeerConnection({iceServers: [{ urls: "stun:stun.example.com:3478" },{ urls: "turns:turn.example.com:443?transport=tcp", username: "{TURN_USER}", credential: "{TURN_CREDENTIAL}" },],});const mic = await navigator.mediaDevices.getUserMedia({ audio: true });mic.getTracks().forEach((track) => pc.addTrack(track, mic));pc.ontrack = ({ streams }) => { remoteAudio.srcObject = streams[0]; };// Trickle ICE: send candidates as they are found.pc.onicecandidate = ({ candidate }) => candidate && signalling.send({ type: "candidate", candidate });const offer = await pc.createOffer();await pc.setLocalDescription(offer);signalling.send({ type: "offer", sdp: pc.localDescription.sdp });signalling.on("answer", ({ sdp }) => pc.setRemoteDescription({ type: "answer", sdp }));signalling.on("candidate", ({ candidate }) => pc.addIceCandidate(candidate));
signalling is your own WebSocket or HTTPS channel; WebRTC only defines what goes through it.
04 · Common mistakes, and the fix
Common mistakes with WebRTC
Running without TURN
STUN alone fails behind symmetric NATs and firewalls that block UDP, common on corporate and some mobile networks. Run TURN, including TURN over TLS on port 443, and monitor how often calls fall back to relay.
Assuming WebRTC includes signalling
It does not. You must build, authenticate and order the offer, answer and candidate exchange yourself; races such as applying candidates before the remote description cause silent failures.
No ICE restart on network change
A phone moving from Wi-Fi to mobile data loses its path. Detect a failed or disconnected ICE state and restart ICE instead of dropping the call.
Getting the WhatsApp call sequence wrong
The
acceptSDP answer must match the one sent withpre_accept, and media sent beforeacceptreturns 200 clips the caller's first words. Reuse the answer and start sending only after acceptance.Flying blind on quality
Without
getStatsyou cannot tell packet loss from a bad microphone. Log round-trip time, jitter, loss and the selected candidate type per call.
05WebRTC: key facts and limits
- Standards
- W3C WebRTC 1.0 (Recommendation, Jan 2021) plus IETF protocols
- Signalling
- Not defined: WebSocket, HTTPS, SIP or webhooks
- NAT traversal
- ICE (RFC 8445) with STUN (RFC 8489) and TURN (RFC 8656)
- Media security
- DTLS-SRTP, mandatory on every session
- Mandatory audio codecs
- Opus and G.711 (PCMU, PCMA)
- Data
- RTCDataChannel, SCTP over DTLS
- WhatsApp Calling API
- Opus over ICE, DTLS and SRTP; SIP also supported
06Why does WebRTC matter?
Real-time voice is unforgiving: a call that takes four seconds to connect, clips the first word or drops when the customer walks from Wi-Fi to 4G loses trust faster than any delayed message. Understanding WebRTC's layers tells a developer where those failures come from: missing TURN servers, signalling races, codec mismatch or no ICE restart. It is also the shared foundation for browser click-to-call with number masking, agent desktops on cloud telephony platforms and answering WhatsApp calls in your own software.
07Example: A Pune clinic's browser calls stop failing
A Pune clinic chain adds a click-to-call button to its appointment page and handles WhatsApp calls from the same agent desktop. About one call in eight from office networks connects with no audio. getStats shows ICE settling on no candidate pair: the clinic runs only a STUN server, and strict corporate firewalls block UDP. Adding a TURN server reachable over TLS on port 443 fixes it. The same review finds the WhatsApp integration started sending audio before the accept request returned 200, clipping greetings; it now waits for the response first.
08 · Tips from the bench
Best practices for WebRTC
- Issue short-lived TURN credentials from your server instead of shipping static ones in the client.
- Prefer Opus and let it adapt; force G.711 only when bridging to legacy telephony.
- Test from a mobile hotspot and a locked-down office network before launch, not just from your desk.
- Verify the X-Hub-Signature-256 header on calls webhooks before answering any offer.