How to Export Klaviyo Profiles and Events to JSON

Export Klaviyo profiles, list members or events (such as Placed Order or Opened Email) to a JSON file on a schedule, ready for a data warehouse, a backup or another tool.

What This Integration Does

Klaviyo exports lists and segments to CSV from its UI, but events, custom properties and anything you want on a schedule need the API. This Spojit workflow uses the Klaviyo API to read profiles (all of them, or those updated recently) or events of a given metric, follows Klaviyo's pagination to the end, flattens Klaviyo's JSON:API format into plain objects, and saves the result as a JSON file in your File Store or on an SFTP server.

Runs are incremental when you filter on updated for profiles or datetime for events, so a daily export contains only that day's changes. Each run writes a new dated file and nothing in Klaviyo is changed, so re-running is always safe.

Prerequisites

  • A Klaviyo connection with a private API key that has read access to Profiles, Lists and Events.
  • For event exports, the metric ID of the event (for example Placed Order). List metrics once with raw-api-request, GET /metrics.
  • Optional: an FTP / SFTP connection for delivery.

Step 1: Schedule Trigger

Add a Trigger node with type Schedule, cron 0 3 * * *. Build the window start with a Date & Time subtract step that takes one day plus an hour of overlap off the trigger time. Name it since; the ISO 8601 timestamp is in {{ since.iso }}.

Step 2: Read Profiles or Events

Add a Connector node on Klaviyo in Direct Mode.

  • Profiles: list-profiles with filter greater-than(updated,{{ since.iso }}), sort updated and pageSize 100.
  • Events: list-events with filter and(equals(metric_id,"YOUR_METRIC_ID"),greater-than(datetime,{{ since.iso }})) and sort datetime.
  • One list's members: raw-api-request with GET /lists/YOUR_LIST_ID/profiles.

Name the output page. Klaviyo returns up to 100 records and a links.next URL when there are more.

Step 3: Follow the Pagination

Wrap the call in a Loop in While mode that continues while links.next is present, passing the cursor from it into pageCursor. Collect each page's data array. A Max iterations of 500 (50,000 records) protects against runaway loops; raise it for very large accounts.

Step 4: Flatten Klaviyo's Format

Klaviyo wraps every record as { "type", "id", "attributes": { ... } }. Add a Transform with Iterate over set to the collected records to produce plain objects:

{
  "id": "{{ item.id }}",
  "email": "{{ item.attributes.email }}",
  "phone_number": "{{ item.attributes.phone_number }}",
  "first_name": "{{ item.attributes.first_name }}",
  "last_name": "{{ item.attributes.last_name }}",
  "created": "{{ item.attributes.created }}",
  "updated": "{{ item.attributes.updated }}",
  "properties": {{ item.attributes.properties }}
}

For events, map datetime, event_properties (which hold the order value, items and so on for Placed Order) and the related profile ID from relationships.profile.data.id.

Step 5: Save the JSON File

Add a Connector node on JSON Tools with stringify, then a File Store node with Save a file: Name klaviyo-profiles-{{ run_date.result }}.json, Content type application/json, If the name is taken Keep both. To deliver the file, add an FTP / SFTP step with upload-file.

Tips

  • Full backup once, then increments: run once manually without the date filter for a full backup, then let the schedule export only changes.
  • Consent fields: email and SMS consent live under subscriptions, which Klaviyo only returns when requested. Use raw-api-request with additional-fields[profile]=subscriptions if your export needs them.
  • Load into a warehouse: the same flattened records can go straight into MySQL or MongoDB instead of a file; see the Snowflake tutorial in this help center for loading into Snowflake.
  • Events are big: high-volume metrics such as Opened Email produce millions of rows. Export the metrics you analyse (Placed Order, Started Checkout) rather than everything.

Common Pitfalls

  • Filter syntax: Klaviyo filters use its own syntax, such as greater-than(updated,2026-10-01T00:00:00Z), with no quotes around dates. A malformed filter returns a 400 error with a hint.
  • Rate limits: Klaviyo limits requests per second per endpoint. Large exports should run off-peak; Spojit's step retries help with occasional 429 responses.
  • Personal data: profile exports are personal data. Keep only fields you need and restrict access to the File Store folder or SFTP path.
  • Time zones: Klaviyo timestamps are UTC with an offset. Build since in UTC too, or the window shifts by your offset.

Testing

Run the workflow manually with a one-hour window and check the file: the record count should match a Klaviyo segment filtered the same way, and every record should have an id and an email or phone number. Then turn on the schedule.

Learn More

Ready to build this?

Start on the free plan: 500 AI credits a month, no card needed.

Start free

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.