How to Approve a Klaviyo Promo Send-List Before Adding Profiles

Build a scheduled Spojit workflow that assembles a candidate promo audience from Klaviyo profiles, pauses for a marketer to approve the count and segment, then adds the approved profiles to your campaign list.

What This Integration Does

Promotional sends are easy to get wrong: a stale filter or a typo in a segment definition can push thousands of the wrong people onto a campaign list, and once profiles are added the email goes out. This workflow puts a human checkpoint between "here are the profiles we matched" and "add them to the send-list". A marketer sees the candidate count and a sample before anyone is added, so a bad audience never reaches the campaign.

The workflow runs on a Schedule trigger (for example, every Monday morning before a weekly promo). On each run it queries Klaviyo for profiles that match your promo criteria, summarizes the candidate audience, and then halts at a Human node. Nothing is written to Klaviyo until a designated approver approves. When approved, the workflow calls add-profiles-to-list to add the profiles to your target list. If the approver rejects or the request times out, the run halts and no profiles are added, so re-runs are safe: the next scheduled run rebuilds the candidate set from scratch.

Prerequisites

  • A Klaviyo connection added in Spojit under Connections, with an API key that can read profiles and modify lists.
  • The Klaviyo listId of the campaign send-list you want to populate. You can find it with the list-lists tool, or copy it from the Lists page in Klaviyo.
  • At least one approver set up as a Spojit user, role, or team so you can fill an approval slot on the Human node.
  • A clear definition of your promo audience expressed as a Klaviyo JSON:API filter string (for example, recently active subscribers in a region).

Step 1: Add a Schedule trigger

Create a new workflow and set its Trigger type to Schedule. Add a 5-field Unix cron expression and an IANA timezone so the run lands at the right local time. For a Monday 9am Sydney build, use:

0 9 * * 1
Australia/Sydney

The trigger output is {{ scheduledAt }}, which you can reference later in the approval message. A single trigger can hold multiple schedules if you run promos on more than one cadence.

Step 2: Query candidate profiles from Klaviyo

Add a Connector node in Direct mode, choose the Klaviyo connection, and select the list-profiles tool. Set the filter field to a Klaviyo JSON:API filter that describes your promo audience, and use pageSize to cap how many profiles you pull per page. For example, to match profiles created since a fixed date:

{
  "filter": "greater-than(created,2026-01-01T00:00:00Z)",
  "sort": "-created",
  "pageSize": 100
}

Map the result to an output variable such as candidates. Each returned profile carries an id, which is what add-profiles-to-list needs later.

Step 3: Shape the candidate list and count it

Add a Transform node to pull just the profile IDs out of the Klaviyo response into a clean array. Reference the candidate profiles from the previous step and produce an array of IDs, for example by mapping each profile to its id. Save this as profileIds.

Then add a Connector node using the built-in array connector with the length tool, pointed at {{ profileIds }}, and save the result as candidateCount. You will surface this number in the approval request so the marketer can sanity-check the audience size before anyone is added.

Step 4: Pause for marketer approval

Add a Human node so the workflow stops until a marketer reviews the audience. Configure it as follows:

  • Label: Approve promo send-list
  • Message: include the count and segment so the approver has context, for example This run matched {{ candidateCount }} profiles for the weekly promo (scheduled {{ scheduledAt }}). Approve to add them to the campaign list.
  • Notification title/body: support {{ variables }}, so reuse {{ candidateCount }} here too.
  • Urgency: set to Normal or High for time-sensitive sends.
  • Email approvers: turn on if you want the first 10 approvers emailed directly.
  • Approval slots: add one slot with an approver atom (a specific User, a Role, or a Team). Every slot must be satisfied for the run to continue.

Approvers act in the Approvals inbox at /approvals. On approval the node outputs { approved: true, approvalId, outcome: "APPROVED" } and the run continues. A rejection or a timeout halts the run, and because nothing has been written to Klaviyo yet, no profiles are added.

Step 5: Add approved profiles to the Klaviyo list

After the Human node, add a Connector node in Direct mode on the Klaviyo connection and select the add-profiles-to-list tool. Map its two inputs:

{
  "listId": "YOUR_CAMPAIGN_LIST_ID",
  "profileIds": {{ profileIds }}
}

Because this node sits downstream of the approval, it only runs when the marketer approves. The profiles are now on your campaign send-list and ready for the Klaviyo campaign or flow that targets that list.

Step 6: Confirm the outcome with a Send Email node

Add a Send Email node so the marketing team gets a record of what shipped. It sends from Spojit's built-in mail service, no connection required. Set Recipients (each external address must be on your org allowlist under Settings → General → Email recipients), a templated Subject, and a Body referencing the run, for example:

Subject: Promo send-list updated ({{ candidateCount }} profiles)
Body: Added {{ candidateCount }} approved profiles to the campaign list on {{ scheduledAt }}.

To send from your own domain instead of the built-in service, swap in the Resend or SMTP connector and its send-email tool.

Tips

  • Keep pageSize reasonable (for example 100) and add a Loop with pageCursor if your audience is large, so you collect every page before the count is shown to the approver.
  • Include a short sample of matched emails in the Human node message, not just the count, so the marketer can spot an obviously wrong segment at a glance.
  • Ask Miraxa, the intelligent layer across your automation, to scaffold the canvas with a prompt like "Build a scheduled workflow that lists Klaviyo profiles, pauses at a Human node, then adds the profiles to a list", then fine-tune fields in the properties panel.
  • Set a Timeout (minutes) on the Human node so a forgotten approval does not leave the run pending forever. A timeout is treated as a rejection and halts the run safely.

Common Pitfalls

  • The profileIds input to add-profiles-to-list must be an array of profile id values, not the full profile objects. Use the Transform step in Step 3 to extract just the IDs.
  • Rejection does not branch: a rejected or timed-out approval halts the whole run. There is no "on reject do X" path, so put any cleanup or notify-on-reject logic in a separate workflow if you need it.
  • Cron is in the timezone you set, not the viewer's local time. Double-check the IANA zone (for example Australia/Sydney) so a Monday-morning build does not fire on Sunday night.
  • Klaviyo filter syntax is strict JSON:API. A malformed filter string returns an error or an empty set, which would surface as a zero count at the approval step. Verify your filter against a known audience first.

Testing

Before turning the schedule loose, validate on a small scope. Point the filter at a narrow segment that matches only a handful of test profiles, and add the profiles to a throwaway test list rather than your live campaign list. Trigger a run, approve it in the Approvals inbox, and confirm the test profiles appear on the test list in Klaviyo. Then reject a second run and confirm no profiles are added. Once both paths behave, point listId at the real campaign list and enable the production schedule.

Learn More

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