Realtime Server SDK

Node.js server SDK for real-time communication through WebSocket connections

View as Markdown
$npm install @signalwire/realtime-api

The SignalWire Realtime SDK v4 is a Node.js server SDK that enables real-time communication through WebSocket connections. Built on an event-driven architecture, it provides dedicated namespaces for voice, video, messaging, chat, pub/sub, and task management.

Getting Started

1

Install the SDK

$npm install @signalwire/realtime-api
2

Create a RELAY Application

For Voice, Messaging, and Task namespaces, create a RELAY Application resource in your dashboard:

  1. Set a name for your application
  2. Choose a reference (e.g., “support”, “sales”) that matches your client’s topics
  3. Assign phone numbers or SIP addresses to route calls to this application
3

Set up authentication

Get your project credentials from the SignalWire Dashboard:

1import { SignalWire } from "@signalwire/realtime-api";
2
3const client = await SignalWire({
4 project: "your-project-id",
5 token: "your-api-token"
6});
7
8// Access namespace clients
9const voiceClient = client.voice;
4

Test your setup

Create a simple inbound call handler to test your setup:

1import { SignalWire } from "@signalwire/realtime-api";
2
3const client = await SignalWire({
4 project: "your-project-id",
5 token: "your-api-token"
6});
7
8const voiceClient = client.voice;
9
10// Answer incoming calls and play a greeting
11await voiceClient.listen({
12 topics: ["support"], // Must match your RELAY Application reference
13 onCallReceived: async (call) => {
14 console.log("Incoming call from:", call.from);
15
16 await call.answer();
17 await call.playTTS({ text: "Welcome to SignalWire!" });
18 }
19});
20
21console.log("Waiting for calls...");

Now call the SignalWire phone number or SIP address you assigned to your RELAY Application in step 2. Your application will answer and play the greeting!

Core Concepts

WebSocket Event Architecture

The SDK operates on a bidirectional WebSocket connection between your application and SignalWire’s servers. This enables real-time communication through a structured event system:

When you call a method like client.dialPhone(), the SDK sends your request over the WebSocket connection and SignalWire processes it and responds immediately. These method calls follow a request-response pattern - the returned promise resolves with the result data, such as a Call object containing all the details of your newly created call.

The listen() methods handle a different communication pattern: real-time event notifications. These are asynchronous events triggered by external actions - like when someone calls your number (onCallReceived), sends you a message (onMessageReceived), or when something happens in a video room you’re monitoring (onMemberJoined). Unlike method responses, these events arrive whenever the triggering action occurs, not as a direct response to your code.

Authentication and Access Control

All SDK clients authenticate using project credentials. Voice, Messaging, and Task namespaces also require topic subscriptions that control event routing:

1import { SignalWire } from "@signalwire/realtime-api";
2
3const client = await SignalWire({
4 project: "your-project-id", // SignalWire project identifier
5 token: "your-project-token" // API token from project settings
6});
7
8const voiceClient = client.voice;
9
10// Voice, Messaging, and Task require topics for event routing
11await voiceClient.listen({
12 topics: ["support", "sales"], // Required for Voice, Messaging, Task
13 onCallReceived: (call) => { /* handle call */ }
14});

Your project ID and token are available in the SignalWire Dashboard. These authenticate your WebSocket connection and establish your access permissions.

Topics (formerly contexts) work with RELAY Application resources to route events. When you assign a phone number or a SIP address to a RELAY Application with reference “support”, SignalWire routes all calls from that number or SIP address to SDK clients authenticated with the “support” topic. This creates strict access control - a client subscribed to “support” cannot receive events intended for “sales”.

The routing process is straightforward: incoming calls hit a phone number or a SIP address, SignalWire checks the RELAY Application’s reference, then delivers the event only to clients with matching topics. This happens automatically based on your authentication.

1// Topic-based client (receives events only for subscribed topics)
2await voiceClient.listen({
3 topics: ["support", "sales"], // Only receive calls for these topics
4 onCallReceived: (call) => { /* handle call */ }
5});
6
7// Non-topic client (receives all events for the project)
8await videoClient.listen({
9 onRoomStarted: (roomSession) => { /* handle room */ } // No topics needed
10});

Available Namespaces