Setting up a video call

This tutorial will walk you through the steps of setting up a basic client using the Between API. By following this guide, you'll learn how to create a video call application and manage the call states.


If you have signed up for Between, you should have received an email that lets you login to the Between dashboard.

Step 1: Import and initial the conference

The Conference object is initialized with three parameters. The first one is the API key given to you. The second one is an optional customCallid which is used to idenitify calls, if it is not entered then a UUID is generated and returned. The second parameter is customUserData, which can be anything such as a JSON object of data, a userId, etc. This will be used to identify Peers later in the call.

import { Conference } from 'between'

let apiKey = ""
let conf = new Conference(apiKey, customCallId, customUserData) // custom or auto generated callId

Step 2: Handling device permissions

Between handles all the difficult parts of the device permissions for the easiest call experience. The built-in method getPermissionState unifies permission handling across all browsers and it returns a DevicePermissionState object. If the participant denies permission, we suggest handling this situation by displaying an alert. To learn more about how devices are used in Between, visit the Adjusting Audio/Video section

// this will ask the user for media permissions
let status = await conf.getPermissionState()

// if the user denies permission, handle that
if (status.state === "denied" || status.state === "failed") {

Step 3: Setting up session listeners

Between uses simple listeners to keep information up-to-date throughout the lifetime of the call. For this example, we'll cover three main listeners: localParticipant, peerJoined, and peerLeft.

The localParticipant listener is used to get a local video stream of the publishing user.

The peerJoined listener is called when a new user joins the call.

The peerLeft listener is called when any user leaves the call.

// we will setup all the relevant events to listen for

let local;
let remoteParticpants = {}

conf.on("localParticipant", (lp: LocalParticipant) => {
    // returns a LocalParticipant object
    // we will use this to publish audio/video
    // also to change devices throughout the conference 
    local = lp
    local.on("videoCreated", (video: HTMLVideoElement) => {
        // we get a local video stream of the publishing user

conf.on("peerJoined", (peer: Peer) => {
    // returns a Peer object 
    // called whenever someone has entered the call
    // we will use this to get information about other
    // Peers in the call

    // NOTE: is customUserData that we initiated with

    peer.on('videoCreated', (video: HTMLVideoElement) => {
        // the remote user has published a video


    // add this to our local array to use later
    // for volume, getting spatial data, etc..
    remoteParticpants[] = peer


conf.on("peerLeft", (id: string) => {
    // the peer has left the call

    delete remoteParticpants[id]

Step 4: Handling termination and starting the call

Starting a call is as easy as calling the startCall method. As for termination, Between dispatches the sessionTerminated listener for when the conference ends through either user input or unexpectedly, visit the Conference reference section to learn more about handling errors.

// finally we will start the call

conf.on("sessionTerminated", () => {
    // the call has ended
    local = null
    remoteParticpants = {}


Errors are a part of every project lifecycle. If your Peers are having issues starting or joining calls, we provide detailed call logs to help you diagnose. These logs include information such as:

If you are not able to resolve the issue on your own, please contact your Between consultant.

Next Steps

Your participants will want to do more than just start and join a call. They'll want to plug in their headphones, mute someone else, and more. Click here to learn how to do this.