connect() then initCall(). Wave handles the SIP registration, the media,
and the short-lived session credentials for you.
Web Calling uses the
webrtc:write scope. In sandbox, calls are
origin-locked and destination-locked to your signup number; a production
key (sk_live_) removes the destination lock.Install
Before you start
- Allow your origin. In the Wave dashboard, add the origin your app runs on
(e.g.
https://app.example.com) to your project’s allowed origins. The SDK fetches its session from/v1/webrtc/config, which rejects any origin that isn’t on the list. - Use a
webrtc:writekey. The key is sent from the browser, so it’s origin-locked by design.
Quickstart
Agent sessions and caller sessions
Each browser session is one of two kinds. Theidentity option selects the kind.
Identity rules
- 1–64 characters from
A–Z a–z 0–9 . _ -. - Use the same identity everywhere: in the SDK, in
POST /v1/queues/agents/login, and in a callflow<Dial>. - The prefixes
p_(portal members) andc_(caller sessions) are reserved. An identity with these prefixes gets400 INVALID_IDENTITY. - If your tenant already has a SIP user with that name that Wave did not create (for example a desk phone), Wave does not change it and returns
409 IDENTITY_CONFLICT. Use a different identity. - Wave creates the SIP user on first use and sets a new password for each session. You never manage SIP users.
- One session for each identity. If the same identity opens a second session (for example a second tab), the newest session wins. The older session gets
onSessionEnded("revoked")at its next credential refresh and stops ringing. - Agent sessions need a production key (
sk_live_). A sandbox key ignoresidentityand opens a caller session.
Receive calls
Setidentity and add an onIncomingCall handler. The handler gets a call object:
- One call at a time. While a call is active or ringing, a new incoming call gets
486 Busy Here. It does not reachonIncomingCall. - If the caller hangs up before you accept or reject,
onIncomingCallCancelled()fires. After that,accept()andreject()on that call object throwNO_ACTIVE_CALL. - If the microphone is denied,
accept()throwsMICROPHONE_UNAVAILABLEand the call continues to ring. You can then callreject(). - If you set
onIncomingCallwithoutidentity, the constructor throwsINCOMING_REQUIRES_IDENTITY.
Call quality
While a call is connected and not on hold, the SDK sendsonQualityReport(metrics)
every 5 seconds. Each report covers the last 5 seconds:
Reports stop when the call ends or is put on hold, and start again when you
resume the call. As a guide:
mos of 4.0 or more is good, 3.6–4.0 is fair, and
less than 3.6 is poor. The quality values stay in the browser; Wave does not
receive them.
Configuration
new WaveSDK(config, events)
Methods
Events
Pass handlers in the second argument to the constructor.You never handle the SIP password or session token yourself. The SDK fetches
them, keeps the call alive, and auto-rotates the credential about a minute
before it expires.
Error codes
onFailed(error) gives you an error.code:
The session request (
POST /v1/webrtc/config) can also fail with these API
errors. The SDK reports them as CONFIG_FAILED, with the HTTP status in the message:
Webhooks
When a browser call ends, Wave sends the usualcall.ended webhook for it (see
Webhooks).
Next steps
How voice works
Where a browser call sits in the call lifecycle.
Calls & recordings
Read the log and fetch a recording.

