Klaviyo
Set up Klaviyo → JustAI data ingestion so JustAI can measure email performance (sends, opens, clicks) and optimize content over time. This is one-time setup — all templates will share this configuration.
What Ingress Includes
Section titled “What Ingress Includes”JustAI ingests Klaviyo engagement events via an SFTP export → AWS Glue pipeline. This provides the core metrics needed for analysis and variant ranking.
Before You Start
Section titled “Before You Start”- Confirm which Klaviyo account you’re connecting.
- Identify your JustAI org slug (usually your company name in all lower case — ask us if unsure).
- Make sure you have permissions to create API keys and edit Flows in Klaviyo.
1) Create a Klaviyo API Key
Section titled “1) Create a Klaviyo API Key”In Klaviyo:
- Go to Settings → API Keys → Create Private API Key.
- Name it
JustAI. - Grant the following scopes:
- Flows: Read
- Campaigns: Read
- Metrics: Read
- Profiles: Write (for writing generated content back to profiles)
- Copy the private key.
2) Save the Klaviyo Key in JustAI
Section titled “2) Save the Klaviyo Key in JustAI”In the JustAI console:
- Open Org Integration Settings.
- Select Klaviyo as the ESP integration.
- Paste the Klaviyo private API key and save.
3) Create a JustAI API Key
Section titled “3) Create a JustAI API Key”Store the key securely — you’ll use it in the Klaviyo webhook step.
Template Setup (Webhook in Klaviyo Flow)
Section titled “Template Setup (Webhook in Klaviyo Flow)”Klaviyo integration uses a Flow with a Webhook step that calls JustAI to generate content, writes it to the recipient’s Klaviyo profile, then renders it in a downstream email step.
Flow Structure
Section titled “Flow Structure”In Klaviyo, create or edit a Flow with this structure:
- Trigger — e.g., “Added to List”, metric trigger, or segment entry.
- Webhook step — calls JustAI to generate content (configured below).
- Time Delay — 2–5 minutes (gives JustAI time to write profile properties).
- Email step — renders the generated content from profile properties.
Configure the Webhook
Section titled “Configure the Webhook”In the Webhook step:
- Destination URL:
https://worker.justwords.ai/api/generate/<org_slug> - Headers:
Content-Type: application/jsonX-Api-Key: <JUSTAI_API_KEY>
- JSON Body:
{ "template_id": "<template_id>", "user_id": "{{ person.KlaviyoID }}", "tracking_id": "{{ person.KlaviyoID }}.<flow_id>.<treatment_action_id>"}Configure the Email Template
Section titled “Configure the Email Template”In the Klaviyo email step, reference the profile properties written by JustAI:
| Field | Klaviyo Liquid |
|---|---|
| Subject Line | {{ person|lookup:'jai_subject'|default:"Your weekly update" }} |
| Preview Text | {{ person|lookup:'jai_preheader'|default:"" }} |
| Body (HTML) | {{ person|lookup:'jai_body'|safe }} |
The |default: filters provide fallback content if the profile property hasn’t been written yet. The |safe filter renders raw HTML.
Configure Template in JustAI
Section titled “Configure Template in JustAI”In the JustAI console, open the template’s Integration Settings:
- Select the Flow from the dropdown (synced from your Klaviyo account).
- Select the Treatment Message — the email action that renders JustAI-generated content.
- If using an external A/B split, select the Control Message as well.
- Save changes.
Personalization
Section titled “Personalization”Pass additional user attributes to JustAI using the attrs field in the webhook body. JustAI uses these for variant ranking and content selection.
{ "template_id": "<template_id>", "user_id": "{{ person.KlaviyoID }}", "tracking_id": "{{ person.KlaviyoID }}.<flow_id>.<treatment_action_id>", "attrs": { "persona": "{{ person|lookup:'persona' }}", "plan": "{{ person|lookup:'plan_type' }}" }}For personalization fields that should be inserted into content without affecting variant selection, use fields:
{ "fields": { "first_name": "{{ person.first_name }}" }}You can combine both in the same request:
{ "attrs": { "persona": "{{ person|lookup:'persona' }}" }, "fields": { "first_name": "{{ person.first_name }}" }}Troubleshooting
Section titled “Troubleshooting”- Webhook not firing: Confirm the Flow is live (not in draft) and the webhook step is active.
- Profile properties empty: Check that the Klaviyo API key has Profiles: Write scope. Also verify the time delay between the webhook and email steps is sufficient (2–5 minutes).
- Wrong profile ID: Make sure you’re using
{{ person.KlaviyoID }}, not{{ person.id }}. - Flows/campaigns not showing in JustAI: Click “Refresh Klaviyo Data” in Integration Settings. If they still don’t appear, verify the API key has Flows: Read and Campaigns: Read scopes.
JustAI can share data about which content each user received for Klaviyo-integrated campaigns. The standard approach is a daily data export to a shared S3 bucket.
Example Data Payload
Section titled “Example Data Payload”Each record reflects one JustAI API call with a user ID and tracking ID that maps back to a Klaviyo flow execution.
{ "event_timestamp": "<unix_timestamp>", "user_id": "<string>", "tracking_id": "<string>", "copy_id": "<uuid_string>", "template_id": "<string>", "vars": { "subject": "<string>", "preheader": "<string>", "body": "<string>" }, "attrs": { "persona": "<string>" }}Implementation
Section titled “Implementation”- JustAI provisions an ARN role with read/write access to the shared bucket.
- Client creates the bucket (or path) and grants access to the role.
- JustAI runs a backfill and sets up daily exports.
- Client transfers data from S3 into their data warehouse.
Implementation Details
Section titled “Implementation Details”- Exported data is in Parquet format, written to a partitioned path (
.../YYYY/MM/DD/HH). - Backfills overwrite existing data for the time range.
- Retention is managed via bucket lifecycle policies.
Please reach out to our team to set up data egress for your Klaviyo integration.