SIP Configuration

Use SIP signaling instead of Graph API + webhooks for WhatsApp calling. TLS certificate requirements, digest authentication, business and user initiated SIP flows, SDES vs DTLS for SRTP, custom SIP headers.

What SIP Mode Is

Session Initiation Protocol (SIP) is the standard signaling protocol for VoIP. WhatsApp Business Calling can use SIP for call signaling instead of Graph API endpoints + calls webhooks.

When SIP is enabled on a business phone number:

  • Calling-related Graph API endpoints (/<PHONE_NUMBER_ID>/calls) stop working — return error 131055.
  • Calling webhooks (calls field) are not sent.
  • Messaging Graph API + webhooks continue to work normally — SIP only intercepts the calling signaling path.

Use SIP if you have a SIP-based contact center, IVR, or telephony infrastructure that needs native SIP integration. Otherwise, prefer Graph API + webhooks for simpler operations.

Trade-offs vs Graph API + Webhooks

Graph API + WebhooksSIP
Setup complexityLower — webhook endpoint + WebRTC stackHigher — SIP server + TLS certificate + digest auth
Operational overheadLowerHigher (TLS cert lifecycle, SIP server uptime)
Native fit for SIP-based call centersAwkward (need translation layer)Native
Calling webhooksYesNo — SIP messages replace them
Functional parityYesYes
Recommended forMost setupsOnly when SIP is already core infra

Prerequisites

  • All standard calling prerequisites met.
  • Your app has whatsapp_business_messaging for the business phone number — verify by sending a test message before configuring SIP.
  • Your app mode is Live, not Development.
  • A standards-compliant third-party SIP server that supports TLS transport and digest authentication.

TLS Certificate Requirements

TLS transport is mandatory for SIP. Two requirements:

  1. Meta's cert has subject name wa.meta.vc. Your SIP client should validate it.
  2. Your SIP server's cert must have a subject name covering the SIP domain you configure (e.g. meta-voip.example.com). Meta validates it on connection.

Meta does not support mutual TLS. When Meta acts as a TLS client, your TLS server must not request a client certificate. If you do, Meta returns a cert with a random dynamic-host subject that won't pass your validation.

Verify your TLS setup before reporting that calls aren't being delivered:

openssl s_client -quiet -verify_hostname meta-voip.example.com -connect meta-voip.example.com:5061

A valid cert returns verify return:1 for each depth and connects cleanly. Hostname mismatch produces verify error:num=62:hostname mismatch. Connection refused / timeout means the host isn't listening for TLS on that port.

Configure SIP

POST /<PHONE_NUMBER_ID>/settings
{
  "calling": {
    "sip": {
      "status": "ENABLED",
      "servers": [
        {
          "hostname": "sip.example.com",
          "port": 5061,
          "request_uri_user_params": {
            "tgrp": "wacall",
            "trunk-context": "byoc.example.com"
          }
        }
      ]
    }
  }
}
FieldNotes
statusENABLED makes SIP exclusive (no Graph API/webhooks for calling). DISABLED is the default. Disabling does NOT clear servers — they persist for re-enabling.
servers[]One server per phone number. Multiple entries in the GET response means different apps configured different servers (we extract the app from the access token).
hostnameTLS-only. Your SIP server hostname.
portTLS port (default 5061).
request_uri_user_paramsOptional key/value pairs added to the user portion of the request URI. Useful for trunk groups (tgrp, trunk-context per RFC 4904). Max key/value 128 chars each.

To delete a SIP server, pass an empty servers array. If servers remain afterward, they belong to a different app — disable SIP entirely or use the corresponding app's token to clear them.

At least one SIP server (any app) must exist when sip.status: ENABLED.

Get and Include SIP Password

Meta generates a unique SIP password per (phone number + app) combination. Retrieve it by adding ?include_sip_credentials=true to the GET settings call:

GET /<PHONE_NUMBER_ID>/settings?include_sip_credentials=true
{
  "calling": {
    "sip": {
      "status": "ENABLED",
      "servers": [
        {
          "app_id": 123456789012345,
          "hostname": "sip.example.com",
          "sip_user_password": "<SIP_USER_PASSWORD>"
        }
      ]
    }
  }
}

