HomeGuidesAPI Reference
ChangelogHelp CenterCommunityContact Us
Guides

Bulk Import Profiles API

This guide will walk you through our new Bulk Import Profiles API. If you have worked with our list upload feature or SFTP import tool, you can now access this same functionality with Klaviyo’s Bulk Import Profiles API.

The Bulk Import Profiles API performs an upsert, meaning it will update matching profiles if they already exist in your account or create them if no matching profiles are found. You can also optionally add these profiles to a list.

🚧

Clearing fields with null values

The Bulk Import Profiles API does not support setting fields to null to clear them. Only fields explicitly provided with non-null values will be updated. To remove a field value from a profile, use the Update Profile endpoint with the field set to null, or the Create or Update Profile endpoint.

Here are some example use cases supported by the Bulk Import Profiles API:

  • Import many profiles as part of onboarding.
  • Update custom properties to deliver personalized experiences in flow & campaign messaging (e.g., preferences, favorite color, birthday, etc.).
  • Update core profile properties (identifiers such as email or phone number, location, etc.) on a regular basis.
  • Sync segments from an external system to Klaviyo for targeting in campaigns or flows. Learn more about our robust segmentation system.
  • Add or remove secondary email addresses on profiles with multi-email profiles enabled.

🚧

This endpoint should not be used for updating a small number of profiles. In those cases, we recommend using our synchronous profile APIs for more efficient processing.

Common use cases

Submit an import job

The example below is an example request payload to the Bulk Import Profiles endpoint. Note that the profile object that can be passed is consistent with the one used by the Create or Update Client Profile endpoint.

{
  "data": {
    "type": "profile-bulk-import-job",
    "attributes": {
      "profiles": {
        "data": [
            {
              "type": "profile",
              "attributes": {
                  "email": "[email protected]",
                  "properties": {
                      "preferences": ["comedy", "drama"]
                  }
              }
          },
          {
              "type": "profile",
              "attributes": {
                  "email": "[email protected]",
                  "properties": {
                      "preferences": ["dramedy", "action"]
                  }
              }
          }
          ...
        ]
      }
    }
  }
}

Sync list(s) to Klaviyo

You may be syncing lists to Klaviyo with our legacy v1/v2 endpoint Add Members to a List. To reference existing profiles (or create new ones in Klaviyo) and add them to a list, call Bulk Import Profiles with a request body like the one below:

{
    "data": {
        "type": "profile-bulk-import-job",
        "attributes": {
            "profiles": {
                "data": [
                    {
                        "type": "profile",
                        "attributes": {
                            "email": "[email protected]"
                        }
                    },
                    {
                        "type": "profile",
                        "attributes": {
                            "email": "[email protected]"
                        }
                    }
                ]
            }
        },
        "relationships": {
            "lists": {
                "data": [
                    {
                        "type": "list",
                        "id": "INSERT_LIST_ID"
                    }
                ]
            }
        }
    }
}

As in the Submit an import job example above, you can include additional fields on these profiles, but a minimum of 1 identifier (email, phone_number, etc.) is required.

Manage secondary emails (multi-email profiles)

If your account has multi-email profiles enabled, you can use the Bulk Import Profiles API to add or remove secondary email addresses on profiles. This is done using the meta.patch_identifiers object on each profile in the request payload.

📘 What are multi-email profiles?

Multi-email profiles allow a single Klaviyo profile to store up to 5 email addresses — one primary and up to four secondary. This helps reduce duplicate profiles and provides a more complete view of each customer. Learn more in our Multi-Email Profiles guide.

Append secondary emails

To add secondary emails to existing profiles, include a meta.patch_identifiers object with append.email set to a list of email addresses:

