Overview
The WhatsApp Connector bridges LiveKit with the WhatsApp communication platform, providing bidirectional audio streaming and media processing—including resampling, mixing, and codec translation. It manages all API calls needed to initiate, connect, and control the call lifecycle. The connector lets you bring WhatsApp calls directly into a LiveKit room, where you can optionally dispatch LiveKit Agents to handle the interaction.
WhatsApp participants can be identified using the kind field, which identifies the type of participant in a LiveKit room. For WhatsApp participants, this is CONNECTOR.
Use cases
Use the WhatsApp Connector to build customer support workflows, triage systems, appointment and reminder flows, or outbound engagement experiences. For example, an agent can speak with a user during a call, then immediately send an invoice or follow-up information as a text message without switching channels.
Prerequisites
To use the WhatsApp Connector, you need the following:
- A phone number registered with a WhatsApp Business account .
- A WhatsApp Cloud API access token.
- A Meta Developer Account to create and manage your app.
- An app capable of receiving and handling WhatsApp webhooks .
- Call permissions enabled on the Meta platform:
- Inbound calls: Configure available call hours for your business. To learn more, see User-initiated calls .
- Outbound calls: Available only in certain regions. You must be in a supported region and obtain explicit permission from the user before initiating a call. To learn more, see Business-initiated calls .
The WhatsApp Connector works with WhatsApp Cloud API v23.0, v24.0, or v25.0.
Key concepts
The WhatsApp Connector relies on webhooks and SDP negotiation to establish and manage calls.
Webhooks
Webhooks are automated, realtime notifications that one application sends to another when specific events occur. They work by delivering an HTTP POST request to a designated URL. WhatsApp uses webhooks to notify your app whenever something happens, such as an incoming call or message.
For both inbound and outbound calls, WhatsApp sends a call connect webhook that includes the Session Description Protocol (SDP) offer or answer needed to establish the connection. Your app must receive this webhook, extract the SDP, and pass it to a LiveKit Connector API to complete the connection.
Configuring a webhook endpoint is required to use the connector. Without it, your app cannot detect when a call is ready to connect or retrieve the SDP offer or answer needed to complete the setup.
To set up webhooks for your WhatsApp Business account, see the webhook configuration guide .
SDP
SDP is a standardized format used in multimedia communications to describe the parameters of a media session, such as media types, codecs, and transport protocols. WhatsApp uses SDP offer and answer negotiation to establish a media connection with LiveKit. For inbound calls, WhatsApp sends an SDP offer; for outbound calls, it sends an SDP answer.
Making outbound calls
An outbound call is a WhatsApp call initiated from a WhatsApp Business account to a user's WhatsApp number. Outbound calling is not available in all regions. Check for feature availability .
Workflow
The flow for a business-initiated (outbound) call is as follows:
Your app calls the
DialWhatsAppCallAPI to initiate an outbound call.- This API call delegates to the WhatsApp Cloud API to initiate the call and returns a
WhatsAppCallId. - Meta begins dialing the user's WhatsApp number.
- This API call delegates to the WhatsApp Cloud API to initiate the call and returns a
When the call is ready to connect, Meta sends a
call connectwebhook containing the SDP answer.Your app calls the
ConnectWhatsAppCallAPI with theWhatsAppCallIdand the SDP answer to complete the connection.
The following diagram illustrates the outbound WhatsApp call flow:
Loading diagram…
Required webhooks
For outbound calls, WhatsApp sends a call connect webhook that includes the SDP answer. Your app must receive this webhook and pass the SDP to ConnectWhatsAppCall to complete the connection.
Example
Completing an outbound call is a multi-step process:
Use the
DialWhatsAppCallAPI to initiate an outbound call with the following parameters:Parameter Required Description WhatsAppPhoneNumberIdYes Your WhatsApp Business phone number ID. WhatsAppToPhoneNumberYes The user's WhatsApp number to call. Must include the country code without the leading +sign.WhatsAppApiKeyYes Your WhatsApp API access token. To learn more, see Generate an access token . WhatsAppCloudApiVersionYes The WhatsApp Cloud API version (for example, 23.0,24.0, or25.0).DestinationCountryNo Optional two letter country code for the country where the call terminates. See Regional routing. Other optional fields include:
Agents,ParticipantMetadata,ParticipantAttributes, andRingingTimeout.For a full list of parameters and their descriptions, see the DialWhatsAppCall API reference.
import { LiveKitAPI, RoomAgentDispatch } from 'livekit-server-sdk';const api = new LiveKitAPI();const res = await api.connector.dialWhatsAppCall({whatsappPhoneNumberId: 'whatsapp-business-phone-number-id',whatsappToPhoneNumber: 'user-number-to-dial',whatsappCloudApiVersion: '25.0',whatsappApiKey: 'your-meta-access-token',destinationCountry: 'US', // optionalroomName: 'whatsapp-connector-test', // optionalparticipantIdentity: 'test-identity', // optionalparticipantName: 'test-user', // optionalagents: [new RoomAgentDispatch({ agentName: 'my-agent' })],});from livekit import apifrom livekit.protocol.agent_dispatch import RoomAgentDispatchlkapi = api.LiveKitAPI()res = await lkapi.connector.dial_whatsapp_call(api.DialWhatsAppCallRequest(whatsapp_phone_number_id="whatsapp-business-phone-number-id",whatsapp_to_phone_number="user-number-to-dial",whatsapp_cloud_api_version="25.0",whatsapp_api_key="your-meta-access-token",destination_country="US", # optionalroom_name="whatsapp-connector-test", # optionalparticipant_identity="test-identity", # optionalparticipant_name="test-user", # optionalagents=[RoomAgentDispatch(agent_name="my-agent")],))require 'livekit'lkapi = LiveKit::LiveKitAPI.newres = lkapi.connector.dial_whatsapp_call(LiveKit::Proto::DialWhatsAppCallRequest.new(whatsapp_phone_number_id: 'whatsapp-business-phone-number-id',whatsapp_to_phone_number: 'user-number-to-dial',whatsapp_cloud_api_version: '25.0',whatsapp_api_key: 'your-meta-access-token',destination_country: 'US', # optionalroom_name: 'whatsapp-connector-test', # optionalparticipant_identity: 'test-identity', # optionalparticipant_name: 'test-user', # optionalagents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: 'my-agent')],),)api, err := lksdk.NewLiveKitAPI()if err != nil {// Handle error}res, err := api.Connector().DialWhatsAppCall(ctx, &livekit.DialWhatsAppCallRequest{WhatsappPhoneNumberId: "whatsapp-business-phone-number-id",WhatsappToPhoneNumber: "user-number-to-dial",WhatsappCloudApiVersion: "25.0",WhatsappApiKey: "your-meta-access-token",DestinationCountry: "US", // optionalRoomName: "whatsapp-connector-test", // optionalParticipantIdentity: "test-identity", // optionalParticipantName: "test-user", // optionalAgents: []*livekit.RoomAgentDispatch{{AgentName: "my-agent",},},})import io.livekit.server.LiveKitAPIimport io.livekit.server.WhatsAppCallOptionsimport livekit.LivekitAgentDispatch.RoomAgentDispatchval api = LiveKitAPI.createClient(host = System.getenv("LIVEKIT_URL"),apiKey = System.getenv("LIVEKIT_API_KEY"),secret = System.getenv("LIVEKIT_API_SECRET"),)val res = api.connector.dialWhatsAppCall(whatsappPhoneNumberId = "whatsapp-business-phone-number-id",whatsappToPhoneNumber = "user-number-to-dial",whatsappApiKey = "your-meta-access-token",whatsappCloudApiVersion = "25.0",options = WhatsAppCallOptions(destinationCountry = "US", // optionalroomName = "whatsapp-connector-test", // optionalparticipantIdentity = "test-identity", // optionalparticipantName = "test-user", // optionalagents = listOf(RoomAgentDispatch.newBuilder().setAgentName("my-agent").build(),),),).execute()use livekit_api::services::connector::DialWhatsAppCallOptions;use livekit_api::services::LiveKitApi;use livekit_protocol::RoomAgentDispatch;let api = LiveKitApi::with_api_key(host, api_key, api_secret);let res = api.connector().dial_whatsapp_call("whatsapp-business-phone-number-id","user-number-to-dial","your-meta-access-token","25.0",DialWhatsAppCallOptions {destination_country: Some("US".into()), // optionalroom_name: Some("whatsapp-connector-test".into()), // optionalparticipant_identity: Some("test-identity".into()), // optionalparticipant_name: Some("test-user".into()), // optionalagents: Some(vec![RoomAgentDispatch {agent_name: "my-agent".into(),..Default::default()}]),..Default::default()},).await?;The response includes a
WhatsAppCallIdfrom Meta and aRoomName(either provided using theRoomNameparameter or auto-generated).Meta then sends a
call connectwebhook containing the SDP answer.Upon receiving the webhook, call
ConnectWhatsAppCallimmediately with theWhatsAppCallIdand the SDP answer from the webhook to complete the connection:const res = await api.connector.connectWhatsAppCall(call.id, {type: 'answer',sdp: call.session.sdp,});from livekit.protocol.rtc import SessionDescriptionres = await lkapi.connector.connect_whatsapp_call(api.ConnectWhatsAppCallRequest(whatsapp_call_id=call.id,sdp=SessionDescription(type="answer", sdp=call.session.sdp),))res = lkapi.connector.connect_whatsapp_call(LiveKit::Proto::ConnectWhatsAppCallRequest.new(whatsapp_call_id: call.id,sdp: LiveKit::Proto::SessionDescription.new(type: 'answer', sdp: call.session.sdp),),)res, err := api.Connector().ConnectWhatsAppCall(ctx, &livekit.ConnectWhatsAppCallRequest{WhatsappCallId: call.ID,Sdp: &livekit.SessionDescription{Type: "answer",Sdp: call.Session.SDP,},})import livekit.LivekitRtc.SessionDescriptionval res = api.connector.connectWhatsAppCall(whatsappCallId = call.id,sdp = SessionDescription.newBuilder().setType("answer").setSdp(call.session.sdp).build(),).execute()use livekit_protocol::SessionDescription;let res = api.connector().connect_whatsapp_call(&call.id,SessionDescription {r#type: "answer".into(),sdp: call.session.sdp.clone(),..Default::default()},).await?;Delayed connection can result in silenceBecause the user's phone starts ringing when the
DialWhatsAppCallcall is processed, delays in callingConnectWhatsAppCallafter the webhook is received can result in silence and eventual disconnection.Disconnecting calls
Use
DisconnectWhatsAppCallto end an active WhatsApp call. You must call this API for both business-initiated and user-initiated disconnects. When a user hangs up, Meta sends a call terminate webhook to your app. Your webhook handler must then callDisconnectWhatsAppCallwithUSER_INITIATEDso LiveKit can clean up the connector session and room resources.Automatic cleanup after 30 secondsIf you don't call
DisconnectWhatsAppCallafter a user hangs up, LiveKit automatically cleans up the call after 30 seconds. During this window, any agents, egress, or other services running in the room continue to run unnecessarily. Always call the API promptly to avoid wasted resources.Parameters
Parameter Required Description whatsapp_call_idYes The call ID provided by Meta. whatsapp_api_keyConditional Your Meta API key. Required when disconnect_reasonisBUSINESS_INITIATED. Optional forUSER_INITIATEDbecause no API call to WhatsApp is needed.disconnect_reasonNo The reason for disconnecting the call. Defaults to BUSINESS_INITIATED.The
disconnect_reasonfield accepts one of the following values:BUSINESS_INITIATED: The business is ending the call. Requireswhatsapp_api_key.USER_INITIATED: The user ended the call. Use this when you receive a call terminate webhook from Meta. Note that Meta also sends this webhook when the business disconnects, so calling the API twice results in an error.
Business-initiated disconnect example
import { DisconnectWhatsAppCallRequest_DisconnectReason } from '@livekit/protocol';await api.connector.disconnectWhatsAppCall('call-id-from-meta','your-meta-access-token',DisconnectWhatsAppCallRequest_DisconnectReason.BUSINESS_INITIATED,);await lkapi.connector.disconnect_whatsapp_call(api.DisconnectWhatsAppCallRequest(whatsapp_call_id="call-id-from-meta",whatsapp_api_key="your-meta-access-token",disconnect_reason=api.DisconnectWhatsAppCallRequest.BUSINESS_INITIATED,))lkapi.connector.disconnect_whatsapp_call(LiveKit::Proto::DisconnectWhatsAppCallRequest.new(whatsapp_call_id: 'call-id-from-meta',whatsapp_api_key: 'your-meta-access-token',disconnect_reason: LiveKit::Proto::DisconnectWhatsAppCallRequest::DisconnectReason::BUSINESS_INITIATED,),)_, err := api.Connector().DisconnectWhatsAppCall(context.Background(), &livekit.DisconnectWhatsAppCallRequest{WhatsappCallId: "call-id-from-meta",WhatsappApiKey: "your-meta-access-token",DisconnectReason: livekit.DisconnectWhatsAppCallRequest_BUSINESS_INITIATED,})if err != nil {// Handle error}import livekit.LivekitConnectorWhatsapp.DisconnectWhatsAppCallRequest.DisconnectReasonval response = api.connector.disconnectWhatsAppCall(whatsappCallId = "call-id-from-meta",whatsappApiKey = "your-meta-access-token",disconnectReason = DisconnectReason.BUSINESS_INITIATED,).execute()use livekit_protocol as proto;api.connector().disconnect_whatsapp_call("call-id-from-meta","your-meta-access-token",proto::disconnect_whats_app_call_request::DisconnectReason::BusinessInitiated,).await?;User-initiated disconnect example
When you receive a call terminate webhook from Meta indicating the user hung up, call
DisconnectWhatsAppCallwithUSER_INITIATEDto clean up the connector session. No API key is needed because no call to WhatsApp is made:import { DisconnectWhatsAppCallRequest_DisconnectReason } from '@livekit/protocol';await api.connector.disconnectWhatsAppCall('call-id-from-meta','', // no API key neededDisconnectWhatsAppCallRequest_DisconnectReason.USER_INITIATED,);await lkapi.connector.disconnect_whatsapp_call(api.DisconnectWhatsAppCallRequest(whatsapp_call_id="call-id-from-meta",disconnect_reason=api.DisconnectWhatsAppCallRequest.USER_INITIATED,))lkapi.connector.disconnect_whatsapp_call(LiveKit::Proto::DisconnectWhatsAppCallRequest.new(whatsapp_call_id: 'call-id-from-meta',disconnect_reason: LiveKit::Proto::DisconnectWhatsAppCallRequest::DisconnectReason::USER_INITIATED,),)_, err := api.Connector().DisconnectWhatsAppCall(context.Background(), &livekit.DisconnectWhatsAppCallRequest{WhatsappCallId: "call-id-from-meta",DisconnectReason: livekit.DisconnectWhatsAppCallRequest_USER_INITIATED,})import livekit.LivekitConnectorWhatsapp.DisconnectWhatsAppCallRequest.DisconnectReasonval response = api.connector.disconnectWhatsAppCall(whatsappCallId = "call-id-from-meta",whatsappApiKey = "",disconnectReason = DisconnectReason.USER_INITIATED,).execute()use livekit_protocol as proto;api.connector().disconnect_whatsapp_call("call-id-from-meta","", // no API key neededproto::disconnect_whats_app_call_request::DisconnectReason::UserInitiated,).await?;Accepting inbound calls
To accept inbound WhatsApp calls, you must handle webhooks from Meta and call the
AcceptWhatsAppCallAPI.Workflow
A user calls your WhatsApp Business number.
Meta sends a
call connectwebhook containing call details and the SDP offer.Your app calls
AcceptWhatsAppCallwith the information from the webhook to accept the call.The API returns the
RoomNamefor the call. If the API doesn't return an error, the call is connected.
Required webhooks
For inbound calls, WhatsApp sends a
call connectwebhook that includes the SDP offer. Your app must receive this webhook and pass the SDP offer to theAcceptWhatsAppCallAPI to complete the connection.Example
The following webhook handler example processes the
call connectwebhook and calls theAcceptWhatsAppCallAPI with the following parameters:Parameter Required Description WhatsAppPhoneNumberIdYes Your WhatsApp Business phone number ID. WhatsAppApiKeyYes Your Meta API key. To learn more, see Generate an access token . WhatsAppCloudApiVersionYes WhatsApp Cloud API version (for example, 23.0,24.0, or25.0).WhatsAppCallIdYes WhatsApp call ID provided by Meta in the webhook. SdpYes The SDP offer provided by Meta in the webhook. The webhook handler creates a room named
whatsapp-connector-roomand dispatches the agent namedwhatsapp-agentto the room after the connection is established:import { ServerError } from 'livekit-server-sdk';// In your webhook handlerasync function handleWhatsAppCallWebhook(webhookData: WhatsAppCallWebhook) {try {const response = await connectorClient.acceptWhatsAppCall({whatsappPhoneNumberId: '<whatsapp-business-phone-number-id>',whatsappApiKey: '<meta-access-token>',whatsappCloudApiVersion: '25.0',whatsappCallId: webhookData.callId,sdp: webhookData.sdp,roomName: 'whatsapp-connector-room',agents: [{ agentName: 'whatsapp-agent' }],// Block until the inbound party (your agent) joins the room before returning.waitUntilAnswered: true,});} catch (e) {if (e instanceof ServerError) {// The agent did not join the conversation.console.error('Failed to accept WhatsApp call:', e.message);}}}from livekit.protocol.agent_dispatch import RoomAgentDispatch# In your webhook handlerasync def handle_whatsapp_call_webhook(webhook_data):try:response = await lkapi.connector.accept_whatsapp_call(api.AcceptWhatsAppCallRequest(whatsapp_phone_number_id="<whatsapp-business-phone-number-id>",whatsapp_api_key="<meta-access-token>",whatsapp_cloud_api_version="25.0",whatsapp_call_id=webhook_data.call_id,sdp=webhook_data.sdp,room_name="whatsapp-connector-room",agents=[RoomAgentDispatch(agent_name="whatsapp-agent")],# Block until the inbound party (your agent) joins the room before returning.wait_until_answered=True,))except api.ServerError as e:# The agent did not join the conversation.print(f"Failed to accept WhatsApp call: {e.message}")# In your webhook handlerdef handle_whatsapp_call_webhook(webhook_data)request = LiveKit::Proto::AcceptWhatsAppCallRequest.new(whatsapp_phone_number_id: '<whatsapp-business-phone-number-id>',whatsapp_api_key: '<meta-access-token>',whatsapp_cloud_api_version: '25.0',whatsapp_call_id: webhook_data.call_id,sdp: webhook_data.sdp,room_name: 'whatsapp-connector-room',agents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: 'whatsapp-agent')],# Block until the inbound party (your agent) joins the room before returning.wait_until_answered: true)beginresponse = lkapi.connector.accept_whatsapp_call(request)rescue LiveKit::ServerError => e# The agent did not join the conversation.puts "Failed to accept WhatsApp call: #{e.message}"endend// In your webhook handlerfunc handleWhatsAppCallWebhook(w http.ResponseWriter, r *http.Request) {// Parse webhook payload from Metavar webhookData WhatsAppCallWebhookjson.NewDecoder(r.Body).Decode(&webhookData)// Accept the callresponse, err := connectorClient.AcceptWhatsAppCall(context.Background(), &livekit.AcceptWhatsAppCallRequest{WhatsappPhoneNumberId: "<whatsapp-business-phone-number-id>",WhatsappApiKey: "<meta-access-token>",WhatsappCloudApiVersion: "25.0",WhatsappCallId: webhookData.CallId,Sdp: webhookData.Sdp,RoomName: "whatsapp-connector-room",Agents: []*livekit.RoomAgentDispatch{{AgentName: "whatsapp-agent",},},// Block until the inbound party (your agent) joins the room before returning.WaitUntilAnswered: true,})if err != nil {// The agent did not join the conversation.w.WriteHeader(http.StatusInternalServerError)return}w.WriteHeader(http.StatusOK)}import io.livekit.server.ServerErrorimport io.livekit.server.WhatsAppCallOptionsimport livekit.LivekitAgentDispatch.RoomAgentDispatchimport livekit.LivekitRtc.SessionDescription// In your webhook handlerfun handleWhatsAppCallWebhook(webhookData: WhatsAppCallWebhook) {val response = connectorClient.acceptWhatsAppCall(whatsappPhoneNumberId = "<whatsapp-business-phone-number-id>",whatsappApiKey = "<meta-access-token>",whatsappCloudApiVersion = "25.0",whatsappCallId = webhookData.callId,sdp = webhookData.sdp,// Block until the inbound party (your agent) joins the room before returning.waitUntilAnswered = true,options = WhatsAppCallOptions(roomName = "whatsapp-connector-room",agents = listOf(RoomAgentDispatch.newBuilder().setAgentName("whatsapp-agent").build(),),),).execute()if (!response.isSuccessful) {// The agent did not join the conversation.val error = ServerError.from(response)println("Failed to accept WhatsApp call: ${error?.message}")}}use livekit_api::services::connector::{ConnectorClient, AcceptWhatsAppCallOptions};use livekit_protocol::RoomAgentDispatch;// In your webhook handlerasync fn handle_whatsapp_call_webhook(connector_client: &ConnectorClient,webhook_data: &WhatsAppCallWebhook,) {let result = connector_client.accept_whatsapp_call("<whatsapp-business-phone-number-id>","<meta-access-token>","25.0",&webhook_data.call_id,webhook_data.sdp.clone(),AcceptWhatsAppCallOptions {room_name: Some("whatsapp-connector-room".into()),agents: Some(vec![RoomAgentDispatch {agent_name: "whatsapp-agent".into(),..Default::default()}]),// Block until the inbound party (your agent) joins the room before returning.wait_until_answered: Some(true),..Default::default()},).await;if let Err(e) = result {// The agent did not join the conversation.eprintln!("Failed to accept WhatsApp call: {e}");}}The same optional parameters as for outbound calls are available for customizing the participant and room. For explicit agent dispatch, make sure to include the
Agentsparameter.AcceptWhatsAppCallhandles an inbound call, soWaitUntilAnsweredhas a different meaning than it does when placing an outbound call. Here it blocks the response until the other inbound party — typically your agent — joins the room, rather than waiting for a callee to pick up. Leave it unset to return as soon as the call is accepted.For a full list of parameters and their descriptions, see the AcceptWhatsAppCall API reference.
Setting up webhooks
This section covers the required configuration steps in the Meta Developer Console. To learn more about implementing a webhook handler, see the WhatsApp webhook configuration guide .
To configure WhatsApp call webhooks:
- Sign in to the Meta Developer Console and select your app.
- Select WhatsApp → Configuration.
- Enter the webhook URL in Callback URL.
- Enter any string for Verify token. Save it for your webhook handler.
- Subscribe to the events you want to receive. At a minimum, enable the
callsevent. - Select the same Version for all subscribed webhooks: v23.0, v24.0, or v25.0.
Agent dispatch
You can automatically dispatch LiveKit Agents to WhatsApp calls by including agent dispatch rules in your call requests, enabling your AI agents to interact with WhatsApp callers.
To explicitly dispatch a specific agent to an inbound or outbound call, use the
Agentsparameter in theAcceptWhatsAppCallorDialWhatsAppCallAPI:// ... other parametersagents: [{agentName: 'whatsapp-agent',metadata: '{"language": "en", "department": "sales"}',},],from livekit.protocol.agent_dispatch import RoomAgentDispatch# ... other parametersagents=[RoomAgentDispatch(agent_name="whatsapp-agent",metadata='{"language": "en", "department": "sales"}',),],# ... other parametersagents: [LiveKit::Proto::RoomAgentDispatch.new(agent_name: 'whatsapp-agent',metadata: '{"language": "en", "department": "sales"}',),],// ... other parametersAgents: []*livekit.RoomAgentDispatch{{AgentName: "whatsapp-agent",Metadata: `{"language": "en", "department": "sales"}`,},},import livekit.LivekitAgentDispatch.RoomAgentDispatch// ... other parametersagents = listOf(RoomAgentDispatch.newBuilder().setAgentName("whatsapp-agent").setMetadata("""{"language": "en", "department": "sales"}""").build(),),use livekit_protocol::RoomAgentDispatch;// ... other parametersagents: Some(vec![RoomAgentDispatch {agent_name: "whatsapp-agent".into(),metadata: r#"{"language": "en", "department": "sales"}"#.into(),}]),For more information on creating voice agents, see the LiveKit Agents documentation.
Regional routing
Use the
destination_countryparameter to optimize call routing based on the caller's location. Provide an ISO 3166-1 alpha-2 code (for example,US,GB,IN).const response = await api.connector.dialWhatsAppCall({// ... other parametersdestinationCountry: 'US',});response = await lkapi.connector.dial_whatsapp_call(api.DialWhatsAppCallRequest(# ... other parametersdestination_country="US",))response = lkapi.connector.dial_whatsapp_call(LiveKit::Proto::DialWhatsAppCallRequest.new(# ... other parametersdestination_country: 'US',),)response, err := api.Connector().DialWhatsAppCall(context.Background(), &livekit.DialWhatsAppCallRequest{// ... other parametersDestinationCountry: "US",})val response = api.connector.dialWhatsAppCall(// ... other required parametersoptions = WhatsAppCallOptions(destinationCountry = "US",),).execute()let response = api.connector().dial_whatsapp_call(// ... other required parametersDialWhatsAppCallOptions {destination_country: Some("US".into()),..Default::default()},).await?;Troubleshooting
The following troubleshooting steps can help you resolve common issues with the WhatsApp Connector.
Call not connecting
- Verify your WhatsApp API key permissions.
- Ensure your phone number is registered and verified.
- Confirm the correct Cloud API version.
- Check webhook URL accessibility from Meta.
Audio quality issues
- Check network connectivity between LiveKit and Meta.
- Confirm that media tracks are being published correctly.
- Use
destination_countryto optimize routing.
Webhook not receiving events
- Verify the webhook URL.
- Ensure the endpoint is publicly accessible.
- Check event subscriptions.
- Validate webhook signatures if enabled.
Next steps