Platform
Chatbot Builder Bulk Messaging Team Inbox Mini CRM API & Webhooks AI Integration WhatsApp Flows
Industries
E-commerce & D2C Real Estate Education Healthcare Finance & BFSI Logistics Hospitality Retail
Integrations 📚 Learn 📝 Blog 🗂 Codex Pricing Start Free Trial →
HomeConnect › Connect Klaviyo to WhatsApp
Klaviyo Integration Guide · Marketing / Email

Connect Klaviyo to WhatsApp

Add every WhatsApp opt-in to your Klaviyo profile list, look up subscriber history before personalising a message, and keep email and WhatsApp contact data in sync across both channels.

Published 23 June 2026  ·  7 min read  ·  Marketing / Email

Before following this guide, read the External API Request step foundation guide. It covers every field in the step interface so this guide can focus on Klaviyo-specific values.

Klaviyo uses a custom Authorization prefix and a mandatory revision header

Every Klaviyo API request needs two non-standard headers. First: Authorization: Klaviyo-API-Key YOUR_PRIVATE_KEY, not Bearer, not api-key. The literal prefix is Klaviyo-API-Key. Second: revision: 2025-01-15, the API version. Omitting either returns an error.

Klaviyo uses JSON:API format

All request and response bodies follow the JSON:API specification. Every request body wraps data in {{"data": {{"type": "...", "attributes": {{...}}}}}}. Every response returns data as an object or array with type, id, and attributes. This is different from the flat JSON bodies used by most other APIs in this series.

Step 1: Create a private API key

1
In Klaviyo, click your account name (bottom left) → SettingsAPI Keys.
2
Click Create Private API Key. Give it a name. Under Select Access Level, choose Custom Key and enable: profiles:read, profiles:write, lists:read, lists:write.
3
Click Create. Copy the key immediately. It is shown only once.
Official docs

Klaviyo REST API: developers.klaviyo.com

Step 2: Get your List ID

Klaviyo list IDs are short alphanumeric strings like Y6nRLr. Fetch them once and store the ID of the list where WhatsApp opt-ins should land.

External API Request Step · WA.Expert
Select Method
GET
Request URL
https://a.klaviyo.com/api/lists/
Select Auth Type
No Auth (Klaviyo-API-Key in header below)
Header Parameters
AuthorizationKlaviyo-API-Key YOUR_PRIVATE_KEY
revision2025-01-15
acceptapplication/vnd.api+json
Select Body Type
None (GET, no body)
Choose Response Type
JSON
GET /api/lists/ response
{{
  "data": [
    {{
      "type": "list",
      "id": "Y6nRLr",
      "attributes": {{
        "name": "WhatsApp Opt-Ins",
        "profile_count": 3842
      }}
    }}
  ]
}}

Copy: data[0].id = "Y6nRLr"
This string ID is used in all list subscription calls.

Step 3: Search for a profile by email

Before adding a contact, check whether they already exist in Klaviyo. The filter query syntax passes the email directly in the URL.

External API Request Step · WA.Expert
Select Method
GET
Request URL
https://a.klaviyo.com/api/profiles/?filter=equals(email,"{{{{customer_email}}}}")
Select Auth Type
No Auth (Klaviyo-API-Key in header below)
Header Parameters
AuthorizationKlaviyo-API-Key YOUR_PRIVATE_KEY
revision2025-01-15
acceptapplication/vnd.api+json
Select Body Type
None (GET, no body)
Choose Response Type
JSON
GET /api/profiles/?filter=equals(email,...) response
{{
  "data": [
    {{
      "type": "profile",
      "id": "01GMTZY2TEKN4KFRP30JZ59KGB",
      "attributes": {{
        "email":      "priya@example.com",
        "first_name": "Priya",
        "last_name":  "Sharma",
        "phone_number": "+919820000001",
        "created":    "2026-01-15T10:00:00Z"
      }}
    }}
  ]
}}

Map: data[0].id -> profile_id
     data[0].attributes.first_name -> profile_name
If data is empty, the profile does not exist yet — run Step 4.

Step 4: Create a profile (if new)

If Step 3 returned an empty data array, create the profile. All Klaviyo write requests use JSON:API format. The body must have a data object with a type and attributes.

External API Request Step · WA.Expert
Select Method
POST
Request URL
https://a.klaviyo.com/api/profiles/
Select Auth Type
No Auth (Klaviyo-API-Key in header below)
Header Parameters
AuthorizationKlaviyo-API-Key YOUR_PRIVATE_KEY
revision2025-01-15
acceptapplication/vnd.api+json
Content-Typeapplication/vnd.api+json
Select Body Type
JSON
Body
{{"data":{{"type":"profile","attributes":{{"email":"{{{{customer_email}}}}","first_name":"{{{{customer_name}}}}","phone_number":"{{{{customer_phone}}}}"}}}}}}
Choose Response Type
JSON
POST /api/profiles/ body and response
Body (JSON:API format):
{{
  "data": {{
    "type": "profile",
    "attributes": {{
      "email":        "{{customer_email}}",
      "first_name":   "{{customer_name}}",
      "phone_number": "{{customer_phone}}"
    }}
  }}
}}

Response (HTTP 201 Created):
{{
  "data": {{
    "type": "profile",
    "id":   "01GMTZY2TEKN4KFRP30JZ59KGB",
    "attributes": {{
      "email": "priya@example.com",
      "first_name": "Priya"
    }}
  }}
}}

Map: data.id -> profile_id
Use this profile_id in Step 5 to subscribe to a list.

Step 5: Subscribe the profile to a list

