← All articles
Integrations9 min read

In-App Video and Voice Calling: Agora, WebRTC and the alternatives

What it takes to add live calling to a mobile app — how the options compare, call lifecycle and token handling, permissions, backgrounding, and how usage-based pricing works.

FlutterAgoraWebRTCReal-time

Live video and voice turn up in more product briefs every year — consultations, teaching, support, astrology, telehealth. The SDK demo takes an afternoon. Making calls reliable for people on Indian mobile networks, on old phones, with interruptions, is the actual project.

The options

ApproachWhat you getWhat you take on
Managed SDK (Agora, Twilio, ZegoCloud, 100ms)Media servers, routing, adaptive quality, prebuilt UI optionsPer-minute cost; token service on your backend
Raw WebRTCNo per-minute vendor fee; full controlSignalling server, STUN/TURN servers, NAT traversal, scaling, and ongoing maintenance
Self-hosted SFU (LiveKit, Janus, mediasoup)Control plus a real media serverInfrastructure, bandwidth bills and operations

For a one-to-one consultation feature inside a product, a managed SDK is almost always the right call. Raw WebRTC looks cheaper until you price a TURN server and the engineering time to keep it healthy — and TURN relaying is exactly what saves calls on restrictive mobile networks.

Self-hosting starts making sense at high, predictable volume, or where data residency rules require it.

Tokens belong on your server

Managed SDKs authenticate with short-lived tokens generated from an app certificate. That certificate must never ship inside the app: anyone can extract strings from an APK and then generate their own tokens against your account, on your bill.

Your backend issues a token scoped to a channel and a user, with a short expiry, and only after checking the caller is allowed to join. Then renew before expiry — a token that lapses mid-call drops the call, and users read that as your app crashing.

Permissions at the right moment

Camera and microphone should be requested when the user starts or accepts a call, never on first launch. Handle three outcomes explicitly:

  • Granted — proceed.
  • Denied — explain what will not work and offer to ask again.
  • Permanently denied — the OS will not prompt again, so deep-link to settings with a clear sentence.

A call screen showing a black rectangle with no explanation is indistinguishable from a broken app.

The call lifecycle is where the bugs live

Decide deliberately what happens in each of these, because they all occur daily:

  • User switches apps mid-call.Typically video pauses and audio continues. Tell the other side so they see “camera off” rather than a frozen frame.
  • A real phone call arrives. The OS takes the audio session. You have to detect it and recover when it ends.
  • The screen locks.
  • The app is force-killed mid-call. The server still thinks the user is in the channel. Without a server-side timeout, a billed session runs until something else stops it.
  • Network switches from wifi to mobile data mid-sentence.

That force-kill case is the one with a direct financial consequence, and the client cannot be relied on to announce its own death.

Incoming calls are a separate problem

Showing a proper incoming-call screen when the app is closed is not part of the video SDK. It needs push notifications plus platform call APIs — CallKit on iOS and ConnectionService on Android — so the OS treats it as a call rather than a notification.

This is a meaningful piece of work. If your product only needs scheduled calls that both parties join from inside the app, you can skip it entirely. Decide early, because it changes the estimate substantially.

Degrade gracefully

On a weak connection, falling back to audio-only is far better than a frozen video frame. Most SDKs expose network quality callbacks; use them to:

  • Drop video and keep audio when quality falls below a threshold.
  • Show a plain message: “Weak connection — video paused”.
  • Lower the resolution before dropping the call.

Telling the user the app is coping is worth as much as the technical fallback itself.

Understanding the cost

Managed services bill per participant-minute, and video costs considerably more than audio, with higher resolutions costing more again. That has product implications:

  • Default to a sensible resolution rather than the highest available.
  • End idle sessions server-side.
  • Offer audio-only as a first-class option — many consultations do not need video.
  • Model the cost per session before pricing the feature to your own users.

Recording and privacy

If sessions are recorded, participants must be told clearly and the recording needs a deliberate storage, retention and access policy. For anything involving health or financial advice, that is a legal question before it is a technical one. Recording quietly because the SDK supports it is not acceptable.

Testing that actually finds problems

Office wifi will tell you everything is fine. Instead test with:

  • Two real devices on different networks, at least one on mobile data.
  • A network link conditioner simulating poor 3G and packet loss.
  • An incoming phone call during a video call.
  • Airplane mode toggled mid-call.
  • A low-end device with battery saver enabled.
  • A long call — over any token expiry window.

Calling features are judged almost entirely on the bad-network case, because that is when people notice them.

Read next