| title | Outbound Calling Script | |||
|---|---|---|---|---|
| category | telephony | |||
| tags |
|
|||
| difficulty | beginner | |||
| description | Script that makes outbound calls via LiveKit Telephony using the LiveKit API | |||
| demonstrates |
|
This example shows how to place an outbound call via LiveKit Telephony. The script creates an agent dispatch, then dials a number through a SIP trunk to connect the caller into the agent's room. This is not an agent itself, but a utility script that triggers an agent and connects a phone call to it.
Prerequisites
- Add a
.envin this directory with your LiveKit credentials:LIVEKIT_URL=your_livekit_url LIVEKIT_API_KEY=your_api_key LIVEKIT_API_SECRET=your_api_secret SIP_OUTBOUND_TRUNK_ID=your_sip_trunk_id - Provision a SIP outbound trunk in LiveKit and set
SIP_OUTBOUND_TRUNK_ID - Install dependencies:
pip install livekit-api dotenv
Load configuration and logging
Load environment variables and set up logging for call status tracking.
import asyncio import os import logging from dotenv import load_dotenv from livekit import api load_dotenv() logger = logging.getLogger("make-call") logger.setLevel(logging.INFO)
Configure room, agent, and trunk
Set the room name, agent dispatch target, and outbound trunk ID pulled from the environment.
room_name = "my-room" agent_name = "test-agent" outbound_trunk_id = os.getenv("SIP_OUTBOUND_TRUNK_ID")
Create the agent dispatch and dial
Use the LiveKit API client to create a dispatch (which starts your agent in the room) and then create a SIP participant to dial the phone number into that room.
async def make_call(phone_number): lkapi = api.LiveKitAPI() dispatch = await lkapi.agent_dispatch.create_dispatch( api.CreateAgentDispatchRequest( agent_name=agent_name, room=room_name, metadata=phone_number ) ) if not outbound_trunk_id or not outbound_trunk_id.startswith("ST_"): logger.error("SIP_OUTBOUND_TRUNK_ID is not set or invalid") return await lkapi.sip.create_sip_participant( api.CreateSIPParticipantRequest( room_name=room_name, sip_trunk_id=outbound_trunk_id, sip_call_to=phone_number, participant_identity="phone_user", ) ) await lkapi.aclose()
Run the script with a number
Provide a phone number (with country code) and run the async entrypoint.
async def main(): phone_number = "+1231231231" await make_call(phone_number) if __name__ == "__main__": asyncio.run(main())
Run it
How it works
- An agent dispatch starts the target agent in the specified room.
- A SIP participant is created via the outbound trunk to dial the user's phone number.
- Once connected, the caller and agent are in the same LiveKit room.
- Close the API client after the call is set up.
Full example
import asyncio import os import logging from dotenv import load_dotenv from livekit import api load_dotenv() logger = logging.getLogger("make-call") logger.setLevel(logging.INFO) room_name = "my-room" agent_name = "test-agent" outbound_trunk_id = os.getenv("SIP_OUTBOUND_TRUNK_ID") async def make_call(phone_number): """Create a dispatch and add a SIP participant to call the phone number""" lkapi = api.LiveKitAPI() logger.info(f"Creating dispatch for agent {agent_name} in room {room_name}") dispatch = await lkapi.agent_dispatch.create_dispatch( api.CreateAgentDispatchRequest( agent_name=agent_name, room=room_name, metadata=phone_number ) ) logger.info(f"Created dispatch: {dispatch}") if not outbound_trunk_id or not outbound_trunk_id.startswith("ST_"): logger.error("SIP_OUTBOUND_TRUNK_ID is not set or invalid") return logger.info(f"Dialing {phone_number} to room {room_name}") try: sip_participant = await lkapi.sip.create_sip_participant( api.CreateSIPParticipantRequest( room_name=room_name, sip_trunk_id=outbound_trunk_id, sip_call_to=phone_number, participant_identity="phone_user", ) ) logger.info(f"Created SIP participant: {sip_participant}") except Exception as e: logger.error(f"Error creating SIP participant: {e}") await lkapi.aclose() async def main(): phone_number = "+1231231231" await make_call(phone_number) if __name__ == "__main__": asyncio.run(main())