Skip to main content

Outbound Calling Script

Script that makes outbound calls via LiveKit Telephony using the LiveKit API

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 .env.local in this directory with your LiveKit credentials and SIP trunk settings:

    LIVEKIT_URL=your_livekit_url
    LIVEKIT_API_KEY=your_api_key
    LIVEKIT_API_SECRET=your_api_secret
    SIP_TRUNK_HOSTNAME=your_sip_server
    SIP_AUTH_USERNAME=your_username
    SIP_AUTH_PASSWORD=your_password
    SIP_FROM_NUMBER=your_sip_number
  • Configure a SIP trunk with your SIP provider. You can pass trunk configuration inline (shown below) or use a stored outbound trunk.

  • 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
from livekit.protocol.sip import SIPOutboundConfig
load_dotenv(".env.local")
logger = logging.getLogger("make-call")
logger.setLevel(logging.INFO)

Configure room, agent, and trunk

Set the room name, agent dispatch target, and SIP trunk settings pulled from the environment.

room_name = "my-room"
agent_name = "test-agent"
sip_trunk_hostname = os.environ["SIP_TRUNK_HOSTNAME"]
sip_auth_username = os.environ["SIP_AUTH_USERNAME"]
sip_auth_password = os.environ["SIP_AUTH_PASSWORD"]
sip_from_number = os.environ["SIP_FROM_NUMBER"]

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
)
)
await lkapi.sip.create_sip_participant(
api.CreateSIPParticipantRequest(
trunk=SIPOutboundConfig(
hostname=sip_trunk_hostname,
auth_username=sip_auth_username,
auth_password=sip_auth_password,
),
sip_number=sip_from_number,
room_name=room_name,
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

python make_call.py

How it works

  1. An agent dispatch starts the target agent in the specified room.
  2. A SIP participant is created with inline trunk configuration to dial the user's phone number.
  3. Once connected, the caller and agent are in the same LiveKit room.
  4. 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
from livekit.protocol.sip import SIPOutboundConfig
load_dotenv(".env.local")
logger = logging.getLogger("make-call")
logger.setLevel(logging.INFO)
room_name = "my-room"
agent_name = "test-agent"
sip_trunk_hostname = os.environ["SIP_TRUNK_HOSTNAME"]
sip_auth_username = os.environ["SIP_AUTH_USERNAME"]
sip_auth_password = os.environ["SIP_AUTH_PASSWORD"]
sip_from_number = os.environ["SIP_FROM_NUMBER"]
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}")
logger.info(f"Dialing {phone_number} to room {room_name}")
try:
sip_participant = await lkapi.sip.create_sip_participant(
api.CreateSIPParticipantRequest(
trunk=SIPOutboundConfig(
hostname=sip_trunk_hostname,
auth_username=sip_auth_username,
auth_password=sip_auth_password,
),
sip_number=sip_from_number,
room_name=room_name,
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())