Configure this password on your SIP server so it can respond to digest authentication challenges from Meta. Treat the password as a secret — Dualhook customers should pull it via API and store it themselves; we don't proxy or cache it.

Reset SIP Password

There's no dedicated "rotate password" endpoint. To force regeneration:

  1. Disable SIP and clear servers (status: "DISABLED", servers: []).
  2. Re-enable SIP with your server (status: "ENABLED", servers: [{ "hostname": "..." }]).
  3. Fetch with include_sip_credentials=true to read the new password.

Make sure you've recorded any old password before doing this — the rotation is irreversible.

Business-Initiated SIP Flow

  1. Send an initial SIP INVITE to wa.meta.vc. Request URI for calling user +11234567890: sip:+11234567890@wa.meta.vc;transport=tls.
  2. Meta returns SIP/2.0 407 Proxy Authentication Required with a WWW-Authenticate header.
  3. Send a second INVITE with a proper Authorization header per RFC 3261 digest auth — username = your business phone number (normalized), password = Meta-generated SIP password.
  4. Meta routes the call to the WhatsApp user.

Constraints on your INVITE:

  • From header username: fully normalized business phone number.
  • From header domain: must match the SIP server hostname you configured.
  • SDP offer: WebRTC-compatible (ICE + DTLS-SRTP + OPUS) — or SDES if configured (see below).

If you receive 403 SIP server foo.com from INVITE does not match any SIP server configured for phone number id [ID], your From header domain doesn't match the SIP server hostname stored in your config. Sub-domains of the configured domain are valid (e.g. bar.foo.com matches foo.com).

User-Initiated SIP Flow

  1. WhatsApp user calls your business number.
  2. Meta sends a SIP INVITE to your configured SIP server.
  3. Recommended: challenge with 407 Proxy Authentication Required (digest auth). Meta resends the INVITE with the auth header.
  4. Respond with 200 OK containing your SDP answer.

If you don't challenge (no digest auth), Meta sends the INVITE without auth — security best practice is to challenge.

User experience is identical whether you're on SIP or Graph API — the user has no idea which signaling path you use.

If your SIP server doesn't receive the INVITE, the most common causes are TLS certificate validation errors, app permission mismatch, or firewall / port reachability issues.

Custom SIP Headers

Meta adds these custom headers to SIP requests:

HeaderWhenValue
x-wa-meta-call-durationSIP BYE from Meta on established callsCall duration in seconds
x-wa-meta-wacidSIP INVITE (UIC) and BYE (UIC + BIC)WhatsApp call ID
x-wa-meta-cta-payloadUIC INVITE when call originated from a voice_call button with payloadBusiness-specified payload
x-wa-meta-deeplink-payloadUIC INVITE when call originated from a wa.me/call/<num>?biz_payload=... deep linkBusiness-specified payload

SDES vs DTLS for SRTP Key Exchange

SRTP needs a key-exchange mechanism. Two options:

DTLS (default)SDES
Industry-standardYesOlder standard
Requires ICE/DTLS handshakeYesNo
Call setup timeSlower (handshake completes after SDP exchange)Faster (key in SDP, sent over secure SIP)
Supports WebRTC stacksYesYes
When to preferDefault for most setupsWhen using SIP and you want shorter call setup, or to address audio clipping caused by DTLS retry intervals

DTLS retries on a 1s, 2s, 4s backoff — common SIP setups see ~3 seconds of dropped media at call start while waiting for the DTLS client hello. SDES sends the key in the SDP itself, so SRTP can flow immediately after SDP exchange. See Calling Troubleshooting → Audio Clipping for the full audio-clipping mitigation menu.

Configure SRTP Key Exchange

POST /<PHONE_NUMBER_ID>/settings
{
  "calling": {
    "srtp_key_exchange_protocol": "SDES"
  }
}

Possible values: DTLS (default) or SDES.

To check current setting:

