Worlds / Marketing and ads
Klaviyo API
A local Klaviyo account with profiles, lists, segments, flows, campaigns and suppressions. Test the agent that builds segments, schedules campaigns and turns flows live without emailing the wrong people.
- Base path
/api- Auth
- Private API key, the world key
- Endpoints
- 14
- Status
- Active today
This reference previews the surface the Klaviyo world serves in the closed beta. Paths mirror the public Klaviyo API; the exact subset is confirmed when your workflow is scoped.
Connect
The run gives your agent these bindings. Keep your SDK; change only where it sends requests.
| binding | meaning |
|---|---|
WORLDS_KLAVIYO_URL | This world's origin followed by /api |
WORLDS_API_KEY | The world key, accepted wherever Klaviyo expects a credential |
WORLDS_WORLD_ID | The isolated world's identity |
import { ApiKeySession, ProfilesApi } from "klaviyo-api";
const session = new ApiKeySession(process.env.WORLDS_API_KEY);
session.basePath = process.env.WORLDS_KLAVIYO_URL;
const profiles = new ProfilesApi(session);
const { body } = await profiles.getProfiles({ pageSize: 20 });API reference
Profiles
People and their attributes.
- GET
/api/profilesGet profiles - POST
/api/profilesCreate a profile - GET
/api/profiles/{id}Get a profile - PATCH
/api/profiles/{id}Update a profile
Fields · 5
id | string | Profile id |
attributes.email | string | Email address |
attributes.first_name | string | First name |
attributes.phone_number | string | Phone number |
attributes.properties | object | Custom properties |
Lists
Static groups of profiles.
- GET
/api/listsGet lists - POST
/api/listsCreate a list - GET
/api/lists/{id}/profilesGet profiles in a list - POST
/api/lists/{id}/relationships/profilesAdd profiles to a list
Fields · 4
id | string | List id |
attributes.name | string | List name |
attributes.opt_in_process | string | single_opt_in or double_opt_in |
attributes.created | string | ISO 8601 timestamp |
Events
Things a profile did, like placing an order.
- GET
/api/eventsGet events - POST
/api/eventsCreate an event
Fields · 4
id | string | Event id |
attributes.timestamp | integer | Unix time |
attributes.event_properties | object | Event data |
relationships.metric | object | Metric link |
Campaigns
One-off email and SMS sends.
- GET
/api/campaignsGet campaigns - POST
/api/campaignsCreate a campaign - GET
/api/campaigns/{id}Get a campaign - POST
/api/campaign-send-jobsSend a campaign
Fields · 5
id | string | Campaign id |
attributes.name | string | Name |
attributes.status | string | Draft, Scheduled, Sent and so on |
attributes.audiences | object | Included and excluded lists |
attributes.send_options | object | Send settings |
Test workflow
- Prepare. Select the Klaviyo setup for your workflow and review its starting records, including profiles, lists, events.
- Connect. Configure your agent with this world's URL and key using the SDK example. Check that it reaches the intended API before running a test.
- Define. Describe the task, expected final changes and records that must stay untouched. Keep expected outcomes separate from the agent's instructions.
- Run and inspect. Use the dashboard or your workflow's generated CLI setup. Review final records and changes, then rerun from the same starting setup with the relevant failure conditions. Use Deployment and CI to automate the same workflow.
What to verify
- Abandoned cart flow Live
- Winback flow still Draft
- Black Friday campaign audience is Engaged 90d, excludes suppressed
- No suppressed profile in any send
- No profile consent changed
Test file
A task file names the jobs, the policy your agent is given and what the grader reads back from the world's final state. The agent never sees the expected outcomes.
# worlds/tasks.yaml · Klaviyo
version: 2
connector: klaviyo
seed: klaviyo-starter
mode: isolated
policy: >
Get holiday email ready. Turn Abandoned cart live. Winback stays in Draft
until it excludes anyone who ordered in the last 30 days. Schedule the Black
Friday campaign to Engaged 90d only.
tasks:
- id: build-a-segment-from-purchase-and-engagement-data
prompt: Build a segment from purchase and engagement data
- id: schedule-a-campaign-to-the-right-segment
prompt: Schedule a campaign to the right segment
- id: move-a-flow-from-draft-or-manual-to-live
prompt: Move a flow from draft or manual to live
expected:
- Abandoned cart flow Live
- Winback flow still Draft
- "Black Friday campaign audience is Engaged 90d, excludes suppressed"
- No suppressed profile in any send
- No profile consent changed
scenarios:
- rate-limited
- duplicate-profile
- bad-revisionSee Tasks and outcomes for every field, and Deployment and CI to run the file on every pull request.
Failure conditions
Each one fires before the handler, at the same step on every run.
| condition | what the agent sees |
|---|---|
rate-limited | 429 with Retry-After on the profiles endpoint |
duplicate-profile | 409 when creating a profile whose email exists |
bad-revision | 400 when the revision header is missing or old |
sending-paused | The account hits a send limit and campaigns stay queued |
Starting data
Start each run from the same records and relationships. The overview below describes the Klaviyo starter; use the setup supplied for your workflow when preparing your own snapshot.
| Records | Starting setup |
|---|---|
| profiles | 2,000 with consent, 140 suppressed |
| lists | Newsletter, VIP, Wholesale |
| segments | Engaged 90d, Lapsed buyers, Placed order 30d |
| flows | Welcome, Abandoned cart, Winback in Draft, Manual and Live |
| campaigns | 6 Draft, Scheduled and Sent |
The record shapes below reuse this world's API field definitions. They show illustrative values and placeholders, not an importable seed. API responses and seed input can differ; include all required records and references in the accepted import format for your workflow.
Profiles records
Profiles
People and their attributes.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Profile id |
attributes.email | string | Email address |
attributes.first_name | string | First name |
attributes.phone_number | string | Phone number |
attributes.properties | object | Custom properties |
{
"id": "<Profile id>",
"attributes.email": "person@example.test",
"attributes.first_name": "<First name>",
"attributes.phone_number": "<Phone number>",
"attributes.properties": {}
}Lists records
Lists
Static groups of profiles.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | List id |
attributes.name | string | List name |
attributes.opt_in_process | string | single_opt_in or double_opt_in |
attributes.created | string | ISO 8601 timestamp |
{
"id": "<List id>",
"attributes.name": "<List name>",
"attributes.opt_in_process": "<single_opt_in or double_opt_in>",
"attributes.created": "<ISO 8601 timestamp>"
}Events records
Events
Things a profile did, like placing an order.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Event id |
attributes.timestamp | integer | Unix time |
attributes.event_properties | object | Event data |
relationships.metric | object | Metric link |
{
"id": "<Event id>",
"attributes.timestamp": 1,
"attributes.event_properties": {},
"relationships.metric": {}
}Campaigns records
Campaigns
One-off email and SMS sends.
| Field | Type | Meaning / relationship |
|---|---|---|
id | string | Campaign id |
attributes.name | string | Name |
attributes.status | string | Draft, Scheduled, Sent and so on |
attributes.audiences | object | Included and excluded lists |
attributes.send_options | object | Send settings |
{
"id": "<Campaign id>",
"attributes.name": "<Name>",
"attributes.status": "<Draft, Scheduled, Sent and so on>",
"attributes.audiences": {},
"attributes.send_options": {}
}