# How to integrate Klaviyo MCP with OpenAI Agents SDK

```json
{
  "title": "How to integrate Klaviyo MCP with OpenAI Agents SDK",
  "toolkit": "Klaviyo",
  "toolkit_slug": "klaviyo",
  "framework": "OpenAI Agents SDK",
  "framework_slug": "open-ai-agents-sdk",
  "url": "https://composio.dev/toolkits/klaviyo/framework/open-ai-agents-sdk",
  "markdown_url": "https://composio.dev/toolkits/klaviyo/framework/open-ai-agents-sdk.md",
  "updated_at": "2026-05-06T08:17:41.701Z"
}
```

## Introduction

This guide walks you through connecting Klaviyo to the OpenAI Agents SDK using the Composio tool router. By the end, you'll have a working Klaviyo agent that can add new subscribers to main email list, clone last week's campaign for reuse, estimate recipients for upcoming product launch through natural language commands.
This guide will help you understand how to give your OpenAI Agents SDK agent real control over a Klaviyo account through Composio's Klaviyo MCP server.
Before we dive in, let's take a quick look at the key ideas and tools involved.

## Also integrate Klaviyo with

- [ChatGPT](https://composio.dev/toolkits/klaviyo/framework/chatgpt)
- [Claude Agent SDK](https://composio.dev/toolkits/klaviyo/framework/claude-agents-sdk)
- [Claude Code](https://composio.dev/toolkits/klaviyo/framework/claude-code)
- [Claude Cowork](https://composio.dev/toolkits/klaviyo/framework/claude-cowork)
- [Codex](https://composio.dev/toolkits/klaviyo/framework/codex)
- [Cursor](https://composio.dev/toolkits/klaviyo/framework/cursor)
- [VS Code](https://composio.dev/toolkits/klaviyo/framework/vscode)
- [OpenCode](https://composio.dev/toolkits/klaviyo/framework/opencode)
- [OpenClaw](https://composio.dev/toolkits/klaviyo/framework/openclaw)
- [Hermes](https://composio.dev/toolkits/klaviyo/framework/hermes-agent)
- [CLI](https://composio.dev/toolkits/klaviyo/framework/cli)
- [Google ADK](https://composio.dev/toolkits/klaviyo/framework/google-adk)
- [LangChain](https://composio.dev/toolkits/klaviyo/framework/langchain)
- [Vercel AI SDK](https://composio.dev/toolkits/klaviyo/framework/ai-sdk)
- [Mastra AI](https://composio.dev/toolkits/klaviyo/framework/mastra-ai)
- [LlamaIndex](https://composio.dev/toolkits/klaviyo/framework/llama-index)
- [CrewAI](https://composio.dev/toolkits/klaviyo/framework/crew-ai)

## TL;DR

Here's what you'll learn:
- Get and set up your OpenAI and Composio API keys
- Install the necessary dependencies
- Initialize Composio and create a Tool Router session for Klaviyo
- Configure an AI agent that can use Klaviyo as a tool
- Run a live chat session where you can ask the agent to perform Klaviyo operations

## What is OpenAI Agents SDK?

The OpenAI Agents SDK is a lightweight framework for building AI agents that can use tools and maintain conversation state. It provides a simple interface for creating agents with hosted MCP tool support.
Key features include:
- Hosted MCP Tools: Connect to external services through hosted MCP endpoints
- SQLite Sessions: Persist conversation history across interactions
- Simple API: Clean interface with Agent, Runner, and tool configuration
- Streaming Support: Real-time response streaming for interactive applications

## What is the Klaviyo MCP server, and what's possible with it?

The Klaviyo MCP server is an implementation of the Model Context Protocol that connects your AI agent and assistants like Claude, Cursor, etc directly to your Klaviyo account. It provides structured and secure access to your marketing campaigns, contact lists, and automation features, so your agent can perform actions like creating campaigns, managing subscribers, sending messages, and analyzing engagement—all on your behalf.
- Automated campaign creation and sending: Instantly have your agent create new marketing campaigns, clone existing ones, and trigger campaign sends to targeted audiences.
- Subscriber and list management: Add or update profiles in specific Klaviyo lists, subscribe contacts to marketing lists, and ensure your audience is always up to date.
- Event and engagement tracking: Automatically record customer activities or bulk-create profile events to power segmentation and analytics.
- Catalog and back-in-stock automation: Let your agent create product catalog categories, manage restock alerts, and help drive timely customer notifications about inventory.
- Campaign recipient estimation and analytics: Start background jobs to estimate campaign reach and analyze how many recipients meet your targeting criteria before a send.

## Supported Tools

| Tool slug | Name | Description |
|---|---|---|
| `KLAVIYO_ADD_PROFILE_TO_LIST` | Add Profile to List | Add profiles to a klaviyo list by profile ids or email addresses. this action subscribes profiles to a marketing list, which is ideal for giving marketing consent. you can add up to 1000 profiles per call using either their klaviyo profile ids or email addresses. rate limits: 10/s burst, 150/m steady. required scopes: `lists:write` and `profiles:write`. preconditions: - either profile ids or emails must be provided (not both) - maximum 1000 profiles per call - email addresses must be valid format - the list must exist and be accessible |
| `KLAVIYO_ASSIGN_CAMPAIGN_MESSAGE_TEMPLATE` | Assign campaign message template | Creates a non-reusable version of the template and assigns it to the message.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_BULK_CREATE_CLIENT_EVENTS` | Bulk create client events | Use the client-side endpoint with a public api key to track profile activity. it accepts up to 1000 events/request with rates of 10/s burst and 150/m steady. for server-side, use the bulk create event endpoint. |
| `KLAVIYO_BULK_CREATE_EVENTS` | Bulk create events | This api endpoint creates or updates profiles by batching up to 1,000 events, with a 5mb payload limit. minimum required: a profile id and metric name. it has rate limits of 10 events per second burst and 150 events per minute. scope is `events:write`. |
| `KLAVIYO_CREATE_BACK_IN_STOCK_SUBSCRIPTION` | Create back in stock subscription | Use the server-side endpoint to subscribe to restock alerts, following the back in stock api guide. for client-side, use the post endpoint provided. rate limits: 350/s burst and 3500/m steady. required scopes: catalogs:write, profiles:write. |
| `KLAVIYO_CREATE_CAMPAIGN` | Create campaign | Creates a campaign given a set of parameters, then returns it.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_CREATE_CAMPAIGN_CLONE` | Create campaign clone | Clones an existing campaign, returning a new campaign based on the original with a new id and name.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_CREATE_CAMPAIGN_RECIPIENT_ESTIMATION_JOB` | Create Campaign Recipient Estimation Job | Start an asynchronous task to estimate the number of recipients for a campaign. this action creates a background job that calculates how many profiles would receive the campaign based on its current audience settings. use the job id returned to track progress with the 'get campaign recipient estimation job' action, and get the final count via 'get campaign recipient estimation' action. rate limits: 10/s burst, 150/m steady. required scope: `campaigns:write`. preconditions: - valid api key with campaigns:write scope - campaign id must exist and be accessible - campaign must have audience settings configured |
| `KLAVIYO_CREATE_CAMPAIGN_SEND_JOB` | Create campaign send job | Trigger a campaign to send asynchronously*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_CREATE_CATALOG_CATEGORY` | Create catalog category | Create a new catalog category.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_CREATE_CATALOG_CATEGORY_RELATIONSHIPS_ITEMS` | Create catalog category relationships items | Create a new item relationship for the given category id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_CREATE_CATALOG_ITEM` | Create catalog item | Create a new catalog item.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_CREATE_CATALOG_ITEM_RELATIONSHIPS_CATEGORIES` | Create catalog item relationships categories | Create a new catalog category relationship for the given item id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_CREATE_CATALOG_VARIANT` | Create catalog variant | Create a new variant for a related catalog item.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_CREATE_CLIENT_BACK_IN_STOCK_SUBSCRIPTION` | Create client back in stock subscription | Use the endpoint for client-side back in stock notifications with a public api key. for server-side, use post /api/back-in-stock-subscriptions. limits are 350 requests per second and 3500 per minute. requires 'catalogs:write' and 'profiles:write' scopes. |
| `KLAVIYO_CREATE_CLIENT_EVENT` | Create client event | Create client-side events to track profiles using a public api key, not for updating identifiers (server-side only). rate limits: 350/s, 3500/m. use `events:write` scope. |
| `KLAVIYO_CREATE_CLIENT_SUBSCRIPTION` | Create client subscription | Endpoint manages email/sms opt-ins using consent and requires public api key for client use. allows single-channel with details. rate limit: 100/s burst, 700/m steady, under 'subscriptions:write'. |
| `KLAVIYO_CREATE_COUPON` | Create coupon | Creates a new coupon.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `coupons:write` |
| `KLAVIYO_CREATE_COUPON_CODE` | Create coupon code | Synchronously creates a coupon code for the given coupon.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `coupon-codes:write` |
| `KLAVIYO_CREATE_EVENT` | Create event | Create or update a profile event with minimum identifiers and metric name. success means validation, not completion. burst limit: 350/s, steady: 3500/m. scope required: `events:write`. |
| `KLAVIYO_CREATE_LIST` | Create list | Create a new list.*rate limits*:burst: `10/s`steady: `150/m`daily: `100/d` **scopes:** `lists:write` |
| `KLAVIYO_CREATE_OR_UPDATE_CLIENT_PROFILE` | Create or update client profile | Update user profiles without tracking using a public client-side api; use a private server-side api for identifier changes. burst rate is 350 requests/sec and 3500 requests/min with 'profiles:write' access. |
| `KLAVIYO_CREATE_OR_UPDATE_CLIENT_PUSH_TOKEN` | Create or update client push token | This endpoint for mobile sdks (ios & android) creates/updates push tokens using a public api key. push notifications must be enabled. for migrating tokens use the server-side post endpoint. rate limits are 3/s burst, 150/m steady. |
| `KLAVIYO_CREATE_OR_UPDATE_PROFILE` | Create or Update Profile | Create or update a profile in klaviyo with the given attributes. this action allows you to create a new profile or update an existing one if it already exists (based on email or other identifiers). returns 201 for creation, 200 for update. empty fields are cleared with `null`; omitted fields remain unchanged. rate limits: 75/s burst, 700/m steady. required scope: `profiles:write`. preconditions: - at least one identifier (email, phone number, external id, or anonymous id) must be provided - email must be in valid format if provided - phone number must be in e.164 format if provided |
| `KLAVIYO_CREATE_OR_UPDATE_PUSH_TOKEN` | Create or update push token | Migrate or create push tokens with klaviyo's endpoint, utilizing their mobile sdks for ios & android. rate limits: 75/s burst, 700/m steady. requires profiles:write and push-tokens:write scopes. |
| `KLAVIYO_CREATE_PROFILE` | Create profile | Create a new profile.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `profiles:write` |
| `KLAVIYO_CREATE_SEGMENT` | Create segment | Create a segment.*rate limits*:burst: `1/s`steady: `15/m`daily: `100/d` **scopes:** `segments:write` |
| `KLAVIYO_CREATE_TAG` | Create tag | Summary: instructions on creating a tag within an account's designated tag group with a maximum of 500 tags, with optional tag group specification. rate limits are 3/s burst and 60/min steady. tag: #tagcreationlimitandrate |
| `KLAVIYO_CREATE_TAG_GROUP` | Create tag group | Create tag groups up to 50 per account, defaulting to non-exclusive unless specified. related resources can have multiple non-exclusive tags but only one if exclusive. rate limits: 3/s burst, 60/m steady. scopes needed: tags:read, tags:write. |
| `KLAVIYO_CREATE_TAG_RELATIONSHIPS_CAMPAIGNS` | Create tag relationships campaigns | Summary: link a tag to campaigns, ensuring a limit of 100 tags per campaign. campaign ids should be sent via request body. rate limit: 3/s, 60/m. required scopes: campaigns:write, tags:write. tag: #campaigntagginglimits |
| `KLAVIYO_CREATE_TAG_RELATIONSHIPS_FLOWS` | Create tag relationships flows | Assign tags to flows using their ids in the request body, ensuring a flow is not linked to over 100 tags. rate limits are 3/s burst and 60/m steady. required scopes: `flows:write` and `tags:write`. tag: flow-tag association limits |
| `KLAVIYO_CREATE_TAG_RELATIONSHIPS_LISTS` | Create tag relationships lists | Summary: a tag can be added to one or more lists, with a max of 100 tags per list. use the request body to link tag and list ids. tag: #apiusagelimits scopes: lists:write, tags:write |
| `KLAVIYO_CREATE_TAG_RELATIONSHIPS_SEGMENTS` | Create tag relationships segments | Summary: set tag associations with segments using the request body, limited to one tag per segment and up to 100 tags per segment. rate limits are three requests per second and sixty per minute. tags: segments:write, tags:write |
| `KLAVIYO_CREATE_TEMPLATE` | Create template | Summary: custom html templates can be created unless an account reaches 1,000 template limit. use sparse fieldsets to request specific fields. rate limits are 10 per second and 150 per minute. requires 'templates:write' scope. |
| `KLAVIYO_CREATE_TEMPLATE_CLONE` | Create template clone | Clone a template by its id, but cloning fails if account has 1,000+ templates. api limit: 1,000 templates. rate limits are 10 per second and 150 per minute. requires `templates:write` scope. |
| `KLAVIYO_CREATE_TEMPLATE_RENDER` | Create template render | Render an email template with specific context and sparse fieldsets, then get html/plain text. rate limit: 3/s burst, 60/m steady. scope: templates:read. |
| `KLAVIYO_CREATE_WEBHOOK` | Create webhook | Create a new webhook*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:write` |
| `KLAVIYO_DELETE_CAMPAIGN` | Delete campaign | Delete a campaign with the given campaign id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_DELETE_CATALOG_CATEGORY` | Delete catalog category | Delete a catalog category using the given category id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_DELETE_CATALOG_CATEGORY_RELATIONSHIPS_ITEMS` | Delete catalog category relationships items | Delete item relationships for the given category id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_DELETE_CATALOG_ITEM` | Delete catalog item | Delete a catalog item with the given item id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_DELETE_CATALOG_ITEM_RELATIONSHIPS_CATEGORIES` | Delete catalog item relationships categories | Delete catalog category relationships for the given item id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_DELETE_CATALOG_VARIANT` | Delete catalog variant | Delete a catalog item variant with the given variant id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_DELETE_COUPON` | Delete coupon | Delete the coupon with the given coupon id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `coupons:write` |
| `KLAVIYO_DELETE_COUPON_CODE` | Delete coupon code | Deletes a coupon code specified by the given identifier synchronously. if a profile has been assigned to the coupon code, an exception will be raised*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `coupon-codes:write` |
| `KLAVIYO_DELETE_FLOW` | Delete flow | Delete a flow with the given flow id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:write` |
| `KLAVIYO_DELETE_LIST` | Delete list | Delete a list with the given list id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:write` |
| `KLAVIYO_DELETE_SEGMENT` | Delete segment | Delete a segment with the given segment id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `segments:write` |
| `KLAVIYO_DELETE_TAG` | Delete tag | Delete the tag with the given tag id. any associations between the tag and other resources will also be removed.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` `tags:write` |
| `KLAVIYO_DELETE_TAG_GROUP` | Delete tag group | Delete a specified tag group and its contents; associated resource links will be removed. the default group is undeletable. rate limits: 3/s burst, 60/m steady. requires tags:read and tags:write permissions. |
| `KLAVIYO_DELETE_TAG_RELATIONSHIPS_CAMPAIGNS` | Delete tag relationships campaigns | Disconnect a tag from campaigns using the campaign id(s) in the request body. rate limits: 3 requests/second, 60 requests/minute. required scopes: campaigns:write, tags:write. |
| `KLAVIYO_DELETE_TAG_RELATIONSHIPS_FLOWS` | Delete tag relationships flows | Remove a tag's association with one or more flows. use the request body to pass in the id(s) of the flows(s) whose association with the tag will be removed.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:write` `tags:write` |
| `KLAVIYO_DELETE_TAG_RELATIONSHIPS_LISTS` | Delete tag relationships lists | Remove a tag's association with one or more lists. use the request body to pass in the id(s) of the list(s) whose association with the tag will be removed.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:write` `tags:write` |
| `KLAVIYO_DELETE_TAG_RELATIONSHIPS_SEGMENTS` | Delete tag relationships segments | Use the request body to de-associate a tag from specified segment ids. rate limits are 3 requests/sec and 60 requests/min. required scopes are 'segments:write' and 'tags:write'. |
| `KLAVIYO_DELETE_TEMPLATE` | Delete template | Delete a template with the given template id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `templates:write` |
| `KLAVIYO_DELETE_WEBHOOK` | Delete webhook | Delete a webhook with the given id.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:write` |
| `KLAVIYO_GET_ACCOUNT` | Get account | Retrieve a single account object by its account id. you can only request the account by which the private api key was generated.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `accounts:read` |
| `KLAVIYO_GET_ACCOUNTS` | Get accounts | Use a private api key to fetch an associated account's details like contact info, timezone, and currency, as well as validate the key. rate limit: 1 request/second, 15 requests/minute. scope required: `accounts:read`. |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB` | Get bulk profile import job | Get a bulk profile import job with the given job id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:read` `profiles:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB_ERRORS` | Get bulk profile import job errors | Get import errors for the bulk profile import job with the given id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `profiles:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB_LISTS` | Get bulk profile import job lists | Get list for the bulk profile import job with the given id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB_PROFILES` | Get bulk profile import job profiles | Get profiles for the bulk profile import job with the given id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `profiles:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB_RELATIONSHIPS_LISTS` | Get bulk profile import job relationships lists | Get list relationship for the bulk profile import job with the given id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOB_RELATIONSHIPS_PROFILES` | Get bulk profile import job relationships profiles | Get profile relationships for the bulk profile import job with the given id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `profiles:read` |
| `KLAVIYO_GET_BULK_PROFILE_IMPORT_JOBS` | Get bulk profile import jobs | Get all bulk profile import jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:read` `profiles:read` |
| `KLAVIYO_GET_CAMPAIGN` | Get Campaign | Retrieve a specific campaign by its id from klaviyo. this action fetches detailed information about a single campaign including its name, status, audience settings, send strategy, and optionally related messages and tags. rate limits: 10/s burst, 150/m steady. required scope: `campaigns:read`. preconditions: - valid api key with campaigns:read scope - campaign id must exist and be accessible |
| `KLAVIYO_GET_CAMPAIGN_CAMPAIGN_MESSAGES` | Get campaign campaign messages | Return all messages that belong to the given campaign.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_MESSAGE` | Get campaign message | Returns a specific message based on a required id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_MESSAGE_CAMPAIGN` | Get campaign message campaign | Return the related campaign*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_MESSAGE_RELATIONSHIPS_CAMPAIGN` | Get campaign message relationships campaign | Returns the id of the related campaign*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_MESSAGE_RELATIONSHIPS_TEMPLATE` | Get campaign message relationships template | Returns the id of the related template*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` `templates:read` |
| `KLAVIYO_GET_CAMPAIGN_MESSAGE_TEMPLATE` | Get campaign message template | Return the related template*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` `templates:read` |
| `KLAVIYO_GET_CAMPAIGN_RECIPIENT_ESTIMATION` | Get campaign recipient estimation | Get estimated recipients for a given campaign id using `create campaign recipient estimation job`. rate limits are 10/s burst and 150/m steady. required scope: `campaigns:read`. |
| `KLAVIYO_GET_CAMPAIGN_RECIPIENT_ESTIMATION_JOB` | Get campaign recipient estimation job | Retrieve the status of a recipient estimation job triggered with the `create campaign recipient estimation job` endpoint.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_RELATIONSHIPS_CAMPAIGN_MESSAGES` | Get campaign relationships campaign messages | Returns the ids of all messages associated with the given campaign.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_RELATIONSHIPS_TAGS` | Get campaign relationships tags | Returns the ids of all tags associated with the given campaign.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `campaigns:read` `tags:read` |
| `KLAVIYO_GET_CAMPAIGNS` | Get Campaigns | Retrieve campaigns from your klaviyo account. this action allows you to fetch campaigns with optional filtering and sorting. klaviyo requires specifying a channel (email or sms) to list campaigns. you can add additional filters for status, name, creation date, and other attributes. results are paginated with a default of 10 campaigns per page. rate limits: 10/s burst, 150/m steady. required scope: `campaigns:read`. preconditions: - valid api key with campaigns:read scope - channel must be specified (email or sms) - additional filter syntax must be valid if provided |
| `KLAVIYO_GET_CAMPAIGN_SEND_JOB` | Get campaign send job | Get a campaign send job*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:read` |
| `KLAVIYO_GET_CAMPAIGN_TAGS` | Get campaign tags | Return all tags that belong to the given campaign.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `campaigns:read` `tags:read` |
| `KLAVIYO_GET_CATALOG_CATEGORIES` | Get catalog categories | Retrieve up to 100 account catalog categories, sortable by creation date. only `$custom` integration and `$default` catalog types supported. rate limits are 350/s and 3500/m. requires `catalogs:read` scope. |
| `KLAVIYO_GET_CATALOG_CATEGORY` | Get catalog category | Get a catalog category with the given category id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CATALOG_CATEGORY_ITEMS` | Get catalog category items | Retrieve up to 100 sorted items per request from a category using the category id. sort by 'created' field. rate limits are 350/s burst and 3500/m steady. requires 'catalogs:read' scope. |
| `KLAVIYO_GET_CATALOG_CATEGORY_RELATIONSHIPS_ITEMS` | Get catalog category relationships items | Get all items in the given category id. returns a maximum of 100 items per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CATALOG_ITEM` | Get catalog item | Get a specific catalog item with the given item id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CATALOG_ITEM_CATEGORIES` | Get catalog item categories | Retrieve the catalog categories for an item by id, sorted by 'created' date, with a 100-category maximum per request. rate limits: 350/s burst, 3500/m steady. requires 'catalogs:read' scope. |
| `KLAVIYO_GET_CATALOG_ITEM_RELATIONSHIPS_CATEGORIES` | Get catalog item relationships categories | Get all catalog categories that a particular item is in. returns a maximum of 100 categories per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CATALOG_ITEMS` | Get catalog items | Retrieve up to 100 sorted catalog items per account, with `$custom` integration and `$default` type. rate limits: 350/s burst, 3500/m steady. scope required: `catalogs:read`. |
| `KLAVIYO_GET_CATALOG_ITEM_VARIANTS` | Get catalog item variants | Retrieve up to 100 variants per request for a specific item id, sortable by creation date. rate limits are 350/s burst and 3500/m steady. requires 'catalogs:read' scope. |
| `KLAVIYO_GET_CATALOG_VARIANT` | Get catalog variant | Get a catalog item variant with the given variant id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CATALOG_VARIANTS` | Get catalog variants | Retrieve up to 100 account variants per request, sortable by creation date. supports only `$custom` integration and `$default` catalog types. rate limits are 350/s burst and 3500/m steady. requires `catalogs:read` scope. |
| `KLAVIYO_GET_COUPON` | Get coupon | Get a specific coupon with the given coupon id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupons:read` |
| `KLAVIYO_GET_COUPON_CODE` | Get coupon code | Returns a coupon code specified by the given identifier.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `coupon-codes:read` |
| `KLAVIYO_GET_COUPON_CODE_BULK_CREATE_JOB` | Get coupon code bulk create job | Get a coupon code bulk create job with the given job id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read` |
| `KLAVIYO_GET_COUPON_CODE_BULK_CREATE_JOBS` | Get coupon code bulk create jobs | Get all coupon code bulk create jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read` |
| `KLAVIYO_GET_COUPON_CODE_RELATIONSHIPS_COUPON` | Get coupon code relationships coupon | Gets a list of coupon code relationships associated with the given coupon id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read` |
| `KLAVIYO_GET_COUPON_CODES` | Get coupon codes | Obtains coupon codes using necessary coupon or profile filters. rate limits: 350/s, 3500/m. requires 'coupon-codes:read' scope. |
| `KLAVIYO_GET_COUPON_CODES_FOR_COUPON` | Get coupon codes for coupon | Gets a list of coupon codes associated with the given coupon id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:read` |
| `KLAVIYO_GET_COUPON_FOR_COUPON_CODE` | Get coupon for coupon code | Get the coupon associated with a given coupon code id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupons:read` |
| `KLAVIYO_GET_COUPON_RELATIONSHIPS_COUPON_CODES` | Get coupon relationships coupon codes | Gets the coupon relationship associated with the given coupon code id*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupons:read` |
| `KLAVIYO_GET_COUPONS` | Get coupons | Get all coupons in an account. to learn more, see our [coupons api guide](https://developers.klaviyo.com/en/docs/use klaviyos coupons api).*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupons:read` |
| `KLAVIYO_GET_CREATE_CATEGORIES_JOB` | Get create categories job | Get a catalog category bulk create job with the given job id. an `include` parameter can be provided to get the following related resource data: `categories`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CREATE_CATEGORIES_JOBS` | Get create categories jobs | Get all catalog category bulk create jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CREATE_ITEMS_JOB` | Get create items job | Get a catalog item bulk create job with the given job id. an `include` parameter can be provided to get the following related resource data: `items`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CREATE_ITEMS_JOBS` | Get create items jobs | Get all catalog item bulk create jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CREATE_VARIANTS_JOB` | Get create variants job | Get a catalog variant bulk create job with the given job id. an `include` parameter can be provided to get the following related resource data: `variants`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_CREATE_VARIANTS_JOBS` | Get create variants jobs | Get all catalog variant bulk create jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_CATEGORIES_JOB` | Get delete categories job | Get a catalog category bulk delete job with the given job id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_CATEGORIES_JOBS` | Get delete categories jobs | Get all catalog category bulk delete jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_ITEMS_JOB` | Get delete items job | Get a catalog item bulk delete job with the given job id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_ITEMS_JOBS` | Get delete items jobs | Get all catalog item bulk delete jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_VARIANTS_JOB` | Get delete variants job | Get a catalog variant bulk delete job with the given job id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_DELETE_VARIANTS_JOBS` | Get delete variants jobs | Get all catalog variant bulk delete jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_EVENT` | Get event | Get an event with the given event id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `events:read` |
| `KLAVIYO_GET_EVENT_METRIC` | Get event metric | Get the metric for an event with the given event id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` `metrics:read` |
| `KLAVIYO_GET_EVENT_PROFILE` | Get event profile | Get the profile associated with an event with the given event id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` `profiles:read` |
| `KLAVIYO_GET_EVENT_RELATIONSHIPS_METRIC` | Get event relationships metric | Get a list of related metrics for an event*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` `metrics:read` |
| `KLAVIYO_GET_EVENT_RELATIONSHIPS_PROFILE` | Get event relationships profile | Get profile [relationships](https://developers.klaviyo.com/en/reference/api overview#relationships) for an event with the given event id.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` `profiles:read` |
| `KLAVIYO_GET_EVENTS` | Get events | Get all events in an account requests can be sorted by the following fields: `datetime`, `timestamp` returns a maximum of 200 events per page.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `events:read` |
| `KLAVIYO_GET_FLOW` | Get flow | Get a flow with the given flow id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_ACTION` | Get flow action | Get a flow action from a flow with the given flow action id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_ACTION_FOR_MESSAGE` | Get flow action for message | Get the flow action for a flow message with the given message id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_ACTION_MESSAGES` | Get flow action messages | Retrieve up to 50 flow messages per request by action id, sortable by various fields, with ascending/descending options, and paginated using `page[size]` and `page[number]`. rate limits: 3/s burst, 60/m steady. scope required: `flows:read`. |
| `KLAVIYO_GET_FLOW_ACTION_RELATIONSHIPS_FLOW` | Get flow action relationships flow | Get the flow associated with the given action id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_ACTION_RELATIONSHIPS_MESSAGES` | Get flow action relationships messages | Retrieves up to 50 flow message relationships per request for a specified flow action id, with cursor pagination. rate limits: 3/s burst, 60/min steady. requires `flows:read` scope. |
| `KLAVIYO_GET_FLOW_FLOW_ACTIONS` | Get flow flow actions | Get all flow actions associated with the given flow id. returns a maximum of 50 flows per request, which can be paginated with cursor-based pagination.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_FOR_FLOW_ACTION` | Get flow for flow action | Get the flow associated with the given action id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_MESSAGE` | Get flow message | Get the flow message of a flow with the given message id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_MESSAGE_RELATIONSHIPS_ACTION` | Get flow message relationships action | Get the [relationship](https://developers.klaviyo.com/en/reference/api overview#relationships) for a flow message's flow action, given the flow id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_MESSAGE_RELATIONSHIPS_TEMPLATE` | Get flow message relationships template | Returns the id of the related template*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `templates:read` |
| `KLAVIYO_GET_FLOW_MESSAGE_TEMPLATE` | Get flow message template | Return the related template*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `templates:read` |
| `KLAVIYO_GET_FLOW_RELATIONSHIPS_FLOW_ACTIONS` | Get flow relationships flow actions | Retrieve all flow action relationships for a specific flow id, sortable by `id`, `status`, `created`, `updated`. refine with filters, max 50 per page, paginated by `page[size]` and `page[number]`. rate limits: burst 3/s, steady 60/m. scope: `flows:read`. |
| `KLAVIYO_GET_FLOW_RELATIONSHIPS_TAGS` | Get flow relationships tags | Return the tag ids of all tags associated with the given flow.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` `tags:read` |
| `KLAVIYO_GET_FLOWS` | Get flows | Get all flows in an account. returns a maximum of 50 flows per request, which can be paginated with cursor-based pagination.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` |
| `KLAVIYO_GET_FLOW_TAGS` | Get flow tags | Return all tags associated with the given flow id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` `tags:read` |
| `KLAVIYO_GET_FORM` | Get form | Get the form with the given id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_FORM_FOR_FORM_VERSION` | Get form for form version | Get the form associated with the given form version.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_FORM_ID_FOR_FORM_VERSION` | Get form id for form version | Get the id of the form associated with the given form version.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_FORMS` | Get forms | Get all forms in an account.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_FORM_VERSION` | Get form version | Get the form version with the given id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_IMAGE` | Get image | Get the image with the given image id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `images:read` |
| `KLAVIYO_GET_IMAGES` | Get images | Get all images in an account.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `images:read` |
| `KLAVIYO_GET_LIST` | Get list | Api allows 75 req/sec and 700 req/min, but with 'profile count' param, it's 1 req/sec and 15 req/min. 'lists:read' scope needed. see developer guide for details. |
| `KLAVIYO_GET_LIST_PROFILES` | Get list profiles | Retrieve profiles in a list by id, filterable by email/phone/push token/join date, sortable by join date. regular rate limit: 75/s, 700/m; with predictive analytics: 10/s, 150/m. details at klaviyo guide. scopes required: lists:read, profiles:read. |
| `KLAVIYO_GET_LIST_RELATIONSHIPS_PROFILES` | Get list relationships profiles | Get profile membership [relationships](https://developers.klaviyo.com/en/reference/api overview#relationships) for a list with the given list id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `lists:read` `profiles:read` |
| `KLAVIYO_GET_LIST_RELATIONSHIPS_TAGS` | Get list relationships tags | Returns the tag ids of all tags associated with the given list.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:read` `tags:read` |
| `KLAVIYO_GET_LISTS` | Get Lists | Retrieve marketing lists from your klaviyo account. this action allows you to fetch lists with optional filtering and sorting. you can filter by name, creation date, and other attributes. results are paginated with a default of 10 lists per page. rate limits: 75/s burst, 700/m steady. required scope: `lists:read`. preconditions: - valid api key with lists:read scope - filter syntax must be valid if provided |
| `KLAVIYO_GET_LIST_TAGS` | Get list tags | Return all tags associated with the given list id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:read` `tags:read` |
| `KLAVIYO_GET_METRIC` | Get metric | Get a metric with the given metric id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `metrics:read` |
| `KLAVIYO_GET_METRICS` | Get metrics | Get all metrics in an account. requests can be filtered by the following fields: integration `name`, integration `category` returns a maximum of 200 results per page.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `metrics:read` |
| `KLAVIYO_GET_PROFILE` | Get profile | Get the profile with the given profile id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `profiles:read` |
| `KLAVIYO_GET_PROFILE_LISTS` | Get profile lists | Get list memberships for a profile with the given profile id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:read` `profiles:read` |
| `KLAVIYO_GET_PROFILE_RELATIONSHIPS_LISTS` | Get profile relationships lists | Get list memberships for a profile with the given profile id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:read` `profiles:read` |
| `KLAVIYO_GET_PROFILE_RELATIONSHIPS_SEGMENTS` | Get profile relationships segments | Get segment membership relationships for a profile with the given profile id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `profiles:read` `segments:read` |
| `KLAVIYO_GET_PROFILES` | Get Profiles | Retrieve profiles from your klaviyo account. this action allows you to fetch profiles with optional filtering and sorting. you can filter by email, external id, creation date, and other attributes. results are paginated with a configurable page size. rate limits: 75/s burst, 700/m steady (lower with predictive analytics). required scope: `profiles:read`. preconditions: - valid api key with profiles:read scope - filter syntax must be valid if provided - page size must be between 1 and 100 |
| `KLAVIYO_GET_PROFILE_SEGMENTS` | Get profile segments | Get segment memberships for a profile with the given profile id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `profiles:read` `segments:read` |
| `KLAVIYO_GET_SEGMENT` | Get segment | Fetch a segment by id with default rates of 75/s and 700/m, or with `additional-fields` at 1/s and 15/m. for details, visit the provided guide. required scope: `segments:read`. |
| `KLAVIYO_GET_SEGMENT_PROFILES` | Get segment profiles | Retrieve profiles in a segment by id, filtering by email, phone, token, or join date, and sorting by join date. rate limit: 75/s burst, 700/m steady. requires profiles:read and segments:read scopes. |
| `KLAVIYO_GET_SEGMENT_RELATIONSHIPS_PROFILES` | Get segment relationships profiles | Get all profile membership [relationships](https://developers.klaviyo.com/en/reference/api overview#relationships) for the given segment id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `profiles:read` `segments:read` |
| `KLAVIYO_GET_SEGMENT_RELATIONSHIPS_TAGS` | Get segment relationships tags | If `related resource` is `tags`, returns the tag ids of all tags associated with the given segment id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `segments:read` `tags:read` |
| `KLAVIYO_GET_SEGMENTS` | Get segments | Fetch segments from an account with filters like `name`, `created`, and `updated`. max 10 results/page. rate limits are 75/s burst, 700/m steady. requires `segments:read` scope. |
| `KLAVIYO_GET_SEGMENT_TAGS` | Get segment tags | Return all tags associated with the given segment id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `segments:read` `tags:read` |
| `KLAVIYO_GET_TAG` | Get tag | Retrieve the tag with the given tag id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TAG_GROUP` | Get tag group | Retrieve the tag group with the given tag group id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TAG_GROUP_RELATIONSHIPS_TAGS` | Get tag group relationships tags | Returns the tag ids of all tags inside the given tag group.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TAG_GROUPS` | Get tag groups | Retrieve up to 25 tag groups per account, sortable/filterable by specific attributes. default group included. supports cursor pagination and adheres to rate limits of 3 requests per second and 60 per minute. requires `tags:read` scope. |
| `KLAVIYO_GET_TAG_GROUP_TAGS` | Get tag group tags | Return the tags for a given tag group id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TAG_RELATIONSHIPS_CAMPAIGNS` | Get tag relationships campaigns | Returns the ids of all campaigns associated with the given tag.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `campaigns:read` `tags:read` |
| `KLAVIYO_GET_TAG_RELATIONSHIPS_FLOWS` | Get tag relationships flows | Returns the ids of all flows associated with the given tag.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:read` `tags:read` |
| `KLAVIYO_GET_TAG_RELATIONSHIPS_LISTS` | Get tag relationships lists | Returns the ids of all lists associated with the given tag.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `lists:read` `tags:read` |
| `KLAVIYO_GET_TAG_RELATIONSHIPS_SEGMENTS` | Get tag relationships segments | Returns the ids of all segments associated with the given tag.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `segments:read` `tags:read` |
| `KLAVIYO_GET_TAG_RELATIONSHIPS_TAG_GROUP` | Get tag relationships tag group | Returns the id of the tag group related to the given tag.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TAGS` | Get tags | Retrieve up to 50 account tags at once, filterable/sortable by name or id, with cursor pagination. rate limits: 3/s burst, 60/m steady. requires `tags:read` scope. |
| `KLAVIYO_GET_TAG_TAG_GROUP` | Get tag tag group | Returns the tag group resource for a given tag id.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` |
| `KLAVIYO_GET_TEMPLATE` | Get template | Get a template with the given template id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `templates:read` |
| `KLAVIYO_GET_TEMPLATES` | Get templates | Retrieve account templates with sorting options (`id`, `name`, `created`, `updated`). limit of 10 results per page, rate limits at 10/s burst and 150/m steady. requires `templates:read` scope. |
| `KLAVIYO_GET_UPDATE_CATEGORIES_JOB` | Get update categories job | Get a catalog category bulk update job with the given job id. an `include` parameter can be provided to get the following related resource data: `categories`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_UPDATE_CATEGORIES_JOBS` | Get update categories jobs | Get all catalog category bulk update jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_UPDATE_ITEMS_JOB` | Get update items job | Get a catalog item bulk update job with the given job id. an `include` parameter can be provided to get the following related resource data: `items`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_UPDATE_ITEMS_JOBS` | Get update items jobs | Get all catalog item bulk update jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_UPDATE_VARIANTS_JOB` | Get update variants job | Get a catalog variate bulk update job with the given job id. an `include` parameter can be provided to get the following related resource data: `variants`.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_UPDATE_VARIANTS_JOBS` | Get update variants jobs | Get all catalog variant bulk update jobs. returns a maximum of 100 jobs per request.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `catalogs:read` |
| `KLAVIYO_GET_VERSION_IDS_FOR_FORM` | Get version ids for form | Get the ids of the form versions for the given form.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_VERSIONS_FOR_FORM` | Get versions for form | Get the form versions for the given form.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `forms:read` |
| `KLAVIYO_GET_WEBHOOK` | Get webhook | Get the webhook with the given id.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:read` |
| `KLAVIYO_GET_WEBHOOKS` | Get webhooks | Get all webhooks in an account.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:read` |
| `KLAVIYO_GET_WEBHOOK_TOPIC` | Get webhook topic | Get the webhook topic with the given id.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:read` |
| `KLAVIYO_GET_WEBHOOK_TOPICS` | Get webhook topics | Get all webhook topics in a klaviyo account.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:read` |
| `KLAVIYO_MERGE_PROFILES` | Merge profiles | Queue a task to merge one source profile into a destination profile using their ids. deletes the source afterwards. visit help center for details. rate limits: 10/s burst, 150/m steady. needs `profiles:write` scope. |
| `KLAVIYO_QUERY_CAMPAIGN_VALUES` | Query campaign values | Returns the requested campaign analytics values data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `campaigns:read` |
| `KLAVIYO_QUERY_FLOW_SERIES` | Query flow series | Returns the requested flow analytics series data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `flows:read` |
| `KLAVIYO_QUERY_FLOW_VALUES` | Query flow values | Returns the requested flow analytics values data*rate limits*:burst: `1/s`steady: `2/m`daily: `225/d` **scopes:** `flows:read` |
| `KLAVIYO_QUERY_METRIC_AGGREGATES` | Query metric aggregates | The klaviyo endpoint fetches metric events, handling json requests for custom data queries, sorting, and filtering; offers grouping and time-based filters; requires adherence to rate limits (3 requests per second, 60 per minute) under 'metrics:read'. |
| `KLAVIYO_REMOVE_PROFILE_FROM_LIST` | Remove Profile from List | Remove profiles from a klaviyo list by profile ids or email addresses. this action removes profiles from a marketing list without affecting their overall consent status. use the unsubscribe profiles action for complete unsubscribing. you can remove up to 1000 profiles per call. rate limits: 10/s burst, 150/m steady. required scopes: `lists:write` and `profiles:write`. preconditions: - either profile ids or emails must be provided (not both) - maximum 1000 profiles per call - email addresses must be valid format - the list must exist and be accessible |
| `KLAVIYO_REQUEST_PROFILE_DELETION` | Request profile deletion | To delete a profile, use only one identifier: email, phone number, or id. requests are asynchronous and can be tracked. ensure legal compliance; refer to docs. rate limits: 3 per second, 60 per minute. |
| `KLAVIYO_SPAWN_BULK_PROFILE_IMPORT_JOB` | Spawn bulk profile import job | Initiate a job to create/update a batch of profiles, up to 10,000 with a max size of 5mb per request. rate limits: 10/s burst, 150/m steady. requires `lists:write` and `profiles:write` scopes. more info in the bulk profile import api guide. |
| `KLAVIYO_SPAWN_COUPON_CODE_BULK_CREATE_JOB` | Spawn coupon code bulk create job | Create a coupon-code-bulk-create-job to bulk create a list of coupon codes. max number of jobs queued at once we allow for is 100.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `coupon-codes:write` |
| `KLAVIYO_SPAWN_CREATE_CATEGORIES_JOB` | Spawn create categories job | Create bulk job for up to 100 catalog categories with a 5mb size limit and a max of 500 concurrent jobs. rate limits: 75/s burst, 700/m steady. requires 'catalogs:write' scope. |
| `KLAVIYO_SPAWN_CREATE_ITEMS_JOB` | Spawn create items job | Create batches of up to 100 catalog items with a 5mb size limit using the bulk job, which allows 500 concurrent jobs. rate limits are 75/s burst and 700/m steady. requires `catalogs:write` scope. |
| `KLAVIYO_SPAWN_CREATE_VARIANTS_JOB` | Spawn create variants job | Initiate a job to bulk create up to 100 catalog variants, with a 5mb payload size limit. a max of 500 jobs can run concurrently. rate limits are 75/s burst and 700/m steady. requires 'catalogs:write' scope. |
| `KLAVIYO_SPAWN_DELETE_CATEGORIES_JOB` | Spawn delete categories job | Delete multiple catalog categories in bulk, with a limit of 100 per request and a 5mb payload size. a maximum of 500 concurrent jobs permitted. rate limits are 75/s burst and 700/min steady. requires `catalogs:write` scope. |
| `KLAVIYO_SPAWN_DELETE_ITEMS_JOB` | Spawn delete items job | Delete batches of catalog items with a bulk job, max 100 items/request, 5mb size limit, and up to 500 concurrent jobs. rate limits are 75/s burst and 700/m steady. requires `catalogs:write` scope. |
| `KLAVIYO_SPAWN_DELETE_VARIANTS_JOB` | Spawn delete variants job | Delete multiple catalog variants with a bulk job, max 100 per request, 5mb size limit. only 500 jobs can run concurrently. rate limits: 75/s burst, 700/m steady. requires `catalogs:write` scope. |
| `KLAVIYO_SPAWN_UPDATE_CATEGORIES_JOB` | Spawn update categories job | Create a job to bulk update up to 100 categories, with a 5mb size limit and a maximum of 500 concurrent jobs. burst rate limit is 75/s, steady is 700/m. requires `catalogs:write` scope. |
| `KLAVIYO_SPAWN_UPDATE_ITEMS_JOB` | Spawn update items job | You can bulk update up to 100 catalog items with a 5mb payload limit. a max of 500 jobs can run concurrently. rate limits are 75 requests/second and 700 requests/minute. required scope: `catalogs:write`. |
| `KLAVIYO_SPAWN_UPDATE_VARIANTS_JOB` | Spawn update variants job | Create a job to bulk update up to 100 catalog variants with a 5mb payload limit. a max of 500 jobs may run concurrently. rate limits are 75/s burst and 700/m steady. requires `catalogs:write` scope. |
| `KLAVIYO_SUBSCRIBE_PROFILES` | Subscribe profiles | The api supports double opt-in for marketing, with 'historical import' bypassing consent. it resets opt-outs for returning users. caps at 1000 profiles, 75/s, and 700/min. needs 'lists:write', 'profiles:write', 'subscriptions:write' permissions. |
| `KLAVIYO_SUPPRESS_PROFILES` | Suppress profiles | Suppress profiles by email, segment, or list id to stop email marketing, regardless of consent. view guides for details. max 100 emails per request, with rate limits of 75/s and 700/m. scopes: profiles:write, subscriptions:write. |
| `KLAVIYO_UNREGISTER_CLIENT_PUSH_TOKEN` | Unregister client push token | This endpoint unsubscribes a push token, for use with klaviyo's mobile sdks and a public api key. push notifications must be on. rate limits are 3/s and 60/m. |
| `KLAVIYO_UNSUBSCRIBE_PROFILES` | Unsubscribe profiles | Opt-out profiles from email or sms marketing. unsubscribe up to 100 profiles at a time with burst (75/s) and steady (700/m) rate limits. use different method to remove without affecting subscriptions. more on consent and removal in the provided links. |
| `KLAVIYO_UNSUPPRESS_PROFILES` | Unsuppress profiles | Remove 'user suppressed' blocks on profiles manually via email, segment, or list id. does not affect unsubscribes or other suppressions. limits: 100 emails per request, 75/s burst, 700/m steady. scope: 'subscriptions:write'. |
| `KLAVIYO_UPDATE_CAMPAIGN` | Update Campaign | Update a campaign with the specified attributes. this action allows you to modify campaign settings including name, audiences, and send strategy. only the fields you provide will be updated; others remain unchanged. rate limits: 10/s burst, 150/m steady. required scope: `campaigns:write`. preconditions: - valid api key with campaigns:write scope - campaign id must exist and be accessible - campaign must be in a state that allows updates (usually draft status) - send strategy options must match the selected method |
| `KLAVIYO_UPDATE_CAMPAIGN_MESSAGE` | Update campaign message | Update a campaign message*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_UPDATE_CAMPAIGN_SEND_JOB` | Update campaign send job | Permanently cancel the campaign, setting the status to canceled or revert the campaign, setting the status back to draft*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `campaigns:write` |
| `KLAVIYO_UPDATE_CATALOG_CATEGORY` | Update catalog category | Update a catalog category with the given category id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_UPDATE_CATALOG_CATEGORY_RELATIONSHIPS_ITEMS` | Update catalog category relationships items | Update item relationships for the given category id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_UPDATE_CATALOG_ITEM` | Update catalog item | Update a catalog item with the given item id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_UPDATE_CATALOG_ITEM_RELATIONSHIPS_CATEGORIES` | Update catalog item relationships categories | Update catalog category relationships for the given item id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_UPDATE_CATALOG_VARIANT` | Update catalog variant | Update a catalog item variant with the given variant id.*rate limits*:burst: `75/s`steady: `700/m` **scopes:** `catalogs:write` |
| `KLAVIYO_UPDATE_COUPON` | Update coupon | *rate limits*:burst: `3/s`steady: `60/m` **scopes:** `coupons:write` |
| `KLAVIYO_UPDATE_COUPON_CODE` | Update coupon code | Updates a coupon code specified by the given identifier synchronously. we allow updating the 'status' and 'expires at' of coupon codes.*rate limits*:burst: `350/s`steady: `3500/m` **scopes:** `coupon-codes:write` |
| `KLAVIYO_UPDATE_FLOW_STATUS` | Update flow status | Update the status of a flow with the given flow id, and all actions in that flow.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `flows:write` |
| `KLAVIYO_UPDATE_IMAGE` | Update image | Update the image with the given image id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `images:write` |
| `KLAVIYO_UPDATE_LIST` | Update list | Update the name of a list with the given list id.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `lists:write` |
| `KLAVIYO_UPDATE_PROFILE` | Update profile | Update profiles with the provided id. setting fields to `null` clears them; omitting fields retains existing data. rate limits: 75/s burst, 700/m steady. required scope: `profiles:write`. |
| `KLAVIYO_UPDATE_SEGMENT` | Update segment | Update a segment with the given segment id.*rate limits*:burst: `1/s`steady: `15/m`daily: `100/d` **scopes:** `segments:write` |
| `KLAVIYO_UPDATE_TAG` | Update tag | Update the tag with the given tag id. only a tag's `name` can be changed. a tag cannot be moved from one tag group to another.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` `tags:write` |
| `KLAVIYO_UPDATE_TAG_GROUP` | Update tag group | Update the tag group with the given tag group id. only a tag group's `name` can be changed. a tag group's `exclusive` or `default` value cannot be changed.*rate limits*:burst: `3/s`steady: `60/m` **scopes:** `tags:read` `tags:write` |
| `KLAVIYO_UPDATE_TEMPLATE` | Update template | Update a template with the given template id. does not currently update drag & drop templates.*rate limits*:burst: `10/s`steady: `150/m` **scopes:** `templates:write` |
| `KLAVIYO_UPDATE_WEBHOOK` | Update webhook | Update the webhook with the given id.*rate limits*:burst: `1/s`steady: `15/m` **scopes:** `webhooks:write` |
| `KLAVIYO_UPLOAD_IMAGE_FROM_FILE` | Upload image from file | Upload an image from a file. if you want to import an image from an existing url or a data uri, use the upload image from url endpoint instead.*rate limits*:burst: `3/s`steady: `100/m`daily: `100/d` **scopes:** `images:write` |
| `KLAVIYO_UPLOAD_IMAGE_FROM_URL` | Upload image from url | Import an image from a url or data uri. if you want to upload an image from a file, use the upload image from file endpoint instead.*rate limits*:burst: `3/s`steady: `100/m`daily: `100/d` **scopes:** `images:write` |

## Supported Triggers

None listed.

## Creating MCP Server - Stand-alone vs Composio SDK

The Klaviyo MCP server is an implementation of the Model Context Protocol that connects your AI agent to Klaviyo. It provides structured and secure access so your agent can perform Klaviyo operations on your behalf through a secure, permission-based interface.
With Composio's managed implementation, you don't have to create your own developer app. For production, if you're building an end product, we recommend using your own credentials. The managed server helps you prototype fast and go from 0-1 faster.

## Step-by-step Guide

### 1. Prerequisites

Before starting, make sure you have:
- Composio API Key and OpenAI API Key
- Primary know-how of OpenAI Agents SDK
- A live Klaviyo project
- Some knowledge of Python or Typescript

### 1. Getting API Keys for OpenAI and Composio

OpenAI API Key
- Go to the [OpenAI dashboard](https://platform.openai.com/settings/organization/api-keys) and create an API key. You'll need credits to use the models, or you can connect to another model provider.
- Keep the API key safe.
Composio API Key
- Log in to the [Composio dashboard](https://dashboard.composio.dev?utm_source=toolkits&utm_medium=framework_docs).
- Go to Settings and copy your API key.

### 2. Install dependencies

Install the Composio SDK and the OpenAI Agents SDK.
```python
pip install composio_openai_agents openai-agents python-dotenv
```

```typescript
npm install @composio/openai-agents @openai/agents dotenv
```

### 3. Set up environment variables

Create a .env file and add your OpenAI and Composio API keys.
```bash
OPENAI_API_KEY=sk-...your-api-key
COMPOSIO_API_KEY=your-api-key
USER_ID=composio_user@gmail.com
```

### 4. Import dependencies

What's happening:
- You're importing all necessary libraries.
- The Composio and OpenAIAgentsProvider classes are imported to connect your OpenAI agent to Composio tools like Klaviyo.
```python
import asyncio
import os
from dotenv import load_dotenv

from composio import Composio
from composio_openai_agents import OpenAIAgentsProvider
from agents import Agent, Runner, HostedMCPTool, SQLiteSession
```

```typescript
import 'dotenv/config';
import { Composio } from '@composio/core';
import { OpenAIAgentsProvider } from '@composio/openai-agents';
import { Agent, hostedMcpTool, run, OpenAIConversationsSession } from '@openai/agents';
import * as readline from 'readline';
```

### 5. Set up the Composio instance

No description provided.
```python
load_dotenv()

api_key = os.getenv("COMPOSIO_API_KEY")
user_id = os.getenv("USER_ID")

if not api_key:
    raise RuntimeError("COMPOSIO_API_KEY is not set. Create a .env file with COMPOSIO_API_KEY=your_key")

# Initialize Composio
composio = Composio(api_key=api_key, provider=OpenAIAgentsProvider())
```

```typescript
dotenv.config();

const composioApiKey = process.env.COMPOSIO_API_KEY;
const userId = process.env.USER_ID;

if (!composioApiKey) {
  throw new Error('COMPOSIO_API_KEY is not set. Create a .env file with COMPOSIO_API_KEY=your_key');
}
if (!userId) {
  throw new Error('USER_ID is not set');
}

// Initialize Composio
const composio = new Composio({
  apiKey: composioApiKey,
  provider: new OpenAIAgentsProvider(),
});
```

### 6. Create a Tool Router session

What is happening:
- You give the Tool Router the user id and the toolkits you want available. Here, it is only klaviyo.
- The router checks the user's Klaviyo connection and prepares the MCP endpoint.
- The returned session.mcp.url is the MCP URL that your agent will use to access Klaviyo.
- This approach keeps things lightweight and lets the agent request Klaviyo tools only when needed during the conversation.
```python
# Create a Klaviyo Tool Router session
session = composio.create(
    user_id=user_id,
    toolkits=["klaviyo"]
)

mcp_url = session.mcp.url
```

```typescript
// Create Tool Router session for Klaviyo
const session = await composio.create(userId as string, {
  toolkits: ['klaviyo'],
});
const mcpUrl = session.mcp.url;
```

### 7. Configure the agent

No description provided.
```python
# Configure agent with MCP tool
agent = Agent(
    name="Assistant",
    model="gpt-5",
    instructions=(
        "You are a helpful assistant that can access Klaviyo. "
        "Help users perform Klaviyo operations through natural language."
    ),
    tools=[
        HostedMCPTool(
            tool_config={
                "type": "mcp",
                "server_label": "tool_router",
                "server_url": mcp_url,
                "headers": {"x-api-key": api_key},
                "require_approval": "never",
            }
        )
    ],
)
```

```typescript
// Configure agent with MCP tool
const agent = new Agent({
  name: 'Assistant',
  model: 'gpt-5',
  instructions:
    'You are a helpful assistant that can access Klaviyo. Help users perform Klaviyo operations through natural language.',
  tools: [
    hostedMcpTool({
      serverLabel: 'tool_router',
      serverUrl: mcpUrl,
      headers: { 'x-api-key': composioApiKey },
      requireApproval: 'never',
    }),
  ],
});
```

### 8. Start chat loop and handle conversation

No description provided.
```python
print("\nComposio Tool Router session created.")

chat_session = SQLiteSession("conversation_openai_toolrouter")

print("\nChat started. Type your requests below.")
print("Commands: 'exit', 'quit', or 'q' to end\n")

async def main():
    try:
        result = await Runner.run(
            agent,
            "What can you help me with?",
            session=chat_session
        )
        print(f"Assistant: {result.final_output}\n")
    except Exception as e:
        print(f"Error: {e}\n")

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() in {"exit", "quit", "q"}:
            print("Goodbye!")
            break

        result = await Runner.run(
            agent,
            user_input,
            session=chat_session
        )
        print(f"Assistant: {result.final_output}\n")

asyncio.run(main())
```

```typescript
// Keep conversation state across turns
const conversationSession = new OpenAIConversationsSession();

// Simple CLI
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: 'You: ',
});

console.log('\nComposio Tool Router session created.');
console.log('\nChat started. Type your requests below.');
console.log("Commands: 'exit', 'quit', or 'q' to end\n");

try {
  const first = await run(agent, 'What can you help me with?', { session: conversationSession });
  console.log(`Assistant: ${first.finalOutput}\n`);
} catch (e) {
  console.error('Error:', e instanceof Error ? e.message : e, '\n');
}

rl.prompt();

rl.on('line', async (userInput) => {
  const text = userInput.trim();

  if (['exit', 'quit', 'q'].includes(text.toLowerCase())) {
    console.log('Goodbye!');
    rl.close();
    process.exit(0);
  }

  if (!text) {
    rl.prompt();
    return;
  }

  try {
    const result = await run(agent, text, { session: conversationSession });
    console.log(`\nAssistant: ${result.finalOutput}\n`);
  } catch (e) {
    console.error('Error:', e instanceof Error ? e.message : e, '\n');
  }

  rl.prompt();
});

rl.on('close', () => {
  console.log('\n👋 Session ended.');
  process.exit(0);
});
```

## Complete Code

```python
import asyncio
import os
from dotenv import load_dotenv

from composio import Composio
from composio_openai_agents import OpenAIAgentsProvider
from agents import Agent, Runner, HostedMCPTool, SQLiteSession

load_dotenv()

api_key = os.getenv("COMPOSIO_API_KEY")
user_id = os.getenv("USER_ID")

if not api_key:
    raise RuntimeError("COMPOSIO_API_KEY is not set. Create a .env file with COMPOSIO_API_KEY=your_key")

# Initialize Composio
composio = Composio(api_key=api_key, provider=OpenAIAgentsProvider())

# Create Tool Router session
session = composio.create(
    user_id=user_id,
    toolkits=["klaviyo"]
)
mcp_url = session.mcp.url

# Configure agent with MCP tool
agent = Agent(
    name="Assistant",
    model="gpt-5",
    instructions=(
        "You are a helpful assistant that can access Klaviyo. "
        "Help users perform Klaviyo operations through natural language."
    ),
    tools=[
        HostedMCPTool(
            tool_config={
                "type": "mcp",
                "server_label": "tool_router",
                "server_url": mcp_url,
                "headers": {"x-api-key": api_key},
                "require_approval": "never",
            }
        )
    ],
)

print("\nComposio Tool Router session created.")

chat_session = SQLiteSession("conversation_openai_toolrouter")

print("\nChat started. Type your requests below.")
print("Commands: 'exit', 'quit', or 'q' to end\n")

async def main():
    try:
        result = await Runner.run(
            agent,
            "What can you help me with?",
            session=chat_session
        )
        print(f"Assistant: {result.final_output}\n")
    except Exception as e:
        print(f"Error: {e}\n")

    while True:
        user_input = input("You: ").strip()
        if user_input.lower() in {"exit", "quit", "q"}:
            print("Goodbye!")
            break

        result = await Runner.run(
            agent,
            user_input,
            session=chat_session
        )
        print(f"Assistant: {result.final_output}\n")

asyncio.run(main())
```

```typescript
import 'dotenv/config';
import { Composio } from '@composio/core';
import { OpenAIAgentsProvider } from '@composio/openai-agents';
import { Agent, hostedMcpTool, run, OpenAIConversationsSession } from '@openai/agents';
import * as readline from 'readline';

const composioApiKey = process.env.COMPOSIO_API_KEY;
const userId = process.env.USER_ID;

if (!composioApiKey) {
  throw new Error('COMPOSIO_API_KEY is not set. Create a .env file with COMPOSIO_API_KEY=your_key');
}
if (!userId) {
  throw new Error('USER_ID is not set');
}

// Initialize Composio
const composio = new Composio({
  apiKey: composioApiKey,
  provider: new OpenAIAgentsProvider(),
});

async function main() {
  // Create Tool Router session
  const session = await composio.create(userId as string, {
    toolkits: ['klaviyo'],
  });
  const mcpUrl = session.mcp.url;

  // Configure agent with MCP tool
  const agent = new Agent({
    name: 'Assistant',
    model: 'gpt-5',
    instructions:
      'You are a helpful assistant that can access Klaviyo. Help users perform Klaviyo operations through natural language.',
    tools: [
      hostedMcpTool({
        serverLabel: 'tool_router',
        serverUrl: mcpUrl,
        headers: { 'x-api-key': composioApiKey },
        requireApproval: 'never',
      }),
    ],
  });

  // Keep conversation state across turns
  const conversationSession = new OpenAIConversationsSession();

  // Simple CLI
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
    prompt: 'You: ',
  });

  console.log('\nComposio Tool Router session created.');
  console.log('\nChat started. Type your requests below.');
  console.log("Commands: 'exit', 'quit', or 'q' to end\n");

  try {
    const first = await run(agent, 'What can you help me with?', { session: conversationSession });
    console.log(`Assistant: ${first.finalOutput}\n`);
  } catch (e) {
    console.error('Error:', e instanceof Error ? e.message : e, '\n');
  }

  rl.prompt();

  rl.on('line', async (userInput) => {
    const text = userInput.trim();

    if (['exit', 'quit', 'q'].includes(text.toLowerCase())) {
      console.log('Goodbye!');
      rl.close();
      process.exit(0);
    }

    if (!text) {
      rl.prompt();
      return;
    }

    try {
      const result = await run(agent, text, { session: conversationSession });
      console.log(`\nAssistant: ${result.finalOutput}\n`);
    } catch (e) {
      console.error('Error:', e instanceof Error ? e.message : e, '\n');
    }

    rl.prompt();
  });

  rl.on('close', () => {
    console.log('\nSession ended.');
    process.exit(0);
  });
}

main().catch((err) => {
  console.error('Fatal error:', err);
  process.exit(1);
});
```

## Conclusion

This was a starter code for integrating Klaviyo MCP with OpenAI Agents SDK to build a functional AI agent that can interact with Klaviyo.
Key features:
- Hosted MCP tool integration through Composio's Tool Router
- SQLite session persistence for conversation history
- Simple async chat loop for interactive testing
You can extend this by adding more toolkits, implementing custom business logic, or building a web interface around the agent.

## How to build Klaviyo MCP Agent with another framework

- [ChatGPT](https://composio.dev/toolkits/klaviyo/framework/chatgpt)
- [Claude Agent SDK](https://composio.dev/toolkits/klaviyo/framework/claude-agents-sdk)
- [Claude Code](https://composio.dev/toolkits/klaviyo/framework/claude-code)
- [Claude Cowork](https://composio.dev/toolkits/klaviyo/framework/claude-cowork)
- [Codex](https://composio.dev/toolkits/klaviyo/framework/codex)
- [Cursor](https://composio.dev/toolkits/klaviyo/framework/cursor)
- [VS Code](https://composio.dev/toolkits/klaviyo/framework/vscode)
- [OpenCode](https://composio.dev/toolkits/klaviyo/framework/opencode)
- [OpenClaw](https://composio.dev/toolkits/klaviyo/framework/openclaw)
- [Hermes](https://composio.dev/toolkits/klaviyo/framework/hermes-agent)
- [CLI](https://composio.dev/toolkits/klaviyo/framework/cli)
- [Google ADK](https://composio.dev/toolkits/klaviyo/framework/google-adk)
- [LangChain](https://composio.dev/toolkits/klaviyo/framework/langchain)
- [Vercel AI SDK](https://composio.dev/toolkits/klaviyo/framework/ai-sdk)
- [Mastra AI](https://composio.dev/toolkits/klaviyo/framework/mastra-ai)
- [LlamaIndex](https://composio.dev/toolkits/klaviyo/framework/llama-index)
- [CrewAI](https://composio.dev/toolkits/klaviyo/framework/crew-ai)

## Related Toolkits

- [Reddit](https://composio.dev/toolkits/reddit) - Reddit is a social news platform with thriving user-driven communities (subreddits). It's the go-to place for discussion, content sharing, and viral marketing.
- [Facebook](https://composio.dev/toolkits/facebook) - Facebook is a social media and advertising platform for businesses and creators. It helps you connect, share, and manage content across your public Facebook Pages.
- [Linkedin](https://composio.dev/toolkits/linkedin) - LinkedIn is a professional networking platform for connecting, sharing content, and engaging with business opportunities. It's the go-to place for building your professional brand and unlocking new career connections.
- [Active campaign](https://composio.dev/toolkits/active_campaign) - ActiveCampaign is a marketing automation and CRM platform for managing email campaigns, sales pipelines, and customer segmentation. It helps businesses engage customers and drive growth through smart automation and targeted outreach.
- [ActiveTrail](https://composio.dev/toolkits/active_trail) - ActiveTrail is a user-friendly email marketing and automation platform. It helps you reach subscribers and automate campaigns with ease.
- [Ahrefs](https://composio.dev/toolkits/ahrefs) - Ahrefs is an SEO and marketing platform for site audits, keyword research, and competitor insights. It helps you improve search rankings and drive organic traffic.
- [Amcards](https://composio.dev/toolkits/amcards) - AMCards lets you create and mail personalized greeting cards online. Build stronger customer relationships with easy, automated card campaigns.
- [Beamer](https://composio.dev/toolkits/beamer) - Beamer is a news and changelog platform for in-app announcements and feature updates. It helps companies boost user engagement by sharing news where users are most active.
- [Benchmark email](https://composio.dev/toolkits/benchmark_email) - Benchmark Email is a platform for creating, sending, and tracking email campaigns. It's built to help you engage audiences and analyze results—all in one place.
- [Bigmailer](https://composio.dev/toolkits/bigmailer) - BigMailer is an email marketing platform for managing multiple brands with white-labeling and automation. It helps teams streamline campaigns and simplify integration with Amazon SES.
- [Brandfetch](https://composio.dev/toolkits/brandfetch) - Brandfetch is an API that delivers company logos, colors, and visual branding assets. It helps marketers and developers keep brand visuals consistent everywhere.
- [Brevo](https://composio.dev/toolkits/brevo) - Brevo is an all-in-one email and SMS marketing platform for transactional messaging, automation, and CRM. It helps businesses engage customers and streamline communications through powerful campaign tools.
- [Campayn](https://composio.dev/toolkits/campayn) - Campayn is an email marketing platform for creating, sending, and managing campaigns. It helps businesses engage contacts and grow audiences with easy-to-use tools.
- [Cardly](https://composio.dev/toolkits/cardly) - Cardly is a platform for creating and sending personalized direct mail to customers. It helps businesses break through the digital clutter by getting real engagement via physical mailboxes.
- [ClickSend](https://composio.dev/toolkits/clicksend) - ClickSend is a cloud-based SMS and email marketing platform for businesses. It streamlines communication by enabling quick message delivery and contact management.
- [Crustdata](https://composio.dev/toolkits/crustdata) - CrustData is an AI-powered data intelligence platform for real-time company and people data. It helps B2B sales teams, AI SDRs, and investors react to live business signals.
- [Curated](https://composio.dev/toolkits/curated) - Curated is a platform for collecting, curating, and publishing newsletters. It streamlines content aggregation and distribution for creators and teams.
- [Customerio](https://composio.dev/toolkits/customerio) - Customer.io is a customer engagement platform for targeted messaging across email, SMS, and push. Easily automate, segment, and track communications with your audience.
- [Cutt ly](https://composio.dev/toolkits/cutt_ly) - Cutt.ly is a URL shortening service for managing and analyzing links. Streamline your workflows with quick, trackable, and branded short URLs.
- [Demio](https://composio.dev/toolkits/demio) - Demio is webinar software built for marketers, offering both live and automated sessions with interactive features. It helps teams engage audiences and optimize lead generation through detailed analytics.

## Frequently Asked Questions

### What are the differences in Tool Router MCP and Klaviyo MCP?

With a standalone Klaviyo MCP server, the agents and LLMs can only access a fixed set of Klaviyo tools tied to that server. However, with the Composio Tool Router, agents can dynamically load tools from Klaviyo and many other apps based on the task at hand, all through a single MCP endpoint.

### Can I use Tool Router MCP with OpenAI Agents SDK?

Yes, you can. OpenAI Agents SDK fully supports MCP integration. You get structured tool calling, message history handling, and model orchestration while Tool Router takes care of discovering and serving the right Klaviyo tools.

### Can I manage the permissions and scopes for Klaviyo while using Tool Router?

Yes, absolutely. You can configure which Klaviyo scopes and actions are allowed when connecting your account to Composio. You can also bring your own OAuth credentials or API configuration so you keep full control over what the agent can do.

### How safe is my data with Composio Tool Router?

All sensitive data such as tokens, keys, and configuration is fully encrypted at rest and in transit. Composio is SOC 2 Type 2 compliant and follows strict security practices so your Klaviyo data and credentials are handled as safely as possible.

---
[See all toolkits](https://composio.dev/toolkits) · [Composio docs](https://docs.composio.dev/llms.txt)
