Overview
LiveKit provides built-in APIs for integrating WhatsApp and Twilio voice calls with LiveKit rooms. Connector clients are available in the following SDKs:
- Node.js Connector client
- Python Connector client
- Go Connector client
- Kotlin Connector client
- Rust Connector client
Requests to the connector APIs require the appropriate credentials for the connector you're using.
To learn more about connector integrations, see Connectors.
Installation
npm install livekit-server-sdk
pip install livekit-api
go get github.com/livekit/server-sdk-go/v2
// build.gradle.ktsdependencies {implementation("io.livekit:livekit-server:0.13.0")}
# Cargo.toml[dependencies]livekit-api = { version = "0.4", features = ["services-tokio", "native-tls"] }
Creating a client
Create a new connector client instance with your LiveKit server URL and API credentials:
import { ConnectorClient } from 'livekit-server-sdk';const connectorClient = new ConnectorClient(process.env.LIVEKIT_URL,process.env.LIVEKIT_API_KEY,process.env.LIVEKIT_API_SECRET,);
from livekit import api# Uses LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET env varslkapi = api.LiveKitAPI()# Access the connector service via lkapi.connector
import ("os"lksdk "github.com/livekit/server-sdk-go/v2")connectorClient := lksdk.NewConnectorClient(os.Getenv("LIVEKIT_URL"),os.Getenv("LIVEKIT_API_KEY"),os.Getenv("LIVEKIT_API_SECRET"),)
import io.livekit.server.ConnectorServiceClientval connectorClient = ConnectorServiceClient.createClient(host = System.getenv("LIVEKIT_URL").replaceFirst(Regex("^ws"), "http"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"),)
use livekit_api::services::connector::ConnectorClient;let host = std::env::var("LIVEKIT_URL")?.replace("wss://", "https://").replace("ws://", "http://");let connector_client = ConnectorClient::with_api_key(&host,&std::env::var("LIVEKIT_API_KEY")?,&std::env::var("LIVEKIT_API_SECRET")?,);
Constructor parameters
If you're using LiveKit Cloud, you can find your LiveKit server URL, API key, and secret key on the API keys page by selecting an API key. Or create a new API key by selecting Create key.
If you're self-hosting, see this guide to get your LiveKit server URL, API key, and secret key for local development.
hoststringURL of your LiveKit server. For example, https://your-project-subdomain.livekit.cloud.
apiKeystringAPI key for authentication. Falls back to LIVEKIT_API_KEY environment variable.
secretstringSecret key for authentication. Falls back to LIVEKIT_API_SECRET environment variable.
optionsClientOptionsClient options. Supports requestTimeout (in seconds) for all server requests.
urlstringURL of your LiveKit server. Falls back to LIVEKIT_URL environment variable.
api_keystringAPI key for authentication. Falls back to LIVEKIT_API_KEY environment variable.
api_secretstringSecret key for authentication. Falls back to LIVEKIT_API_SECRET environment variable.
timeoutaiohttp.ClientTimeoutRequest timeout. Default: 60 seconds.
sessionaiohttp.ClientSessionAn existing aiohttp.ClientSession to use for requests. If not provided, a new session is created.
urlstringURL of your LiveKit server. For example, https://your-project-subdomain.livekit.cloud.
apiKeystringAPI key for authentication.
secretKeystringSecret key for authentication.
opts...twirp.ClientOptionOptional Twirp client options for advanced configuration.
hostStringURL of your LiveKit server. Must use http:// or https:// scheme.
apiKeyStringAPI key for authentication.
secretStringSecret key for authentication.
okHttpSupplierSupplier<OkHttpClient>Custom OkHttpClient supplier for advanced HTTP configuration. Defaults to OkHttpFactory().
host&strURL of your LiveKit server. Must use http:// or https:// scheme.
api_key&strAPI key for authentication.
api_secret&strSecret key for authentication.
WhatsApp Connector APIs
The WhatsApp Connector APIs allow you to initiate, accept, connect, and disconnect WhatsApp voice calls.
Requests to the WhatsApp Connector API require appropriate WhatsApp Business API credentials from Meta. You must provide a valid WhatsApp API key (access token) for all operations.
All RPC definitions and options can be found on GitHub .
DialWhatsAppCall
Create an outbound WhatsApp call from your business phone number to a user's WhatsApp phone number.
Returns DialWhatsAppCallResponse.
const dialRes = await connectorClient.dialWhatsAppCall({whatsappPhoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,whatsappToPhoneNumber: process.env.WHATSAPP_TO_PHONE_NUMBER!,whatsappCloudApiVersion: '23.0',whatsappApiKey: process.env.WHATSAPP_API_KEY!,destinationCountry: 'US',roomName: 'whatsapp-connector-test',participantIdentity: 'test-identity',participantName: 'test-user',agents: [{ agentName: 'my-agent' }],});
from livekit import apifrom livekit.protocol.agent_dispatch import RoomAgentDispatchdial_res = await lkapi.connector.dial_whatsapp_call(api.DialWhatsAppCallRequest(whatsapp_phone_number_id=os.environ["WHATSAPP_PHONE_NUMBER_ID"],whatsapp_to_phone_number=os.environ["WHATSAPP_TO_PHONE_NUMBER"],whatsapp_cloud_api_version="23.0",whatsapp_api_key=os.environ["WHATSAPP_API_KEY"],destination_country="US",room_name="whatsapp-connector-test",participant_identity="test-identity",participant_name="test-user",agents=[RoomAgentDispatch(agent_name="my-agent")],))
dialRes, err := connectorClient.DialWhatsAppCall(ctx, &livekit.DialWhatsAppCallRequest{WhatsappPhoneNumberId: os.Getenv("WHATSAPP_PHONE_NUMBER_ID"),WhatsappToPhoneNumber: os.Getenv("WHATSAPP_TO_PHONE_NUMBER"),WhatsappCloudApiVersion: "23.0",WhatsappApiKey: os.Getenv("WHATSAPP_API_KEY"),DestinationCountry: "US",RoomName: "whatsapp-connector-test",ParticipantIdentity: "test-identity",ParticipantName: "test-user",Agents: []*livekit.RoomAgentDispatch{{AgentName: "my-agent"},},})
import io.livekit.server.WhatsAppCallOptionsimport livekit.LivekitAgentDispatch.RoomAgentDispatchval dialResponse = connectorClient.dialWhatsAppCall(whatsappPhoneNumberId = System.getenv("WHATSAPP_PHONE_NUMBER_ID"),whatsappToPhoneNumber = System.getenv("WHATSAPP_TO_PHONE_NUMBER"),whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),whatsappCloudApiVersion = "23.0",options = WhatsAppCallOptions(destinationCountry = "US",roomName = "whatsapp-connector-test",participantIdentity = "test-identity",participantName = "test-user",agents = listOf(RoomAgentDispatch.newBuilder().setAgentName("my-agent").build(),),),).execute()
use livekit_api::services::connector::DialWhatsAppCallOptions;use livekit_protocol::RoomAgentDispatch;let dial_res = connector_client.dial_whatsapp_call(env::var("WHATSAPP_PHONE_NUMBER_ID")?,env::var("WHATSAPP_TO_PHONE_NUMBER")?,env::var("WHATSAPP_API_KEY")?,"23.0",DialWhatsAppCallOptions {destination_country: Some("US".into()),room_name: Some("whatsapp-connector-test".into()),participant_identity: Some("test-identity".into()),participant_name: Some("test-user".into()),agents: Some(vec![RoomAgentDispatch {agent_name: "my-agent".into(),..Default::default()}]),..Default::default()},).await?;
whatsapp_phone_number_idstringWhatsApp Business phone number ID of the business that is initiating the call. To learn more, see Retrieve Phone Numbers .
whatsapp_to_phone_numberstringPhone number of the WhatsApp user to call. Must include the country code without the leading +.
whatsapp_api_keystringMeta API key (access token). To learn more, see Generate an access token .
whatsapp_cloud_api_versionstringWhatsApp Cloud API version, for example, 23.0 or 24.0.
whatsapp_biz_opaque_callback_datastringAn arbitrary string you can pass in that is useful for tracking and logging purposes.
room_namestringName of the LiveKit room the participant should be connected to. If not specified, the room name is autogenerated.
agentsarray<RoomAgentDispatch>Agents to dispatch to the room for the call. To learn more about this parameter, see RoomAgentDispatch.
participant_identitystringIdentity of the participant in LiveKit room.
participant_namestringName of the participant in LiveKit room.
participant_metadatastringUser-defined metadata. Attached to created participant in the room.
participant_attributesmap<string, string>User-defined attributes. Attached to created participant in the room.
destination_countrystringCountry where the call terminates as ISO 3166-1 alpha-2 , for example, US, GB, or IN. Used by the LiveKit infrastructure to route calls. To learn more, see region pinning for outbound calls.
ringing_timeoutDurationMaximum time to wait for the callee to answer the call.
AcceptWhatsAppCall
Accept an inbound WhatsApp call from a user.
Returns AcceptWhatsAppCallResponse.
import { SessionDescription } from '@livekit/protocol';const res = await connectorClient.acceptWhatsAppCall({whatsappPhoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,whatsappApiKey: process.env.WHATSAPP_API_KEY!,whatsappCloudApiVersion: '23.0',whatsappCallId: callId, // from the Meta webhooksdp: new SessionDescription({type: 'offer',sdp: sdpFromWebhook,}),roomName: 'my-room',agents: [{ agentName: 'my-agent' }],});
from livekit import apifrom livekit.protocol.rtc import SessionDescriptionres = await lkapi.connector.accept_whatsapp_call(api.AcceptWhatsAppCallRequest(whatsapp_phone_number_id=os.environ["WHATSAPP_PHONE_NUMBER_ID"],whatsapp_api_key=os.environ["WHATSAPP_API_KEY"],whatsapp_cloud_api_version="23.0",whatsapp_call_id=call_id, # from the Meta webhooksdp=SessionDescription(type="offer",sdp=sdp_from_webhook,),room_name="my-room",agents=[api.RoomAgentDispatch(agent_name="my-agent")],))
res, err := connectorClient.AcceptWhatsAppCall(ctx, &livekit.AcceptWhatsAppCallRequest{WhatsappPhoneNumberId: os.Getenv("WHATSAPP_PHONE_NUMBER_ID"),WhatsappApiKey: os.Getenv("WHATSAPP_API_KEY"),WhatsappCloudApiVersion: "23.0",WhatsappCallId: callId, // from the Meta webhookSdp: &livekit.SessionDescription{Type: "offer",Sdp: sdpFromWebhook,},RoomName: "my-room",Agents: []*livekit.RoomAgentDispatch{{AgentName: "my-agent"},},})
import io.livekit.server.WhatsAppCallOptionsimport livekit.LivekitAgentDispatch.RoomAgentDispatchimport livekit.LivekitRtc.SessionDescriptionval res = connectorClient.acceptWhatsAppCall(whatsappPhoneNumberId = System.getenv("WHATSAPP_PHONE_NUMBER_ID"),whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),whatsappCloudApiVersion = "23.0",whatsappCallId = callId, // from the Meta webhooksdp = SessionDescription.newBuilder().setType("offer").setSdp(sdpFromWebhook).build(),options = WhatsAppCallOptions(roomName = "my-room",agents = listOf(RoomAgentDispatch.newBuilder().setAgentName("my-agent").build(),),),).execute()
use livekit_api::services::connector::AcceptWhatsAppCallOptions;use livekit_protocol::{RoomAgentDispatch, SessionDescription};let res = connector_client.accept_whatsapp_call(&std::env::var("WHATSAPP_PHONE_NUMBER_ID")?,&std::env::var("WHATSAPP_API_KEY")?,"23.0",call_id, // from the Meta webhookSessionDescription {r#type: "offer".into(),sdp: sdp_from_webhook,},AcceptWhatsAppCallOptions {room_name: Some("my-room".into()),agents: Some(vec![RoomAgentDispatch {agent_name: "my-agent".into(),..Default::default()}]),..Default::default()},).await?;
whatsapp_phone_number_idstringWhatsApp Business phone number ID of the business that is connecting the call.
whatsapp_api_keystringThe API key (access token) of the business that is connecting the call.
whatsapp_cloud_api_versionstringWhatsApp Cloud API version, for example, 23.0 or 24.0.
whatsapp_call_idstringCall ID sent by Meta.
whatsapp_biz_opaque_callback_datastringAn arbitrary string you can pass in that is useful for tracking and logging purposes.
sdpSessionDescriptionSDP offer from Meta in the call connect webhook.
room_namestringName of the LiveKit room to connect this participant to. If not specified, the room name is autogenerated.
participant_identitystringIdentity of the participant in the LiveKit room.
participant_namestringName of the participant in the LiveKit room.
participant_metadatastringUser-defined metadata. Attached to created participant in the room.
participant_attributesmap<string, string>User-defined attributes. Attached to created participant in the room.
destination_countrystringCountry where the call terminates as ISO 3166-1 alpha-2 , for example, US, GB, or IN. Used by the LiveKit infrastructure to route calls. To learn more, see region pinning for outbound calls.
ringing_timeoutDurationMaximum time to wait for the callee to answer the call.
wait_until_answeredboolWait for the call to be answered before returning.
ConnectWhatsAppCall
Connect an active WhatsApp call by providing the answer SDP from Meta's webhook.
Returns ConnectWhatsAppCallResponse.
import { SessionDescription } from '@livekit/protocol';await connectorClient.connectWhatsAppCall(callId, // from the Meta webhooknew SessionDescription({type: 'answer',sdp: sdpFromWebhook,}),);
from livekit import apifrom livekit.protocol.rtc import SessionDescriptionawait lkapi.connector.connect_whatsapp_call(api.ConnectWhatsAppCallRequest(whatsapp_call_id=call_id, # from the Meta webhooksdp=SessionDescription(type="answer",sdp=sdp_from_webhook,),))
res, err := connectorClient.ConnectWhatsAppCall(ctx, &livekit.ConnectWhatsAppCallRequest{WhatsappCallId: callId, // from the Meta webhookSdp: &livekit.SessionDescription{Type: "answer",Sdp: sdpFromWebhook,},})
import livekit.LivekitRtc.SessionDescriptionval res = connectorClient.connectWhatsAppCall(whatsappCallId = callId, // from the Meta webhooksdp = SessionDescription.newBuilder().setType("answer").setSdp(sdpFromWebhook).build(),).execute()
use livekit_protocol::SessionDescription;let res = connector_client.connect_whatsapp_call(call_id, // from the Meta webhookSessionDescription {r#type: "answer".into(),sdp: sdp_from_webhook,},).await?;
whatsapp_call_idstringCall ID sent by Meta.
sdpSessionDescriptionSDP answer from Meta in the call connect webhook.
DisconnectWhatsAppCall
Disconnect an active WhatsApp call.
Returns DisconnectWhatsAppCallResponse.
await connectorClient.disconnectWhatsAppCall(dialRes.whatsappCallId,process.env.WHATSAPP_API_KEY!,);
from livekit import apiawait lkapi.connector.disconnect_whatsapp_call(api.DisconnectWhatsAppCallRequest(whatsapp_call_id=dial_res.whatsapp_call_id,whatsapp_api_key=os.environ["WHATSAPP_API_KEY"],))
_, err = connectorClient.DisconnectWhatsAppCall(ctx, &livekit.DisconnectWhatsAppCallRequest{WhatsappCallId: dialRes.WhatsappCallId,WhatsappApiKey: os.Getenv("WHATSAPP_API_KEY"),})
val disconnectResponse = connectorClient.disconnectWhatsAppCall(whatsappCallId = dialBody.whatsappCallId,whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),).execute()
connector_client.disconnect_whatsapp_call(&dial_res.whatsapp_call_id,env::var("WHATSAPP_API_KEY")?,).await?;
whatsapp_call_idstringCall ID sent by Meta.
whatsapp_api_keystringThe API key (access token) of the business that is disconnecting the call.
Twilio Connector APIs
The Twilio Connector APIs allow you to connect Twilio voice calls to LiveKit rooms.
Requests to the Twilio Connector API require valid Twilio credentials.
All RPC definitions and options can be found on GitHub .
ConnectTwilioCall
Connect an inbound or outbound Twilio call to a LiveKit room.
Returns ConnectTwilioCallResponse.
import { ConnectTwilioCallRequest_TwilioCallDirection } from '@livekit/protocol';const res = await connectorClient.connectTwilioCall({twilioCallDirection: ConnectTwilioCallRequest_TwilioCallDirection.TWILIO_CALL_DIRECTION_OUTBOUND,roomName: 'twilio-connector-test',destinationCountry: 'US',participantIdentity: 'test',participantName: 'test',agents: [{ agentName: 'my-agent' }],});// Use res.connectUrl to configure a Twilio Media Stream
from livekit import apifrom livekit.protocol.agent_dispatch import RoomAgentDispatchres = await lkapi.connector.connect_twilio_call(api.ConnectTwilioCallRequest(twilio_call_direction=api.ConnectTwilioCallRequest.TWILIO_CALL_DIRECTION_OUTBOUND,destination_country="US",room_name="twilio-connector-test",participant_identity="test",participant_name="test",agents=[RoomAgentDispatch(agent_name="my-agent")],))# Use res.connect_url to configure a Twilio Media Stream
res, err := connectorClient.ConnectTwilioCall(ctx, &livekit.ConnectTwilioCallRequest{TwilioCallDirection: livekit.ConnectTwilioCallRequest_TWILIO_CALL_DIRECTION_OUTBOUND,DestinationCountry: "US",RoomName: "twilio-connector-test",ParticipantIdentity: "test",ParticipantName: "test",Agents: []*livekit.RoomAgentDispatch{{AgentName: "my-agent"},},})// Use res.ConnectUrl to configure a Twilio Media Stream
import io.livekit.server.TwilioCallOptionsimport livekit.LivekitAgentDispatch.RoomAgentDispatchimport livekit.LivekitConnectorTwilio.ConnectTwilioCallRequest.TwilioCallDirectionval response = connectorClient.connectTwilioCall(twilioCallDirection = TwilioCallDirection.TWILIO_CALL_DIRECTION_OUTBOUND,options = TwilioCallOptions(roomName = "twilio-connector-test",destinationCountry = "US",participantIdentity = "test",participantName = "test",agents = listOf(RoomAgentDispatch.newBuilder().setAgentName("my-agent").build(),),),).execute()// Use response.body()!!.connectUrl to configure a Twilio Media Stream
use livekit_api::services::connector::ConnectTwilioCallOptions;use livekit_protocol::{connect_twilio_call_request::TwilioCallDirection, RoomAgentDispatch,};let res = connector_client.connect_twilio_call(TwilioCallDirection::Outbound,"twilio-connector-test",ConnectTwilioCallOptions {destination_country: Some("US".into()),participant_identity: Some("test".into()),participant_name: Some("test".into()),agents: Some(vec![RoomAgentDispatch {agent_name: "my-agent".into(),..Default::default()}]),..Default::default()},).await?;// Use res.connect_url to configure a Twilio Media Stream
twilio_call_directionTwilioCallDirectionDirection of the call. See TwilioCallDirection.
room_namestringName of the LiveKit room to connect this call to.
agentsarray<RoomAgentDispatch>Agents to dispatch to the room for the call. To learn more about this parameter, see RoomAgentDispatch.
participant_identitystringIdentity of the participant in the LiveKit room.
participant_namestringName of the participant in the LiveKit room.
participant_metadatastringUser-defined metadata. Attached to created participant in the room.
participant_attributesmap<string, string>User-defined attributes. Attached to created participant in the room.
destination_countrystringCountry where the call terminates as ISO 3166-1 alpha-2 , for example, US, GB, or IN. Used by the LiveKit infrastructure to route calls. To learn more, see region pinning for outbound calls.
Types
The Connector service includes the following types.
AcceptWhatsAppCallResponse
| Field | Type | Description |
|---|---|---|
| room_name | string | The name of the LiveKit room that the call is connected to. |
ConnectTwilioCallResponse
| Field | Type | Description |
|---|---|---|
| connect_url | string | The websocket URL which Twilio media stream connects to. |
ConnectWhatsAppCallResponse
Empty response. Returns successfully if the call was connected.
DialWhatsAppCallResponse
| Field | Type | Description |
|---|---|---|
| whatsapp_call_id | string | Call ID sent by Meta. |
| room_name | string | The name of the LiveKit room that the call is connected to. |
DisconnectWhatsAppCallResponse
Empty response. Returns successfully if the call was disconnected.
TwilioCallDirection
Enum. Valid values are as follows:
| Name | Value | Description |
|---|---|---|
| TWILIO_CALL_DIRECTION_INBOUND | 0 | Call is inbound to LiveKit from Twilio. |
| TWILIO_CALL_DIRECTION_OUTBOUND | 1 | Call is outbound from LiveKit to Twilio. |
WhatsAppCall
| Field | Type | Description |
|---|---|---|
| whatsapp_call_id | string | The call ID from WhatsApp. |
| direction | WhatsAppCallDirection | Direction of the call. See WhatsAppCallDirection. |
WhatsAppCallDirection
Enum. Valid values are as follows:
| Name | Value | Description |
|---|---|---|
| WHATSAPP_CALL_DIRECTION_INBOUND | 0 | User-initiated call where a WhatsApp user calls your business phone number. |
| WHATSAPP_CALL_DIRECTION_OUTBOUND | 2 | Business-initiated call where your app calls a WhatsApp user's phone number. |