{
  "data": {
    "type": "profile-bulk-import-job",
    "attributes": {
      "profiles": {
        "data": [
          {
            "type": "profile",
            "attributes": {
              "email": "[email protected]"
            },
            "meta": {
              "patch_identifiers": {
                "append": {
                  "email": [
                    "[email protected]",
                    "[email protected]"
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
}

In this example, [email protected] and [email protected] will be added as secondary emails on the profile identified by [email protected].

Remove secondary emails

To remove secondary emails from a profile, use the unappend.email field:

{
  "data": {
    "type": "profile-bulk-import-job",
    "attributes": {
      "profiles": {
        "data": [
          {
            "type": "profile",
            "attributes": {
              "email": "[email protected]"
            },
            "meta": {
              "patch_identifiers": {
                "unappend": {
                  "email": [
                    "[email protected]"
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
}

Append and remove in a single request

You can combine append and unappend in the same patch_identifiers object:

{
  "data": {
    "type": "profile-bulk-import-job",
    "attributes": {
      "profiles": {
        "data": [
          {
            "type": "profile",
            "attributes": {
              "email": "[email protected]"
            },
            "meta": {
              "patch_identifiers": {
                "append": {
                  "email": ["[email protected]"]
                },
                "unappend": {
                  "email": ["[email protected]"]
                }
              }
            }
          }
        ]
      }
    }
  }
}

Swap primary and secondary emails

To swap a profile's primary and secondary email, send a payload where the email attribute is set to an existing secondary email you want to promote, and use meta.patch_identifiers.append.email to demote the current primary to a secondary:

{
  "data": {
    "type": "profile-bulk-import-job",
    "attributes": {
      "profiles": {
        "data": [
          {
            "type": "profile",
            "attributes": {
              "email": "[email protected]"
            },
            "meta": {
              "patch_identifiers": {
                "append": {
                  "email": ["[email protected]"]
                }
              }
            }
          }
        ]
      }
    }
  }
}

All four conditions must be met for the swap to trigger:

  1. The profile has a primary email.
  2. The email attribute in the payload matches one of the profile's existing secondary emails.
  3. patch_identifiers.append.email contains only the profile's current primary email (exactly one email).
  4. patch_identifiers.unappend.email is empty or not provided.

Multi-email rules and behavior

  • Email limit: Each profile supports a maximum of 5 email addresses (1 primary + up to 4 secondary). If a profile would exceed this limit, the entire profile update is rejected with a SECONDARY_EMAIL_LIMIT_EXCEEDED error.
  • Conflict resolution: If an email appears in both append and unappend for the same profile, the remove wins — the email will not be added.
  • Deduplication: Duplicate emails within the append or unappend lists are silently deduplicated.
  • Normalization: All emails are trimmed of whitespace and lowercased before processing.
  • Row atomicity: Each profile in the batch is processed independently. If a validation error occurs for a profile's patch_identifiers, the entire profile update is skipped.
  • Existing emails: If an email in append already exists on the profile (as primary or secondary), the append for that email is ignored — no error is raised.
  • Profile resolution: The profile must be resolvable by at least one identifier (e.g., email, phone_number, or external_id). If no matching profile is found and the request includes patch_identifiers, a new profile will be created with the primary email and secondary emails from the append list.

🚧 patch_identifiers only supports email

Currently, patch_identifiers only supports the email identifier type. Passing other identifier types (e.g., phone_number) will result in a validation error.

Retrieve import jobs

Call Get Bulk Import Profiles Job to retrieve all jobs for bulk import profiles. You can use filtering on this endpoint to list all jobs that haven’t been processed yet:

GET /api/profile-bulk-import-jobs/?filter=any(status,["queued","processing"])

Retrieve import status

Retrieve a single bulk import profiles job by calling Get Bulk Import Profiles Job with a given job ID. You can use filtering to return only the status of a specific bulk import job:

GET /api/profile-bulk-import-jobs/{job_id}/?fields[profile-bulk-import-job]=status

Retrieve import errors

To retrieve any errors that occurred during a job’s processing, call the Get Errors for Bulk Import Profiles Job endpoint (see Job processing errors):

GET /api/profile-bulk-import-jobs/:id/import-errors/

Retrieve successfully imported profiles

Call the Get Profiles for Bulk Import Profiles Job endpoint to retrieve successfully imported profiles:

GET /api/profile-bulk-import-jobs/:id/profiles

🚧

Note that the Get Profiles for Bulk Import Profiles Job endpoint returns the current state of the profiles, not the state at the time that the profiles were imported.

Retrieve related list

Get the list associated with the bulk import profiles job with a given job ID via Get List for Bulk Import Profiles Job:

GET /api/profile-bulk-import-jobs/:id/lists

Limitations

Payload limits and job expiration

We enforce the following payload limits:

  1. Maximum total payload size of 5 MB.
  2. Maximum of 10,000 profiles per job.
  3. Maximum individual profile payload size of 100 KB. Note that if this payload size is exceeded, the profile will be dropped from the processing job.

Note that jobs expire after 7 days. If jobs are requested more than 7 days after creation, the request will result in a 404 error. If limit 1 or 2 is exceeded, we will return a 400 error. See Troubleshooting below for more details on errors.

Validation

Some validation happens synchronously, and some asynchronously. For synchronous validation (e.g., email and phone formatting), at most 1 validation error is shown for each profile.

🚧

Note that bulk import profile jobs are not created in the event that there are synchronous errors (i.e., a 400 response). For example, if a batch of 100 profiles contains invalid emails, no bulk import profile job is submitted, and 0 profiles are imported.

Ordering and duplicates

Processing order is not guaranteed. If there are duplicates within a job or across jobs, there is no guarantee that profiles earlier in the array (or in an earlier job) will be processed first. If ordering is important to your application, you can leverage our synchronous Create and Update Profile APIs to guarantee the order, or wait until a batch is completed.

Note that if there are duplicates in a job, that profile will be listed multiple times in the resulting successful profile list (/api/profile-bulk-import-jobs/1/profiles/).

Consent

The Bulk Import Profiles Job endpoint will not update the consent status for profiles. However, you can create/update profiles via this endpoint, retrieve the related profile IDs upserted by the job, and then update those profiles' consent status using the Subscribe Profiles endpoint. Learn more about collecting consent and best practices.

Multi-email profiles

Multi-email profile operations via patch_identifiers are only available for accounts with multi-email profiles enabled. If your account does not have this feature enabled and you include patch_identifiers in a request, the field will be ignored.

Troubleshooting

Below are error status codes you may encounter with Bulk Import Profiles Jobs, including the corresponding reasons for these errors to help you resolve them.

Status codeReasons
400Profile(s) are missing 1 or more required fields.
Profile(s) have an invalid email address or phone number.
The provided list is invalid, e.g., the list ID does not exist in the account.
A patch_identifiers field contains an invalid email format or an unsupported identifier type.
401Missing auth information. See details on key authentication.
403API key is missing required API scopes. This endpoint requires both profiles:write and lists:write.
413Request payload size is too large (> 5 MB), see Limitations above.
429Rate limit exceeded.

Job processing errors

The following errors may occur during job processing:

  • Missing 1 or more identifiers. We need at least one identifier (e.g., email) to process the profile.
  • 1 or more invalid emails or phone numbers are provided. Emails must be in a valid format and phone numbers must be an allowable phone number (i.e., country code exists) in E.164 format.
  • The profile update would result in a duplicate profile, so the upsert is dropped. This will be included in the import errors.
  • The individual profile payload is too large (> 100 KB). Large custom properties are dropped from the profile update until the profile meets the size requirements.
  • INVALID_EMAIL — An email address in patch_identifiers.append or patch_identifiers.unappend is not a valid email format.
  • SECONDARY_EMAIL_LIMIT_EXCEEDED — The operation would result in more than 5 emails on a single profile.

🚧

After receiving a 200 response, all or some profiles may be created (e.g., some duplicate profiles may be dropped in the process). Use the Get Errors for Bulk Import Profiles Job endpoint to check for specific import errors.

Additional resources