broad-boots-9735
03/03/2026, 7:55 PMtall-airline-16756
03/03/2026, 7:55 PMtall-airline-16756
03/03/2026, 7:55 PMbroad-boots-9735
03/03/2026, 7:56 PMtall-airline-16756
03/03/2026, 7:56 PMlk sip outbound list (or from the Console).
• Confirm your agent is connected in the target room (room name and agent identity).
• Confirm network/auth from your Python app can reach the LiveKit control API.
Python example (outline):
1) Install the LiveKit Python client (if you already have the SDK, use it; otherwise use the requests HTTP client). 2) Call the Create SIP Participant endpoint with the room name, trunk id, and the number to call.
Minimal example using a generic HTTP POST (replace placeholders):
import requests
import os
LIVEKIT_API_URL = "<https://api.livekit.example/v1>" # replace with your LiveKit control API base URL
API_KEY = os.environ.get("LIVEKIT_API_KEY")
API_SECRET = os.environ.get("LIVEKIT_API_SECRET")
ROOM_NAME = "my-room"
SIP_TRUNK_ID = "ST_..." # obtain from lk sip outbound list or Console
TO_NUMBER = "+1234567890" # number you want to call
PARTICIPANT_ID = "caller"
# Example payload - adapt field names to your control API's request schema
payload = {
"room_name": ROOM_NAME,
"sip_trunk_id": SIP_TRUNK_ID,
"sip_call_to": TO_NUMBER,
"participant_identity": PARTICIPANT_ID
}
# Simple auth header example — adapt to your auth method (API key/secret, bearer token, etc.)
headers = {
"Authorization": f"Basic {API_KEY}:{API_SECRET}",
"Content-Type": "application/json"
}
resp = <http://requests.post|requests.post>(f"{LIVEKIT_API_URL}/sip/participants", json=payload, headers=headers)
print(resp.status_code, resp.text)
Notes and next steps:
• If you use the official LiveKit Python SDK, the function name will be similar to create_sip_participant (use the SDK’s request object and auth).
• If you get authentication errors, confirm your API credentials and endpoint URL.
• If you get a “No sip exists” error again, confirm the SIP trunk ID and that the trunk is active.
If you want, tell me:
• The SIP method you’re using (LiveKit phone number vs third‑party provider).
• The room name and agent identity.
I’ll provide a tailored Python snippet using the LiveKit Python client (or exact HTTP endpoint and required JSON schema) and the exact auth header format you should use.broad-boots-9735
03/03/2026, 8:11 PMtall-airline-16756
03/03/2026, 8:11 PMbroad-boots-9735
03/03/2026, 8:15 PMtall-airline-16756
03/03/2026, 8:15 PMbroad-boots-9735
03/03/2026, 8:15 PMtall-airline-16756
03/03/2026, 8:16 PMnpm install livekit-server-sdk
2) Server-side: create room / generate join tokens
• Use RoomServiceClient to manage rooms if you need server-side control (optional — rooms are auto-created when participants join).
• Use AccessToken to mint tokens for each participant/agent.
Example (ES module):
import { RoomServiceClient, AccessToken, Grants } from 'livekit-server-sdk';
// Set these env vars: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, LIVEKIT_URL (e.g. "<https://your-livekit-host>")
const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_API_SECRET;
const livekitHost = process.env.LIVEKIT_URL; // should include protocol and host
// Optional: use RoomServiceClient when you want to create/update rooms or list participants
const roomService = new RoomServiceClient(apiKey, apiSecret, { host: livekitHost });
// Helper to create a JWT token for a participant
function createJoinToken(identity, roomName) {
const at = new AccessToken(apiKey, apiSecret, { identity });
// grant join to a single room
const grants = new Grants({ roomJoin: true, room: roomName });
at.addGrant(grants);
return at.toJwt();
}
// Example usage
const roomName = 'my-webrtc-room';
const agentIdentity = 'agent-123';
const userIdentity = 'user-456';
// Optionally ensure room exists (rooms are usually auto-created on join)
async function ensureRoom(name) {
try {
await roomService.createRoom({ name });
} catch (err) {
// ignore if already exists or handle errors as needed
}
}
(async () => {
await ensureRoom(roomName);
const agentToken = createJoinToken(agentIdentity, roomName);
const userToken = createJoinToken(userIdentity, roomName);
// Return these tokens to the clients that will connect (agent and user)
console.log('agent token:', agentToken);
console.log('user token:', userToken);
})();
3) Client-side (browser or Node WebRTC client)
• Clients use the tokens you generated to connect via the LiveKit client SDK (livekit-client).
• Example (browser):
import { Room } from 'livekit-client';
const room = new Room();
await room.connect("<wss://your-livekit-ws-host>", agentToken);
// publish tracks or subscribe as needed
Notes and tips
• If you want the server itself to act as a participant (publish audio/video from the server), you can use a headless WebRTC client or a server-side WebRTC implementation to join the room with the token you generated for the server identity.
• Use RoomServiceClient when you need explicit room lifecycle management (create, list participants, force disconnect, etc.). If you only need to mint tokens, creating tokens alone is sufficient because rooms are created automatically when the first participant joins.
• Keep tokens short-lived in production for security; mint them per-join request and return to authenticated clients.
• Ensure your LIVEKIT_URL (and WS URL used by clients) match your deployment and that your server can reach the LiveKit control endpoint.
If you’d like, I can:
• Provide a full example where the server creates an "agent" token and immediately triggers a web client connection (useful to simulate Console Run).
• Show how to publish an audio track from a Node.js process (server-side participant) if you need the server to actively send audio into the room.
Which of those would help you next — a server-as-participant example, or full client + server token flow?
Sources: Server-side | livekit/livekit_composite | DeepWiki