Before you start
To make your first stream call, you need:- A voice Pearl that is active. The call runs its published version.
- Its Pearl ID: on your Pearl’s overview page, in the Settings popover.
- An API key, or an OAuth app with the
pearls:streamscope (Make stream calls through the API in the platform). See API Authorization. - One of the four audio formats, the same in both directions:
Connect
1
Create the token
From your backend, call Create Stream Token. It creates the call and returns the
url to open and a token valid for 60 seconds.endUserId is your own id for the person on the call, such as a customer id: send the same value for the same person every time. It is optional: without it, Pearl does not remember the person.2
Open the WebSocket
Open the
url with the token, within 60 seconds. Pearl sends ready, then you stream.Stream audio
- Audio is binary, in both directions: raw bytes in the call’s format, with no base64 and no JSON. On an Opus call, each message is one Opus packet.
- Send one 20 ms frame every 20 ms, in real time, for the whole call. When the end user is quiet or muted, send silence, not nothing.
- Pearl sends one 20 ms frame every 20 ms too, with silence while it listens. Play the frames through a small jitter buffer of 60 to 100 ms.
- Interruptions need no code. When the end user talks over Pearl, it stops speaking and the next frames are already silence: there is nothing to clear on your side.
Events
Text messages are JSON events, such as{"type":"hangup"}, in both directions:
After the call
The call appears in your call history and webhooks like any other call of your Pearl, withchannel: "stream" and your endUserId where the end user’s phone number would be (empty without one).
Errors and limits
The cases you are most likely to meet. Stream WebSocket lists every end reason and limit.Examples
Quickstart
Talk to your Pearl from your terminal, with your microphone.
Browser App
A web page with the microphone and Pearl’s voice.

