steep-mechanic-38687
02/27/2026, 9:46 AMtall-airline-16756
02/27/2026, 9:46 AMtall-airline-16756
02/27/2026, 9:46 AMcreateSipParticipant with the LiveKit Node.js SDK.
Short answer: the SDK surfaces provider (Twilio) rejections as a TwirpError whose metadata includes sip_status_code and sip_status. A Twilio rate-limit rejection will show a SIP status code of 429 (Too Many Requests).
Example detection pattern (Node.js / TypeScript):
import { TwirpError } from 'twirp-rpc'; // or the Twirp error type your environment uses
import { SipClient } from 'livekit-server-sdk';
try {
await sipClient.createSipParticipant({
roomName: 'my-room',
sipTrunkId: 'ST_xxx',
sipCallTo: '+1234567890',
});
} catch (err) {
// Check for Twirp/SIP error metadata
if (err instanceof TwirpError) {
const sipStatusCode = err.metadata?.get?.('sip_status_code') ?? err.metadata?.['sip_status_code'];
const sipStatus = err.metadata?.get?.('sip_status') ?? err.metadata?.['sip_status'];
if (sipStatusCode === '429' || (typeof sipStatus === 'string' && sipStatus.includes('429'))) {
// Detected Twilio rate limiting
console.log('Call rejected due to rate limiting (429).');
// Handle: e.g., exponential backoff retry, queue the call, or reduce call concurrency
} else {
console.log('SIP call failed:', sipStatusCode, sipStatus);
}
} else {
console.error('Unexpected error creating SIP participant:', err);
}
}
Suggestions for handling 429:
• Implement exponential backoff and retries.
• Throttle outgoing createSipParticipant calls (limit concurrency or queue requests).
• Monitor how often you see 429s and adjust rate or request pacing accordingly.
If you’d like, tell me:
• Which Twirp/TwirpError package you see in your project (so I can give exact type checks), and
• Whether you want an example of a retry/backoff implementation or a simple queue to throttle calls. Sources: SIP Lifecycle Management Agent | LiveKit Documentation