Get started →
Documentation

WebRTC softphone

Give every agent a business line in their browser. Provision extensions, register a SIP client, and accept or place calls — no desk phones, no installs.

How it works

  1. Each agent is assigned an agent extension on your carrier (e.g. agent-1001).
  2. The browser registers that extension over WebSocket (SIP over WSS) through the client gateway.
  3. Calls to the extension — or ring-group dials — arrive as SIP INVITEs straight to the browser.

Provision an extension

Create an agent extension and get its ephemeral SIP credentials:

Create + fetch credentials in one callts

import { RuutVoice } from "@ruut/voice-sdk";

const client = new RuutVoice({ accountSid, authToken, baseUrl });

// Create + fetch credentials in one call
const creds = await client.agentExtensions.provision({
  agentName: "Adaeze",
});

console.log(creds.username, creds.password, creds.ws_url);
// agent-1001 ******** wss://voice.ruut.chat:8443

Or create the extension first, then fetch credentials:

Examplets

const ext = await client.agentExtensions.create({ agentName: "Adaeze" });
const creds = await client.agentExtensions.credentials(ext.sid);
Credentials are ephemeral and expire (default TTL 24h). Re-fetch or refresh them before expiry, and rotate on a schedule.

Register the browser device

Use the SDK's browser client (@ruut/voice-sdk/browser) to register and answer calls:

Show an Answer button, then:ts

import { RuutDevice } from "@ruut/voice-sdk/browser";

const device = new RuutDevice({
  credentials: {
    username: creds.username,
    password: creds.password,
    domain: creds.domain,
    wsUrl: creds.ws_url,
    agentExtensionId: creds.id,
    restBaseUrl: creds.restBaseUrl,
    restAccountSid: creds.restAccountSid,
    restAuthToken: creds.restAuthToken,
  },
  audioElement: document.querySelector("audio"),
});

device.on("registered", () => console.log("Ready to take calls"));
device.on("incoming", (call) => {
  // Show an Answer button, then:
  call.accept();
});
device.on("callEnded", () => console.log("Call ended"));

await device.start();

Ring groups

Assign the account's numbers to a ring group so every online, registered agent in the group rings simultaneously. The first to answer claims the call; the others are released. Agents must be marked online and registered to be dialed.

Dial an agent from the API

Route an inbound call (or an API-created call) to an agent extension using <Dial> with the agent's SIP URI:

TwiMLxml


  sip:agent-1001@sip.ruut.chat

Or use the SDK helper:

Examplets

await client.calls.createAgentCall({
  agentUsername: "agent-1001",
  sipDomain: "sip.ruut.chat",
  from: "+2348000000002",
  twiml: new VoiceResponse().say("Connecting you to an agent.").toXml(),
});

Presence & status

Update an agent's availability (which ring groups consider when dialing):

Examplets

await client.agentExtensions.update("AE…", { status: "online", ttlSeconds: 3600 });

Statuses: online, offline, busy, away, dnd.

Next