Connect Klaviyo with InstantDM
Create or update Klaviyo profiles from Instagram DM leads automatically. Optionally add them to a specific list for segmentation and flow-based email/SMS.
What you get
- Every Instagram lead with an email becomes a Klaviyo profile.
- first_name, phone_number, and the Instagram handle (as a custom property) populate from the flow.
- Source tagged via custom property
source: "instantdm"so you can filter Instagram-sourced profiles. - Optional: add new profiles to a specific Klaviyo list for segmentation or email/SMS flows.
- Klaviyo's profile API accepts arbitrary properties — handles existing profiles via 409 detection.
Prerequisites
| Requirement | Details |
|---|---|
| InstantDM plan | Any plan that includes integrations (Trendsetter Pro and above, or any Multi plan). |
| Klaviyo account | Any tier — Klaviyo's profiles API is on all plans. |
| Klaviyo Private API Key | Required. Created in Klaviyo → Settings → API Keys. |
| Klaviyo List ID | Optional. Only needed if you want every Instagram lead added to a specific list. |
| A flow that asks for email | Klaviyo identifies profiles by email — without it, no push happens. |
Step 1 — Generate a Klaviyo Private API Key
- Log in to klaviyo.com.
- Click your account name (top-right) → Settings.
- Open API Keys → Create Private API Key.
- Name it "InstantDM" so it's identifiable.
- Scopes: grant Profiles: Read/Write. If you'll use the List ID feature, also grant Lists: Read/Write.
- Click Create and copy the key. It starts with
pk_.
Heads up: Klaviyo only shows the key once. Save it somewhere safe — if you lose it, generate a new one.
Step 2 (Optional) — Get your List ID
If you want every Instagram lead added to a specific Klaviyo list:
- In Klaviyo, go to Lists & Segments.
- Click the list you want.
- Copy the list ID from the URL — it's the segment after
/list/(e.g.https://www.klaviyo.com/list/WqL7Pa/...).
Step 3 — Add it in InstantDM
- In InstantDM, open Account Settings → Integrations.
- Click Klaviyo in the left list.
- Paste the Private API Key into the API Key field.
- Optionally paste the List ID.
- Click Save. The integration shows as "Connected".
Step 4 — Enable Klaviyo on a flow
- Open a flow in the flow editor.
- Click the Integrations button in the toolbar.
- Toggle Klaviyo on. (Greyed-out with a "Not connected" tag means the API key isn't saved yet — go back to Step 3.)
- Click Set Live to publish.
Step 5 — Choose when to push
| Mode | When the push fires | Best for |
|---|---|---|
| On flow completion (default) | Once, when the flow ends. | Most flows. Single profile POST with email + first_name + phone_number + properties. |
| Each answer | After every accepted question answer. | Long flows or AI conversations where you want profiles to appear in Klaviyo in real time. |
When AI Reply is in the flow
If the flow has an AI Reply node, the trigger is locked to Each answer — AI conversations are open-ended and don't have a deterministic completion event. The AI extracts lead data (email, name, phone) turn-by-turn, and each new field fires a Klaviyo profile call.
What InstantDM sends to Klaviyo
For each push, InstantDM calls POST https://a.klaviyo.com/api/profiles/ with:
{
"data": {
"type": "profile",
"attributes": {
"email": "<contact email>",
"first_name": "<from 'name' question>",
"phone_number": "<from 'phone' question>",
"properties": {
"source": "instantdm",
"ig_username": "<contact's Instagram handle>"
}
}
}
} If you set a List ID in Step 3, AND the profile creation returned an ID (either a 200/201 with a new data.id or a 409 with duplicate_profile_id), InstantDM makes a follow-up call:
POST /api/lists/<your List ID>/relationships/profiles/
This adds the profile to the Klaviyo list you configured. If you didn't set a List ID, this step is skipped — the profile still gets created, it just isn't added to any specific list.
Handling existing profiles
When a contact's email already exists in Klaviyo:
- The POST returns HTTP 409 Conflict with the existing profile's ID in the error body.
- InstantDM extracts that ID from
errors[0].meta.duplicate_profile_id. - If a list is configured, the existing profile is added to it (no duplicate created).
- The profile's attributes are not overwritten — Klaviyo's POST is create-only. To update existing profiles, use Klaviyo's PATCH endpoint via the Webhook integration.
Troubleshooting
HTTP 401 or 403 in the logs
The API key is invalid, revoked, or missing scopes. Generate a new key in Klaviyo → Settings → API Keys with Profiles: Read/Write (and Lists: Read/Write if you're using the list feature). Update it in InstantDM Settings.
Profile created but not added to my list
Check three things: (1) the List ID is set in InstantDM Settings → Integrations → Klaviyo; (2) the API key has Lists: Read/Write scope; (3) the list ID is correct (copy it from the Klaviyo URL, not the list name).
"No email yet, skipping" in the logs
InstantDM can't push to Klaviyo without an email. Add an email question to your flow, or — for AI flows — make sure your AI prompt asks for the email.
I want to trigger a Klaviyo flow on new Instagram leads
In Klaviyo, create a flow with the trigger List trigger: added to list targeting the list ID you configured. Every Instagram lead will enter the flow automatically. Alternative: use the custom property source = "instantdm" as a segment definition and target it from any Klaviyo flow or campaign.