The standard WebRTC configuration offers the simplest way to enable voice calls directly within your Rocket.Chat workspace. It uses the built-in WebRTC capabilities of modern browsers, allowing users to make and receive voice calls without needing external telephony or SIP infrastructure. It’s ideal for teams that want a quick and easy voice call solution for internal communication.
This guide explains how to enable and configure Rocket.Chat Voice for intra-workspace calls using the standard WebRTC configuration.
How Rocket.Chat Voice Works with WebRTC
Rocket.Chat Voice uses WebRTC to establish a secure, direct, peer-to-peer media link between the calling and receiving users’ browsers. Once this connection is established, it enables the direct exchange of audio data between users.
The Rocket.Chat server acts as a signaling server, managing the call setup process. It coordinates the call request, notifies the recipient, and facilitates the exchange of WebRTC parameters (such as ICE candidates) for connection negotiation. After signaling is complete, the two user clients establish a direct peer-to-peer WebRTC connection, allowing them to exchange audio without the Rocket.Chat server ever handling or relaying the media stream.
Overcoming network challenges (NAT traversal)
One of the main technical challenges in peer-to-peer communication is Network Address Translation (NAT), since users are often located behind firewalls or private networks. NAT can prevent browsers from discovering each other’s real network addresses, making direct communication difficult.
To ensure a reliable connection, Rocket.Chat strongly recommends servers for ICE (Interactive Connectivity Establishment) to negotiate a network path. ICE includes two key servers:
STUN (Session Traversal Utilities for NAT): Helps a client discover its own public IP address and port when behind a NAT, allowing it to attempt a direct, low-latency connection to another peer.
TURN (Traversal Using Relays around NAT): When a direct P2P connection is impossible (e.g., due to restrictive firewalls), the TURN server acts as an audio relay, routing the entire media stream to guarantee the call connects.
By default, STUN is enabled using the public service provided by Google. For better control and reliability, configure your own STUN servers in ICE servers and your TURN servers in TURN servers, as described in Configure WebRTC settings.
Prerequisites
Before you begin, confirm you have the following:
An active premium plan.
The Rocket.Chat Voice add-on
If you don’t have these, contact the Sales Team.
Configure WebRTC settings
Once the prerequisites are met, the next step is to configure the WebRTC network settings in your workspace.
In your Rocket.Chat workspace, navigate to Manage → Workspace → Settings → Team voice calls (VoIP).
Go to WebRTC settings and update the following fields:
Field
Description
Screen sharing
Enable users to share their screen during voice calls for improved collaboration. Visit the Screen sharing guide for more details.
Mobile ringing
Allow users to make and receive voice calls using the mobile app. Visit the Configure voice calls on mobile guide for more details.
ICE servers
Enter a comma-separated list of STUN and/or TURN servers used to gather network address candidates for Voice calls. Only one working address is needed for a call, but all configured servers are contacted before the call starts.
Format:
[username:password@]stun:host:portor[username:password@]turn:host:portUsernames and passwords may be HTML-encoded.
By default, STUN is enabled using the public service provided by Google.
This setting is readable by anyone who can reach your workspace. Enter TURN servers that need credentials in TURN servers instead. See Configure private TURN servers.
ICE gathering timeout
Specify how long (in milliseconds) the system should wait for ICE candidate gathering to complete before starting a call.
A longer timeout ensures TURN servers have time to respond, but may delay call setup. For local or STUN-only setups, a shorter timeout may reduce call startup delays.
TURN servers
Enter a JSON list of TURN servers and their credentials. The field is empty by default. Unlike ICE servers, this setting isn't public. See Configure private TURN servers for the format.
Click Save changes.
After saving the configuration, your workspace is now ready to handle voice calls using the standard WebRTC engine.
Configure private TURN servers
Use the TURN servers setting in WebRTC settings to keep TURN servers and their credentials out of public settings. The setting appears directly after ICE gathering timeout.
The workspace sends the servers in TURN servers, with the credentials for that user, only to the users on a call, when the call starts. Users who aren't on a call never receive them. During a call, clients use the servers in ICE servers first, followed by the servers in TURN servers.
Workspace admins see the stored usernames, credentials, and secrets in plain text, both in the field and through the REST API. Users with the default user role and people who aren't signed in can't read the setting. When the setting changes, the settings audit log records the change with the value masked.
Anyone who can reach your workspace can read ICE servers, including people who aren't signed in. ICE servers accepts TURN entries with a username and password without any warning, and those credentials become readable too. Keep only STUN servers there, and move every TURN server with a username and password to TURN servers.
TURN servers format
Enter a JSON list. Each entry has a urls field and an optional auth field:
urls: required. Onestun:,stuns:,turn:, orturns:address, or a list of addresses.auth: optional. The credentials for the server. Each entry uses one type only. The following table describes each type.
| Description |
|---|---|
No | The server address with no credentials. |
| Fixed credentials. Enter the Every user on a call receives the same long-lived credentials and can reuse them until you change them on the TURN server. If your TURN server supports it, use |
| Credentials issued for each user from |
The following example adds one server with fixed credentials and one server that uses a shared secret:
[
{ "urls": "turn:legacy.example.com:3478", "auth": { "type": "static", "username": "rocketchat", "credential": "your-turn-password" } },
{
"urls": ["turn:turn.example.com:3478", "turns:turn.example.com:443?transport=tcp"],
"auth": { "type": "shared-secret", "secret": "your-shared-secret", "ttl": 3600 }
}
]The workspace checks the value before saving it:
If the field doesn't contain valid JSON, Invalid JSON appears under the field and Save changes is unavailable.
If the JSON is valid but doesn't match this format, clicking Save changes shows an error message and the setting keeps its previous value. For example, a single object instead of a list, a
shared-secretentry withoutsecret, attllower than 60, or astaticentry that also hassecretisn't saved.If an invalid value reaches the workspace another way, for example through an environment variable, the workspace ignores it, logs an error, and sends no servers from TURN servers to users.
Use time-limited credentials with a shared secret
To use a shared secret, your TURN server must support shared-secret authentication, also known as the TURN REST API. For example, coturn supports it with the use-auth-secret option. The secret in TURN servers must match static-auth-secret on the TURN server.
For each user on a call, the workspace issues a username in the format <expiry timestamp>:<user ID> and a password calculated from that username and the secret (HMAC-SHA1, Base64-encoded). The TURN server checks these credentials on its own, without contacting Rocket.Chat, and rejects them after they expire. Because the secret is a workspace setting, every Rocket.Chat instance in a multi-instance deployment issues credentials the TURN server accepts.
On your TURN server, turn on shared-secret authentication and set
static-auth-secretto your secret. See Example coturn configuration.In TURN servers, add an entry for the server with
"auth": { "type": "shared-secret", "secret": "<your secret>" }. Use the same secret as on the TURN server.In ICE servers, remove every entry in the
username:password@turn:host:portformat, so that only STUN servers remain.Click Save changes.
After you save, the public ICE servers setting holds only STUN servers, and the TURN server and its secret are stored only in TURN servers.
Example coturn configuration
The following coturn configuration uses a shared secret, listens for TURN over TLS on port 443, and blocks relaying to private and loopback addresses so the TURN server can't be used to reach your internal network:
listening-port=3478
tls-listening-port=443
cert=/etc/coturn/fullchain.pem
pkey=/etc/coturn/privkey.pem
realm=turn.example.com
use-auth-secret
static-auth-secret=<the same value as the secret in TURN servers>
fingerprint
no-cli
no-multicast-peers
# Never relay into private or loopback ranges
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=::1
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
# Limit what a single credential can consume
user-quota=12
total-quota=1200TURN over TLS on port 443 (
turns:addresses) can get through restrictive networks that allow outbound TLS on port 443. Proxies that inspect HTTPS traffic still block it.If your media servers are on a private network that the TURN server must reach, add an
allowed-peer-ipline for exactly those addresses instead of removing the denied ranges.
Choose a credential lifetime
The ttl value controls how long the credentials issued from a shared secret stay valid. Consider the following when you choose it:
The workspace issues credentials when a call starts, and again when a user's app reconnects and resyncs the call. A connection that already exists keeps the credentials it started with.
A relay that's already in use keeps working after its credentials expire. However, if a user's network changes after the credentials expire, for example when they switch from Wi-Fi to mobile data, the call can't reconnect. Set
ttllonger than your longest expected call.A deactivated user's credentials stay valid until they expire. A shorter lifetime makes this window smaller.
The workspace and the TURN server compare an absolute timestamp, so keep both clocks in sync, for example with NTP. This matters most with short lifetimes.
The default is 86400 seconds (24 hours). For a more secure setup, use a lifetime between one and a few hours, for example 3600 to 14400 seconds.
Verify the TURN configuration
After you configure a shared secret, start a call and check the following:
In the browser's developer tools, the WebSocket message that starts the call includes
iceServerswith a username in the<timestamp>:<user ID>format. The shared secret never appears.With coturn, running
turnutils_uclient -u '<username>' -w '<credential>' turn.example.comwith the credentials from that message succeeds. After the timestamp passes, coturn responds with401 Unauthorized.With the browser limited to relayed connections,
chrome://webrtc-internalsshows a selected candidate pair of typerelay.
Next steps
After configuring WebRTC, Set up Rocket.Chat Voice Permissions to define which users can access calling features. Once permissions are set, end users can follow the Rocket.Chat Voice User Guide to start making calls.