GET /<PHONE_NUMBER_ID>/settings

If the field has not been explicitly set, it's not returned.

Note: Meta still expects the business side to send the maiden SRTP packet for both UIC and BIC.

Common SIP Errors

SIP status / errorMeaningFix
400 Asset not foundFrom header phone number is not a registered business numberCheck the number and resend
403 SIP server X from INVITE does not match...From header domain doesn't match configured SIP server hostnameUpdate SIP config or From header
403 No Approved Call Permission FoundNo permission from recipient (or recipient not on WhatsApp)Get permission first (Call Permissions)
403 The app [APP_ID] configured for SIP server X is not authorized for phone number id [ID]App used to configure SIP doesn't have whatsapp_business_messaging on the numberReconfigure with the right app
403 Business Initiated Connected Call Per Day Limit Hit5 connected BICs in 24h reachedWait or check pricing tier
404 SIP INVITEs using IP in request URI are not allowedDon't use IP literal in request URIUse the correct request URI (see flow examples)
407 Proxy Authentication RequiredStandard digest auth challenge from MetaResend with Authorization header
408 RTP TimeoutNo media received for too longSee Audio Clipping & Media Issues
480 Temporarily UnavailableUser unreachable / didn't answerTry later; unanswered calls degrade permission
486 Busy HereUser declined the callTry later; rejections degrade permission
487 Request TerminatedYou sent SIP CANCEL before Meta respondedExpected — your CANCEL worked
503 Service UnavailableGeneric internal errorRetry later or contact Meta support

Full error reference and Graph-API-side errors on Calling Troubleshooting.

SIP FAQ

Why is user-initiated call disconnecting immediately after enabling SIP?

Most likely TLS certificate validation error. Run the openssl s_client check above.

Why am I not getting SIP requests when expected?

Common causes: TLS cert validation error, SIP not actually enabled (verify with GET settings), app that configured SIP lacks whatsapp_business_messaging, network/firewall blocking Meta's IP ranges, or SIP server not listening on the configured port. Verify TCP reachability with nc -zvw2 -G 2 <sip-host> <sip-port>.

Why is my SIP TERMINATE not hanging up the user?

Usually TLS handshake failure when your SIP server tries to establish TLS to Meta's. Capture SIP traffic with pcap or check SIP server logs.

Why does my SIP server keep responding 401 Unauthorized for UIC?

Meta supports digest auth. After your 401, Meta resends the INVITE with Authorization. Confirm your SIP server is configured with username = (normalized) business phone number, password = Meta-generated password. Or disable digest auth on your SIP server (not recommended).

Why is my SIP server responding 488 Not Acceptable Here?

Likely your SIP server doesn't support WebRTC ICE. Switch the business phone number to use SDES instead of DTLS.

Do I need to SIP REGISTER the business phone number to Meta?

No. REGISTER requests fail with 403 Forbidden. Meta's SIP server only owns the meta.vc domain (where WhatsApp consumers live). Your business numbers belong to the SIP domain you configure.

Does Meta support SIP re-INVITEs?

No. Returns 500 Internal Server Error.

SIP vs Graph API — is one functionally better?

No, they have parity. Pick based on your existing infrastructure.

If I use SIP, do I still need webhooks?

Yes — but only for messaging and other non-calling events. SIP only covers call signaling.

Does Meta have an approved list of SIP vendors / SBCs?

No. Any compatible standards-compliant SIP server works.

Related

  • Cloud API CallingVoice calling on WhatsApp Business Cloud API: VoIP via WebRTC or SIP, business-initiated and user-initiated calls, prerequisites, availability, and integration patterns.
  • Calling ConfigurationEnable calling on a business phone number, configure call hours and holidays, restrict the call icon by country, set callback permissions, choose audio codecs, listen for settings webhooks.
  • Calling TroubleshootingWhatsApp Calling errors and fixes: full error code table (138000-138023), SIP-specific status codes, media-flow timeouts, audio clipping causes and mitigations (SDES, pre-accept), quick triage guide.
Browse more docsStart Free Trial