With {{profile_id}} and {{list_id}} (from Step 2) stored as variables, add the profile to the list:

External API Request Step · WA.Expert
Select Method
POST
Request URL
https://a.klaviyo.com/api/lists/{{{{list_id}}}}/relationships/profiles/
Select Auth Type
No Auth (Klaviyo-API-Key in header below)
Header Parameters
AuthorizationKlaviyo-API-Key YOUR_PRIVATE_KEY
revision2025-01-15
acceptapplication/vnd.api+json
Content-Typeapplication/vnd.api+json
Select Body Type
JSON
Body
{{"data":[{{"type":"profile","id":"{{{{profile_id}}}}"}}]}}
Choose Response Type
JSON (HTTP 204 on success)
POST /api/lists/{list_id}/relationships/profiles/ body and response
Body:
{{
  "data": [
    {{"type": "profile", "id": "{{profile_id}}"}}
  ]
}}

Response: HTTP 204 No Content (empty body = success)

The profile is now subscribed to the list.
If already subscribed, Klaviyo returns 204 again (idempotent).
HTTP 204 on success is normal

Klaviyo returns HTTP 204 No Content when a list subscription succeeds. There is no JSON body in the response. This is expected and correct, not an error.

Response field mapping:

Variable nameSourceExample value
profile_idStep 3 data[0].id or Step 4 data.id01GMTZY2TEKN4KFRP30JZ59KGB
profile_nameStep 3 data[0].attributes.first_namePriya
list_idStep 2 data[0].idY6nRLr

Store profile_id and list_id as persistent variables to avoid re-fetching them on every automation run.

Worked example: WhatsApp opt-in to Klaviyo list

Automation flow — sync WhatsApp opt-in to Klaviyo
Trigger: Customer messages 'SUBSCRIBE' on WhatsApp.

Captured: {{customer_email}} = priya@example.com
          {{customer_name}}  = Priya Sharma
          {{customer_phone}} = +919820000001

Step 1 — Search profile:
GET https://a.klaviyo.com/api/profiles/?filter=equals(email,"priya@example.com")
Authorization: Klaviyo-API-Key pk_...
revision: 2025-01-15

Response: data = [] (not found)

Conditions: if data not empty -> use data[0].id as profile_id, skip to Step 3
            if data empty     -> run Step 2

Step 2 — Create profile:
POST https://a.klaviyo.com/api/profiles/
Body: {{"data":{{"type":"profile","attributes":{{"email":"priya@example.com",
        "first_name":"Priya","phone_number":"+919820000001"}}}}}}

Response: data.id = '01GMTZY2TEKN4KFRP30JZ59KGB'
Stored as {{profile_id}}.

Step 3 — Subscribe to list:
POST https://a.klaviyo.com/api/lists/Y6nRLr/relationships/profiles/
Body: {{"data":[{{"type":"profile","id":"{{profile_id}}"}}]}}

Response: HTTP 204 (success, no body)

Bot replies:
'You are now subscribed, Priya! You will receive updates
at priya@example.com.'

Troubleshooting

SymptomLikely causeFix
401 errorWrong Authorization formatUse 'Authorization: Klaviyo-API-Key YOUR_KEY'. Not Bearer, not api-key. Ensure there is a space between Klaviyo-API-Key and the key value.
403 ForbiddenMissing required scopes on the API keyThe private key needs profiles:read, profiles:write, lists:read, lists:write. Delete the key and create a new one with the correct scopes.
400 on POST profilesWrong JSON:API body structureEnsure the body is wrapped as: {data: {type: 'profile', attributes: {...}}}. A flat JSON body returns 400.
revision header errorMissing or wrong revision headerAdd revision: 2025-01-15 to every request. Without it, Klaviyo may return deprecated behaviour or errors.
data array empty on profile searchProfile not in KlaviyoThe email does not exist as a Klaviyo profile. Proceed to create it with POST /profiles/.
204 on list subscriptionNormal success responseHTTP 204 No Content means the profile was successfully added to the list. There is no response body. This is not an error.

Common questions

What is the Klaviyo Authorization header format?
+
Authorization: Klaviyo-API-Key YOUR_PRIVATE_KEY. Not Bearer, not api-key. The prefix is Klaviyo-API-Key followed by a space.
Is the revision header required?
+
Yes, on every request. Use revision: 2025-01-15. Without it Klaviyo may return deprecated behaviour.
Why does Klaviyo use JSON:API format?
+
Klaviyo follows the JSON:API spec. All bodies are wrapped in data.type and data.attributes. All responses return data as an object or array with type, id, attributes.
How do I search a profile by email?
+
GET /api/profiles/?filter=equals(email,"priya@example.com") with Klaviyo-API-Key and revision headers. Empty data array means not found.
How do I add a WhatsApp contact to a list?
+
Create the profile first (POST /profiles/) to get a profile ID, then POST to /lists/{list_id}/relationships/profiles/ with the profile ID. Returns 204 on success.
Does this incur extra WA.Expert charges?
+
One automation action per External API Request call. Included on the Complete plan. Starter: from Rs. 49 per 1,000 actions.

Connect Mailchimp to WhatsApp

Mailchimp API: data centre prefix, anystring auth, subscriber upsert.

Read guide →

Connect Brevo to WhatsApp

Brevo API: api-key header, contact upsert, list sync.

Read guide →

External API Request Step

Master every field in WA.Expert's HTTP action step.

Read foundation guide →

Connect Klaviyo to WhatsApp today

Free trial, no credit card. If you get stuck, we answer live on WhatsApp.

Start Free Trial → Book a Demo
1