DEV Community

Cover image for CF7 Submissions Not Reaching Klaviyo? Here Is What Is Actually Going On
Rahul Sharma
Rahul Sharma

Posted on

CF7 Submissions Not Reaching Klaviyo? Here Is What Is Actually Going On

A site owner posted on the WordPress forums that their signup form was not sending data to Klaviyo. The API key was correct. The list ID was correct. Everything looked set up properly, but submissions were not showing up.

The plugin author asked a clarifying question that turned out to be the key to the whole problem: did the form fail to submit with an error message, or did it submit successfully but the new contact never appeared in the Klaviyo list? Those are two completely different problems with two completely different fixes.

The site owner eventually found a setting that was wrong and fixed it themselves, but never said which one. This post covers every place a CF7 to Klaviyo integration can break, what each failure looks like, and how to fix it.

The First Thing to Check: List vs Campaign

This is the single most common confusion with Klaviyo integrations and it is worth ruling out before anything else.

When your CF7 form adds someone to Klaviyo, it only adds them to a list. It does not enroll them in a campaign. These are two separate things in Klaviyo. A list is a static collection of contacts. A campaign is an email that gets sent out, either immediately or on a schedule.

If you check your Klaviyo list and the new contact is sitting there correctly, your integration is working. If you were expecting them to receive an automatic welcome email and nothing arrived, that is a separate Klaviyo flow setup issue, not an integration issue. You need a Klaviyo flow that triggers when someone is added to that specific list, and that flow needs to be turned on. Check Klaviyo under Flows and confirm a "List Subscribed" trigger flow exists and is live, not in draft.

If the contact is not even appearing in the list at all, the problem is somewhere in the API call itself. Keep reading.

Reason 1: Using the Wrong Klaviyo API Version

Klaviyo has deprecated several older API endpoints over the past few years. If your integration was set up a while ago, or if a tutorial you followed was written before the changes, you might be using endpoints that no longer work the way you expect.

The old v1/v2 endpoints like POST /api/v2/list/{list_id}/subscribe are deprecated. If your plugin or custom code is still using them, the request can fail silently or return an error that your integration is not surfacing to you.

The current correct approach uses two separate API calls. First you create or update the profile:

POST https://a.klaviyo.com/api/profiles/
Enter fullscreen mode Exit fullscreen mode

Then you add that profile to a list, or better yet, subscribe them with consent:

POST https://a.klaviyo.com/api/profile-subscription-bulk-create-jobs/
Enter fullscreen mode Exit fullscreen mode

This second endpoint is what Klaviyo recommends if you want the contact's consent properly recorded, rather than just silently dropping them into a list with no marketing consent on record. If your form is a signup form meant for email campaigns, you want consent recorded correctly. Otherwise Klaviyo will treat the contact as not subscribed even though they appear in your list.

Reason 2: Authentication Header Format Is Wrong

Klaviyo's API requires the Authorization header in a very specific format:

Authorization: Klaviyo-API-Key pk_your_private_key_here
Enter fullscreen mode Exit fullscreen mode

A common mistake is using Bearer instead of Klaviyo-API-Key:

Authorization: Bearer pk_your_private_key_here
Enter fullscreen mode Exit fullscreen mode

This looks correct because Bearer is the standard format for most APIs, but Klaviyo specifically requires its own prefix. Using the wrong prefix returns a 401 authentication error. If your integration is silently failing and you have not checked the raw error response, this is one of the first things to verify.

You also need the API revision header on every request:

revision: 2024-10-15
Enter fullscreen mode Exit fullscreen mode

Klaviyo versions its API by date. Missing this header can cause requests to behave unpredictably or get rejected depending on which default revision your account falls back to.

Reason 3: Missing Required Identifier on the Profile

Klaviyo requires at least one identifier to create a profile: an email address, a phone number, or an external ID. If your CF7 form only collects a phone number and your integration sends the request without an email and without marking the phone number correctly, Klaviyo returns:

{
  "detail": "One or more identifiers is required"
}
Enter fullscreen mode Exit fullscreen mode

Check what fields your CF7 form actually sends to Klaviyo. If the form has an email field, make sure it is actually included in the payload and not accidentally left out of the field mapping.

Reason 4: Profile Already Exists (409 Conflict)

If someone has previously interacted with your Klaviyo account under the same email, trying to create them again as a brand new profile can return a 409 conflict:

{
  "detail": "A profile already exists with one of these identifiers"
}
Enter fullscreen mode Exit fullscreen mode

This does not mean your integration is broken. It means Klaviyo already has a profile for that person somewhere in your account, even if they are not in the specific list you are checking. The correct behaviour is to update the existing profile rather than attempting to create a new one. Using the subscribe/bulk job endpoint mentioned above handles this correctly because it performs an upsert: it updates the profile if it exists, or creates it if it does not.

How to Set This Up Correctly Without Managing API Versions Yourself

Klaviyo's API has changed enough times that hand-rolled integrations or older plugins frequently break without obvious warning. The safest way to connect Contact Form 7 to Klaviyo reliably is to use a tool that calls Klaviyo's current API endpoints correctly and gives you visibility into what is actually being sent and received.

Contact Form to API lets you set up a Contact Form 7 to Klaviyo integration by configuring the exact Klaviyo endpoint, adding your API key with the correct Klaviyo-API-Key header format, and mapping your CF7 form fields to the profile attributes Klaviyo expects. You also get visibility into the response from each submission, so if something does fail, you see the actual error from Klaviyo instead of guessing why a contact never showed up.

This removes the guesswork around API versions, header formats, and consent handling that trips up most manual CF7 to Klaviyo setups.

Quick Checklist

If your CF7 form is not sending data to Klaviyo, work through these in order.

Check whether the contact actually appears in your Klaviyo list. If they do, your integration works and the issue is with a flow or campaign not being triggered, which is a separate Klaviyo setup task.

Confirm you are using current API endpoints, not the deprecated v1/v2 versions.

Check your Authorization header uses Klaviyo-API-Key, not Bearer.

Confirm your CF7 form sends at least one valid identifier (email, phone, or external ID) to Klaviyo.

If you see a 409 conflict error, switch to the subscribe/bulk job endpoint which performs an upsert instead of a strict create.

Top comments (0)