RelayClient

View as MarkdownOpen in Claude

RelayClient manages a persistent WebSocket connection to SignalWire’s RELAY service. It handles authentication, automatic reconnection with exponential backoff, inbound event dispatch, outbound dialing, and SMS/MMS messaging. Use it when you need imperative, event-driven control over calls rather than the declarative AI agent approach.

The client supports two authentication modes: project ID + API token, or JWT token. Credentials can be passed directly or read from environment variables.

Properties

project
string

SignalWire project ID. Set via constructor or SIGNALWIRE_PROJECT_ID environment variable.

token
string

API token for authentication. Set via constructor or SIGNALWIRE_API_TOKEN environment variable.

jwtToken
string

JWT token for alternative authentication. Set via constructor or SIGNALWIRE_JWT_TOKEN environment variable. When provided, project and token are not required.

host
stringDefaults to relay.signalwire.com

SignalWire space hostname (e.g., your-space.signalwire.com). Set via constructor or SIGNALWIRE_SPACE environment variable.

contexts
string[]Defaults to []

List of contexts to subscribe to for inbound call and message events.

maxActiveCalls
number | undefinedDefaults to 1000

Maximum number of concurrent inbound calls the client will track. Calls arriving beyond this limit are dropped with a log warning. Set via constructor or RELAY_MAX_ACTIVE_CALLS environment variable. Constructor-only — not accessible as a public attribute after initialization.

relayProtocol
string

Server-assigned protocol string from the connect response. Read-only. Used internally for session resumption on reconnect.

Methods

Async Disposable

RelayClient implements Symbol.asyncDispose, so it can be used with the await using statement for scoped connections. The client disconnects automatically when the scope exits.

1import { RelayClient } from '@signalwire/sdk';
2
3async function main() {
4 await using client = new RelayClient({
5 project: process.env.SIGNALWIRE_PROJECT_ID!,
6 token: process.env.SIGNALWIRE_API_TOKEN!,
7 contexts: ['default'],
8 });
9 await client.connect();
10 const call = await client.dial([
11 [{ type: 'phone', params: { to_number: '+15559876543', from_number: '+15551234567' } }],
12 ]);
13 // Automatically disconnects on exit
14}
15
16await main();

For environments without await using support, use try/finally with disconnect().

Example

1import { RelayClient } from '@signalwire/sdk';
2
3const client = new RelayClient({
4 project: process.env.SIGNALWIRE_PROJECT_ID!,
5 token: process.env.SIGNALWIRE_API_TOKEN!,
6 contexts: ['default']
7});
8
9client.onCall(async (call) => {
10 await call.answer();
11 const action = await call.play([{ type: 'tts', text: 'Hello from RELAY!' }]);
12 await action.wait();
13 await call.hangup();
14});
15
16client.onMessage(async (message) => {
17 console.log(`SMS from ${message.fromNumber}: ${message.body}`);
18});
19
20await client.run();