@tetrax/voice-sdk
v1.2.1
Published
Tetrax CPaaS — Multi-product SDK. Voice (WebRTC audio rooms), SMS (send & track), and Video (room management) for web and React Native.
Maintainers
Readme
@tetrax/voice-sdk
Tetrax CPaaS — Multi-Product Client SDK · v1.2.0
Client SDK for the Tetrax Communications Platform as a Service (CPaaS). Provides JavaScript/TypeScript clients for Voice, SMS, and Video APIs — works in web browsers and React Native.
Platform: Tetrax CPaaS (tetrax.io)
Product: Voice API ● Available Now
SMS API ● Available Now
Video API ● Available NowInstallation
npm install @tetrax/voice-sdkOr reference locally (monorepo / development):
"dependencies": {
"@tetrax/voice-sdk": "file:../tetrax-sdk"
}Named Exports
import { Voice } from '@tetrax/voice-sdk'; // WebRTC audio rooms
import { Sms } from '@tetrax/voice-sdk'; // SMS send & delivery tracking
import { Video } from '@tetrax/voice-sdk'; // Video room managementBackward compatible:
import { TetraxVoice } from '@tetrax/voice-sdk'still works — it is an alias ofVoice.
Quick Start — Voice
import { Voice } from '@tetrax/voice-sdk';
// 1. Initialize
const voice = new Voice({
apiKey: 'trx_voice_your_key_here',
apiUri: 'https://api.tetrax.io' // or your self-hosted server
});
// 2. Register event listeners
voice.on('track', ({ stream, userId }) => {
const audio = new Audio();
audio.srcObject = stream;
audio.play();
});
voice.on('user-joined', ({ userId }) => console.log(`${userId} joined`));
voice.on('user-left', ({ userId }) => console.log(`${userId} left`));
voice.on('user-muted', ({ userId }) => { /* update UI */ });
voice.on('user-unmuted', ({ userId }) => { /* update UI */ });
voice.on('warning', (msg) => console.warn(msg));
// 3. Obtain a short-lived token from your backend:
// POST /v1/token { apiKey, userId } → { token }
const { token } = await fetch('/api/voice-token').then(r => r.json());
// 4. Connect and join
await voice.connect(token);
await voice.joinRoom('room_a4f91bc2d8e3');
// 5. Mic controls
await voice.mute();
await voice.unmute();
// 6. Leave
await voice.leaveRoom();
voice.disconnect();Quick Start — SMS
import { Sms } from '@tetrax/voice-sdk';
const sms = new Sms({
apiKey: 'trx_sms_your_key_here',
apiUri: 'https://api.tetrax.io',
token: customerJwt, // required for getLogs / getStats
});
// Send a message
const result = await sms.send({
to: '+919876543210',
from: 'TETRAX', // optional — falls back to server default
body: 'Hello from Tetrax!',
});
// → { messageId, status, provider, segments, cost }
// Dashboard helpers (require customer JWT)
const logs = await sms.getLogs();
const stats = await sms.getStats();
// → { total, delivered, failed, sent, queued }Quick Start — Video
import { Video } from '@tetrax/voice-sdk';
const video = new Video({
apiKey: 'trx_video_your_key_here',
apiUri: 'https://api.tetrax.io',
token: customerJwt, // required for getLiveRooms / closeRoom / getStats
});
// Create a video room (API key auth)
const room = await video.createRoom({ name: 'Team Standup', maxParticipants: 25 });
// → { roomId, name, status, maxParticipants, createdAt }
// Dashboard helpers (customer JWT required)
const rooms = await video.getLiveRooms();
const ok = await video.closeRoom(room.roomId);
const stats = await video.getStats();
// → { total, active }API Reference — Voice
new Voice(options) (alias: new TetraxVoice(options))
| Option | Type | Required | Description |
|---|---|---|---|
| apiKey | string | ✓ | Your trx_voice_ API key from the Tetrax Console |
| apiUri | string | ✓ | Signaling server URL (e.g. https://api.tetrax.io) |
| socketOptions | object | — | Extra options passed to socket.io-client |
| mediaDevices | object | — | Custom mediaDevices implementation (React Native) |
| MediaStream | class | — | Custom MediaStream class (React Native) |
Methods
| Method | Returns | Description |
|---|---|---|
| connect(token) | Promise<void> | Connect to signaling server using a voice token |
| joinRoom(roomId, opts?) | Promise<res> | Join a room and set up audio send/receive |
| mute() | Promise<void> | Pause local audio producer + emit mute signal |
| unmute() | Promise<void> | Resume local audio producer + emit unmute signal |
| leaveRoom() | Promise<void> | Leave room, stop local tracks, close transports |
| disconnect() | void | Disconnect from signaling server entirely |
joinRoom(roomId, options?)
| Option | Type | Description |
|---|---|---|
| audioTrack | MediaStreamTrack | Pre-captured audio track (skip getUserMedia) |
| localStream | MediaStream | Pre-captured stream — uses first audio track |
| audioConstraints | object | Passed to getUserMedia if no track/stream provided |
Events
| Event | Payload | Fired when |
|---|---|---|
| connected | — | Successfully connected to signaling server |
| joined | res | Successfully joined a room |
| track | { track, stream, userId, consumerId } | A remote participant's audio track is ready to play |
| user-joined | { userId } | A participant joined the room |
| user-left | { userId } | A participant left the room |
| user-muted | { userId } | A remote participant muted |
| user-unmuted | { userId } | A remote participant unmuted |
| local-mute-changed | boolean | Local mute state changed (true = muted) |
| warning | string | Non-fatal warning (e.g. listen-only mode due to no mic) |
| error | Error | Connection error |
API Reference — Sms
new Sms({ apiKey, apiUri, token? })
| Method | Auth | Returns | Description |
|---|---|---|---|
| send({ to, from?, body }) | API key | { messageId, status, provider, segments, cost } | Send an SMS via POST /v1/sms/send |
| getLogs() | JWT | Array<SmsLog> | Delivery logs via GET /v1/sms |
| getStats() | JWT | { total, delivered, failed, sent, queued } | Stats via GET /v1/sms/stats |
API Reference — Video
new Video({ apiKey, apiUri, token? })
| Method | Auth | Returns | Description |
|---|---|---|---|
| createRoom({ name?, maxParticipants? }) | API key | { roomId, name, status, maxParticipants, createdAt } | Create room via POST /v1/video/rooms |
| getLiveRooms() | JWT | { rooms, total } | Live rooms via GET /v1/video/rooms/live |
| closeRoom(roomId) | JWT | boolean | Close room via DELETE /v1/video/rooms/:id |
| getStats() | JWT | { total, active } | Stats via GET /v1/video/stats |
Frontend Implementation Guides
1. Next.js (App Router / Pages Router)
Add serverExternalPackages so Next.js doesn't bundle React Native bindings on the server:
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
serverExternalPackages: ['react-native-webrtc'],
};
export default nextConfig;Use 'use client' components:
'use client';
import { Voice } from '@tetrax/voice-sdk';
export default function VoiceRoom() {
const startCall = async (token) => {
const voice = new Voice({ apiKey: 'trx_voice_xxx', apiUri: 'https://api.tetrax.io' });
voice.on('track', ({ stream }) => {
const audio = new Audio();
audio.srcObject = stream;
audio.autoplay = true;
document.body.appendChild(audio);
});
await voice.connect(token);
await voice.joinRoom('room_demo');
};
return <button onClick={startCall}>Join Voice Room</button>;
}2. React (Vite / Create React App)
Webpack and Vite automatically respect the "browser" field — SDK works out-of-the-box:
import { Voice, Sms, Video } from '@tetrax/voice-sdk';3. React Native
The SDK auto-detects React Native via navigator.product === 'ReactNative' and registers WebRTC globals automatically:
import { Voice } from '@tetrax/voice-sdk';
const voice = new Voice({
apiKey: 'trx_voice_xxx',
apiUri: 'http://YOUR_SERVER_IP:5000',
socketOptions: { transports: ['websocket'] }
});
// Pre-captured audio track:
const stream = await mediaDevices.getUserMedia({ audio: true });
await voice.connect(token);
await voice.joinRoom('room_123', { audioTrack: stream.getAudioTracks()[0] });SDK Metadata
import { TETRAX_SDK_INFO, SDK_VERSION } from '@tetrax/voice-sdk';
console.log(TETRAX_SDK_INFO);
// {
// platform: 'tetrax-cpaas',
// version: '1.2.0',
// products: ['voice', 'sms', 'video'],
// }API Key Namespace
| Product | Key Prefix | Status |
|---|---|---|
| Voice API | trx_voice_ | ✅ Available |
| SMS API | trx_sms_ | ✅ Available |
| Video API | trx_video_ | ✅ Available |
Get your API keys from the Tetrax Console → Applications.
Publishing to npm
# Inside tetrax-sdk/
npm login
npm publish --access publicChangelog
v1.2.0
- Multi-product SDK: Added
SmsandVideonamed exports alongside existingVoice Voiceis the new canonical class name;TetraxVoiceis kept as a backward-compat alias- Restructured into
src/voice/,src/sms/,src/video/sub-modules - Updated
SDK_VERSIONandTETRAX_SDK_INFO.productsto reflect all three products
v1.1.5
- Minor dependency updates
v1.1.4
- Fixed Next.js (Turbopack/Webpack) module resolution errors by properly aliasing
react-native-webrtcin the"browser"package field
v1.1.3
- CPaaS rebranding:
TETRAX_SDK_INFOandSDK_VERSIONexports - API key namespace documented (
trx_voice_) - README restructured with full API reference table
v1.1.2
- React Native auto-detection and
react-native-webrtcglobal registration - Pre-captured track/stream support via
joinRoomoptions - Listen-only mode fallback when no microphone is available
License
MIT © Tetrax Inc.
