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
- Ruby 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
gem install livekit-server-sdk
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 LiveKitAPI client with your LiveKit server URL and API credentials, then access the connector service through the connector accessor:
import { LiveKitAPI } from 'livekit-server-sdk';// Reads LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET from the environmentconst api = new LiveKitAPI();// Access the connector service via api.connector
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
require 'livekit'# Reads LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET from the environmentlkapi = LiveKit::LiveKitAPI.new# Access the connector service via lkapi.connector
import (lksdk "github.com/livekit/server-sdk-go/v2")// Reads LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET from the environmentapi, err := lksdk.NewLiveKitAPI()if err != nil {// Handle error}// Access the connector service via api.Connector()
import io.livekit.server.LiveKitAPIval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"),)// Access the connector service via api.connector
use livekit_api::services::LiveKitApi;// Reads LIVEKIT_API_KEY and LIVEKIT_API_SECRET from the environment.// A wss:// URL is converted to https:// internally.let api = LiveKitApi::new(&std::env::var("LIVEKIT_URL")?)?;// Access the connector service via api.connector()
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. Falls back to the LIVEKIT_URL environment variable.
api_keyStringAPI key for authentication. Falls back to the LIVEKIT_API_KEY environment variable.
api_secretStringSecret key for authentication. Falls back to the LIVEKIT_API_SECRET environment variable.
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 api.connector.dialWhatsAppCall({whatsappPhoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,whatsappToPhoneNumber: process.env.WHATSAPP_TO_PHONE_NUMBER!,whatsappCloudApiVersion: '25.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="25.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")],))
dial_res = lkapi.connector.dial_whatsapp_call(LiveKit::Proto::DialWhatsAppCallRequest.new(whatsapp_phone_number_id: ENV["WHATSAPP_PHONE_NUMBER_ID"],whatsapp_to_phone_number: ENV["WHATSAPP_TO_PHONE_NUMBER"],whatsapp_cloud_api_version: "25.0",whatsapp_api_key: ENV["WHATSAPP_API_KEY"],destination_country: "US",room_name: "whatsapp-connector-test",participant_identity: "test-identity",participant_name: "test-user",agents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: "my-agent")],),)
dialRes, err := api.Connector().DialWhatsAppCall(ctx, &livekit.DialWhatsAppCallRequest{WhatsappPhoneNumberId: os.Getenv("WHATSAPP_PHONE_NUMBER_ID"),WhatsappToPhoneNumber: os.Getenv("WHATSAPP_TO_PHONE_NUMBER"),WhatsappCloudApiVersion: "25.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 = api.connector.dialWhatsAppCall(whatsappPhoneNumberId = System.getenv("WHATSAPP_PHONE_NUMBER_ID"),whatsappToPhoneNumber = System.getenv("WHATSAPP_TO_PHONE_NUMBER"),whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),whatsappCloudApiVersion = "25.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 = api.connector().dial_whatsapp_call(env::var("WHATSAPP_PHONE_NUMBER_ID")?,env::var("WHATSAPP_TO_PHONE_NUMBER")?,env::var("WHATSAPP_API_KEY")?,"25.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, 24.0, or 25.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 api.connector.acceptWhatsAppCall({whatsappPhoneNumberId: process.env.WHATSAPP_PHONE_NUMBER_ID!,whatsappApiKey: process.env.WHATSAPP_API_KEY!,whatsappCloudApiVersion: '25.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="25.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 = lkapi.connector.accept_whatsapp_call(LiveKit::Proto::AcceptWhatsAppCallRequest.new(whatsapp_phone_number_id: ENV["WHATSAPP_PHONE_NUMBER_ID"],whatsapp_api_key: ENV["WHATSAPP_API_KEY"],whatsapp_cloud_api_version: "25.0",whatsapp_call_id: call_id, # from the Meta webhooksdp: LiveKit::Proto::SessionDescription.new(type: "offer",sdp: sdp_from_webhook,),room_name: "my-room",agents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: "my-agent")],),)
res, err := api.Connector().AcceptWhatsAppCall(ctx, &livekit.AcceptWhatsAppCallRequest{WhatsappPhoneNumberId: os.Getenv("WHATSAPP_PHONE_NUMBER_ID"),WhatsappApiKey: os.Getenv("WHATSAPP_API_KEY"),WhatsappCloudApiVersion: "25.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 = api.connector.acceptWhatsAppCall(whatsappPhoneNumberId = System.getenv("WHATSAPP_PHONE_NUMBER_ID"),whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),whatsappCloudApiVersion = "25.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 = api.connector().accept_whatsapp_call(&std::env::var("WHATSAPP_PHONE_NUMBER_ID")?,&std::env::var("WHATSAPP_API_KEY")?,"25.0",call_id, // from the Meta webhookSessionDescription {r#type: "offer".into(),sdp: sdp_from_webhook,..Default::default()},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, 24.0, or 25.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 api.connector.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,),))
lkapi.connector.connect_whatsapp_call(LiveKit::Proto::ConnectWhatsAppCallRequest.new(whatsapp_call_id: call_id, # from the Meta webhooksdp: LiveKit::Proto::SessionDescription.new(type: "answer",sdp: sdp_from_webhook,),),)
res, err := api.Connector().ConnectWhatsAppCall(ctx, &livekit.ConnectWhatsAppCallRequest{WhatsappCallId: callId, // from the Meta webhookSdp: &livekit.SessionDescription{Type: "answer",Sdp: sdpFromWebhook,},})
import livekit.LivekitRtc.SessionDescriptionval res = api.connector.connectWhatsAppCall(whatsappCallId = callId, // from the Meta webhooksdp = SessionDescription.newBuilder().setType("answer").setSdp(sdpFromWebhook).build(),).execute()
use livekit_protocol::SessionDescription;let res = api.connector().connect_whatsapp_call(call_id, // from the Meta webhookSessionDescription {r#type: "answer".into(),sdp: sdp_from_webhook,..Default::default()},).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 api.connector.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"],))
lkapi.connector.disconnect_whatsapp_call(LiveKit::Proto::DisconnectWhatsAppCallRequest.new(whatsapp_call_id: dial_res.whatsapp_call_id,whatsapp_api_key: ENV["WHATSAPP_API_KEY"],),)
_, err = api.Connector().DisconnectWhatsAppCall(ctx, &livekit.DisconnectWhatsAppCallRequest{WhatsappCallId: dialRes.WhatsappCallId,WhatsappApiKey: os.Getenv("WHATSAPP_API_KEY"),})
val disconnectResponse = api.connector.disconnectWhatsAppCall(whatsappCallId = dialResponse.body()!!.whatsappCallId,whatsappApiKey = System.getenv("WHATSAPP_API_KEY"),).execute()
use livekit_protocol as proto;api.connector().disconnect_whatsapp_call(&dial_res.whatsapp_call_id,env::var("WHATSAPP_API_KEY")?,proto::disconnect_whats_app_call_request::DisconnectReason::BusinessInitiated,).await?;
whatsapp_call_idstringCall ID sent by Meta.
whatsapp_api_keystringThe API key (access token) of the business that is disconnecting the call. Required when the disconnect reason is BUSINESS_INITIATED.
disconnect_reasonDisconnectReasonReason the call is being disconnected: BUSINESS_INITIATED (default) or USER_INITIATED. In the Rust SDK this argument is required.
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 api.connector.connectTwilioCall({twilioCallDirection: ConnectTwilioCallRequest_TwilioCallDirection.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 = lkapi.connector.connect_twilio_call(LiveKit::Proto::ConnectTwilioCallRequest.new(twilio_call_direction: LiveKit::Proto::ConnectTwilioCallRequest::TwilioCallDirection::TWILIO_CALL_DIRECTION_OUTBOUND,destination_country: "US",room_name: "twilio-connector-test",participant_identity: "test",participant_name: "test",agents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: "my-agent")],),)# Use res.connect_url to configure a Twilio Media Stream
res, err := api.Connector().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 = api.connector.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 = api.connector().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. |