The official JavaScript SDK for Unbound's comprehensive communication and AI platform. This SDK provides easy access to messaging (SMS/Email), voice calling, video conferencing, AI services, workflows, and data management capabilities.
- 🚀 Universal: Works in Node.js and browsers
- 📱 Messaging: SMS/MMS and Email with templates and campaigns
- 📞 Voice: Call management, conferencing, recording, transcription
- 📹 Video: Video conferencing with advanced controls
- 🤖 AI: Generative AI chat and text-to-speech
- 💾 Data: Object management with queries and relationships
- 🔄 Workflows: Programmable workflow execution
- 🔌 Extensible: Plugin system for transports and extensions
- ⚡ Performance: Automatic transport optimization (NATS/Socket/HTTP)
npm install @unboundcx/sdk
For enhanced functionality, you may also install:
# For Socket.io transport (browser environments)
npm install socket.io-client
# For improved MIME type detection
npm install mime-types
import SDK from '@unboundcx/sdk';
// Initialize the SDK
const api = new SDK({
namespace: 'your-namespace',
token: 'your-jwt-token',
});
// Or using legacy positional parameters (backwards compatible)
const api = new SDK('your-namespace', null, 'your-jwt-token');
// Login (gets JWT token)
const login = await api.login.login('username', 'password');
// Send SMS
const sms = await api.messaging.sms.send({
from: '+1234567890',
to: '+0987654321',
message: 'Hello from Unbound!',
});
// Create video meeting
const meeting = await api.video.createRoom({
name: 'Team Meeting',
startTime: '2024-01-15T10:00:00Z',
duration: 60,
});
import SDK from '@unboundcx/sdk';
import { socketAppStore } from './stores/socket.js';
// Initialize for browser usage
const api = new SDK({
namespace: 'your-namespace',
socketStore: socketAppStore, // Optional: for optimized WebSocket transport
});
// The SDK automatically connects to your-namespace.api.unbound.cx
const objects = await api.objects.query('contacts', {
limit: 10,
orderBy: 'createdAt',
});
import SDK from '@unboundcx/sdk';
// Initialize for server-side usage
const api = new SDK({
namespace: 'your-namespace',
token: 'jwt-token',
callId: 'call-id', // Optional: for request tracking
});
// Automatically connects to your-namespace.api.unbound.cx
const result = await api.objects.create('leads', {
name: 'John Doe',
email: 'john@example.com',
phone: '+1234567890',
});
The SDK constructor supports both object-based and legacy positional parameters:
const api = new SDK({
namespace: 'your-namespace', // Required: Your Unbound namespace
token: 'jwt-token', // Optional: JWT authentication token
callId: 'call-123', // Optional: Call tracking ID
fwRequestId: 'request-456', // Optional: Request forwarding ID
socketStore: socketAppStore, // Optional: Socket.io store (browser only)
});
const api = new SDK(
'your-namespace', // namespace
'call-123', // callId
'jwt-token', // token
'request-456', // fwRequestId
);
import { createSDK } from '@unboundcx/sdk';
const api = createSDK({
namespace: 'your-namespace',
token: 'jwt-token',
});
// Login and get session
await api.login.login('username', 'password');
await api.login.logout();
await api.login.validate();
await api.login.changePassword('current', 'new');
// CRUD operations on data objects
await api.objects.create('contacts', {
name: 'John',
email: 'john@example.com',
});
await api.objects.query('contacts', { limit: 10 });
await api.objects.byId('contact-123');
await api.objects.updateById('contacts', 'contact-123', { name: 'Jane' });
await api.objects.deleteById('contacts', 'contact-123');
await api.objects.describe('contacts'); // Get schema
await api.objects.list(); // List all object types
// SMS/MMS
await api.messaging.sms.send({
from: '+1234567890',
to: '+0987654321',
message: 'Hello!',
mediaUrls: ['https://example.com/image.jpg'],
});
// Email
await api.messaging.email.send({
from: 'sender@example.com',
to: 'recipient@example.com',
subject: 'Hello',
htmlBody: '<h1>Hello World!</h1>',
});
// Templates
await api.messaging.sms.templates.create({
name: 'welcome',
message: 'Welcome {{name}}!',
variables: { name: 'string' },
});
// Campaign Management
await api.messaging.campaigns.tollFree.create({
companyName: 'Acme Corp',
phoneNumber: '+1234567890',
description: 'Marketing campaign',
});
// Room Management
const room = await api.video.createRoom({
name: 'Team Meeting',
password: 'secret123',
startTime: '2024-01-15T10:00:00Z',
waitingRoom: true,
hosts: ['user@example.com'],
});
// Join meeting
await api.video.joinRoom(room.id, 'password', 'user@example.com');
// Participant controls
await api.video.mute(room.id, 'participant-id', 'microphone', true);
await api.video.removeParticipant(room.id, 'participant-id');
// Analytics
const analytics = await api.video.getMeetingAnalytics(room.id, {
startTime: '2024-01-15T10:00:00Z',
endTime: '2024-01-15T11:00:00Z',
});
// Make calls
const call = await api.voice.createCall({
to: '+1234567890',
from: '+0987654321',
record: true,
transcribe: true,
});
// Call controls
await api.voice.mute(call.callControlId);
await api.voice.hold(call.callControlId);
await api.voice.sendDtmf(call.callControlId, '1234');
await api.voice.transfer(call.callControlId, '+1555555555');
await api.voice.hangup(call.callControlId);
// Conference calls
const conference = await api.voice.createConference({ name: 'Team Call' });
await api.voice.joinConference(call.callControlId, conference.id);
// Generative AI
const response = await api.ai.generative.chat({
messages: [{ role: 'user', content: 'Hello AI!' }],
model: 'gpt-4',
temperature: 0.7,
method: 'openai',
});
// Text-to-Speech
const audio = await api.ai.tts.create({
text: 'Hello, this is a test message',
voice: 'en-US-Standard-A',
audioEncoding: 'MP3',
});
// Upload files
const files = await api.storage.uploadFiles(fileData, {
classification: 'documents',
isPublic: false,
expireAfter: '30d',
});
// Get files
const fileUrl = api.storage.getFileUrl(files[0].storageId);
await api.storage.deleteFile(files[0].storageId);
// Workflow items
await api.workflows.items.create({
workflowVersionId: 'wf-123',
category: 'communication',
type: 'sendEmail',
settings: { template: 'welcome' },
});
// Connections
await api.workflows.connections.create({
workflowItemId: 'item-1',
workflowItemPortId: 'output',
inWorkflowItemId: 'item-2',
inWorkflowItemPortId: 'input',
});
The SDK automatically optimizes transport based on environment:
- Node.js: NATS → HTTP fallback
- Browser: WebSocket → HTTP fallback
- Always available: HTTP fetch
import SDK from '@unboundcx/sdk';
class CustomTransport {
constructor(config) {
this.config = config;
this.name = 'custom';
}
getPriority() {
return 10;
} // Lower = higher priority
async isAvailable() {
return true; // Check if transport is ready
}
async request(endpoint, method, params, options) {
// Custom transport logic
return response;
}
}
const api = new SDK({ namespace: 'namespace', token: 'token' });
api.addTransport(new CustomTransport({}));
import SDK from '@unboundcx/sdk';
const api = new SDK({ namespace: 'namespace' });
// Add custom functionality via extensions
api.extend({
customMethod: function () {
return this.objects.query('custom', {});
},
});
// Use custom method
await api.customMethod();
import SDK from '@unboundcx/sdk';
// Automatic environment detection
const api = new SDK({ namespace: process.env.UNBOUND_NAMESPACE });
import SDK from '@unboundcx/sdk';
const api = new SDK({
namespace: 'your-namespace',
});
// Automatically connects to your-namespace.api.unbound.cx
import SDK from '@unboundcx/sdk';
import { socketAppStore } from '$lib/stores/socket.js';
const api = new SDK({
namespace: 'your-namespace',
socketStore: socketAppStore, // Enables WebSocket transport
});
// Automatically connects to your-namespace.api.unbound.cx
try {
await api.messaging.sms.send({ to: 'invalid' });
} catch (error) {
console.log(error.name); // 'API :: Error :: https :: POST :: /messaging/sms :: ...'
console.log(error.message); // 'Invalid phone number format'
console.log(error.status); // 400
console.log(error.method); // 'POST'
console.log(error.endpoint); // '/messaging/sms'
}
The SDK includes TypeScript definitions:
import SDK, { MessagingService, VideoService } from '@unboundcx/sdk';
const api: SDK = new SDK({ namespace: 'namespace', token: 'token' });
// Full type safety
const sms: any = await api.messaging.sms.send({
from: '+1234567890',
to: '+0987654321',
message: 'Hello TypeScript!',
});
git clone https://github.com/unbound/sdk-js.git
cd sdk-js
npm install
npm test # Run all tests
npm run test:unit # Unit tests only
npm run test:integration # Integration tests
npm run test:watch # Watch mode
npm run build # Build for production
npm run lint # Check code style
npm run docs # Generate documentation
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.