- name
- klaviyo
- description
- |
- compatibility
- Requires network access and valid Maton API key
- metadata
- author
- maton
- version
- 1.0
- clawdbot
- emoji
- 🧠
- requires
- env
Klaviyo
Access the Klaviyo API with managed OAuth authentication. Manage profiles, lists, segments, campaigns, flows, events, metrics, templates, catalogs, and webhooks for email marketing and customer engagement.
Quick Start
# List profiles
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFBase URL
https://gateway.maton.ai/klaviyo/{native-api-path}Replace {native-api-path} with the actual Klaviyo API endpoint path. The gateway proxies requests to a.klaviyo.com and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEYEnvironment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"Getting Your API Key
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
API Versioning
Klaviyo uses date-based API versioning. Include the revision header in all requests:
revision: 2026-01-15Connection Management
Manage your Klaviyo OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=klaviyo&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'klaviyo'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"connection": {
"connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "klaviyo",
"metadata": {}
}
}Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFSpecifying Connection
If you have multiple Klaviyo connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFIf omitted, the gateway uses the default (oldest) active connection.
API Reference
Profiles
Manage customer data and consent.
Get Profiles
GET /klaviyo/api/profilesQuery parameters:
filter- Filter profiles (e.g.,filter=equals(email,"test@example.com"))fields[profile]- Comma-separated list of fields to includepage[cursor]- Cursor for paginationpage[size]- Number of results per page (max 100)sort- Sort field (prefix with-for descending)
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles?fields[profile]=email,first_name,last_name&page[size]=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "profile",
"id": "01GDDKASAP8TKDDA2GRZDSVP4H",
"attributes": {
"email": "alice@example.com",
"first_name": "Alice",
"last_name": "Johnson"
}
}
],
"links": {
"self": "https://a.klaviyo.com/api/profiles",
"next": "https://a.klaviyo.com/api/profiles?page[cursor]=..."
}
}Get a Profile
GET /klaviyo/api/profiles/{profile_id}Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles/01GDDKASAP8TKDDA2GRZDSVP4H')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate a Profile
POST /klaviyo/api/profiles
Content-Type: application/json
{
"data": {
"type": "profile",
"attributes": {
"email": "newuser@example.com",
"first_name": "John",
"last_name": "Doe",
"phone_number": "+15551234567",
"properties": {
"custom_field": "value"
}
}
}
}Example:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'profile', 'attributes': {'email': 'newuser@example.com', 'first_name': 'John', 'last_name': 'Doe'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFUpdate a Profile
PATCH /klaviyo/api/profiles/{profile_id}Example:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'profile', 'id': '01GDDKASAP8TKDDA2GRZDSVP4H', 'attributes': {'first_name': 'Jane'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles/01GDDKASAP8TKDDA2GRZDSVP4H', data=data, method='PATCH')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFMerge Profiles
POST /klaviyo/api/profile-mergeGet Profile Lists
GET /klaviyo/api/profiles/{profile_id}/listsGet Profile Segments
GET /klaviyo/api/profiles/{profile_id}/segmentsLists
Organize subscribers into static lists.
Get Lists
GET /klaviyo/api/listsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/lists?fields[list]=name,created,updated')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "list",
"id": "Y6nRLr",
"attributes": {
"name": "Newsletter Subscribers",
"created": "2024-01-15T10:30:00Z",
"updated": "2024-03-01T14:22:00Z"
}
}
]
}Get a List
GET /klaviyo/api/lists/{list_id}Create a List
POST /klaviyo/api/listsExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'list', 'attributes': {'name': 'VIP Customers'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/lists', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFUpdate a List
PATCH /klaviyo/api/lists/{list_id}Delete a List
DELETE /klaviyo/api/lists/{list_id}Add Profiles to List
POST /klaviyo/api/lists/{list_id}/relationships/profilesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': [{'type': 'profile', 'id': '01GDDKASAP8TKDDA2GRZDSVP4H'}]}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/lists/Y6nRLr/relationships/profiles', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFRemove Profiles from List
DELETE /klaviyo/api/lists/{list_id}/relationships/profilesGet List Profiles
GET /klaviyo/api/lists/{list_id}/profilesSegments
Create dynamic audiences based on conditions.
Get Segments
GET /klaviyo/api/segmentsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/segments?fields[segment]=name,created,updated')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet a Segment
GET /klaviyo/api/segments/{segment_id}Create a Segment
POST /klaviyo/api/segmentsUpdate a Segment
PATCH /klaviyo/api/segments/{segment_id}Delete a Segment
DELETE /klaviyo/api/segments/{segment_id}Get Segment Profiles
GET /klaviyo/api/segments/{segment_id}/profilesCampaigns
Design and send email campaigns.
Get Campaigns
GET /klaviyo/api/campaignsNote: A channel filter is required. Usefilter=equals(messages.channel,"email")orfilter=equals(messages.channel,"sms").
Query parameters:
filter- Required. Filter by channel (e.g.,filter=equals(messages.channel,"email"))fields[campaign]- Fields to includesort- Sort by field
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/campaigns?filter=equals(messages.channel,"email")')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "campaign",
"id": "01GDDKASAP8TKDDA2GRZDSVP4I",
"attributes": {
"name": "Spring Sale 2024",
"status": "Draft",
"audiences": {
"included": ["Y6nRLr"],
"excluded": []
},
"send_options": {
"use_smart_sending": true
}
}
}
]
}Get a Campaign
GET /klaviyo/api/campaigns/{campaign_id}Create a Campaign
POST /klaviyo/api/campaignsExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'campaign', 'attributes': {'name': 'Summer Newsletter', 'audiences': {'included': ['Y6nRLr']}, 'campaign-messages': {'data': [{'type': 'campaign-message', 'attributes': {'channel': 'email'}}]}}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/campaigns', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFUpdate a Campaign
PATCH /klaviyo/api/campaigns/{campaign_id}Delete a Campaign
DELETE /klaviyo/api/campaigns/{campaign_id}Send a Campaign
POST /klaviyo/api/campaign-send-jobsGet Recipient Estimation
POST /klaviyo/api/campaign-recipient-estimationsFlows
Build automated customer journeys.
Get Flows
GET /klaviyo/api/flowsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/flows?fields[flow]=name,status,created,updated')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "flow",
"id": "VJvBNr",
"attributes": {
"name": "Welcome Series",
"status": "live",
"created": "2024-01-10T08:00:00Z",
"updated": "2024-02-15T12:30:00Z"
}
}
]
}Get a Flow
GET /klaviyo/api/flows/{flow_id}Create a Flow
POST /klaviyo/api/flowsNote: Flow creation via API may be limited. Flows are typically created through the Klaviyo UI, then managed via API. Use GET, PATCH, and DELETE operations for existing flows.
Update Flow Status
PATCH /klaviyo/api/flows/{flow_id}Example:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'flow', 'id': 'VJvBNr', 'attributes': {'status': 'draft'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/flows/VJvBNr', data=data, method='PATCH')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFDelete a Flow
DELETE /klaviyo/api/flows/{flow_id}Get Flow Actions
GET /klaviyo/api/flows/{flow_id}/flow-actionsGet Flow Messages
GET /klaviyo/api/flows/{flow_id}/flow-messagesEvents
Track customer interactions and behaviors.
Get Events
GET /klaviyo/api/eventsQuery parameters:
filter- Filter events (e.g.,filter=equals(metric_id,"ABC123"))fields[event]- Fields to includesort- Sort by field (default:-datetime)
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/events?filter=greater-than(datetime,2024-01-01T00:00:00Z)&page[size]=50')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "event",
"id": "4vRpBT",
"attributes": {
"metric_id": "TxVpCr",
"profile_id": "01GDDKASAP8TKDDA2GRZDSVP4H",
"datetime": "2024-03-15T14:30:00Z",
"event_properties": {
"value": 99.99,
"product_name": "Running Shoes"
}
}
}
]
}Get an Event
GET /klaviyo/api/events/{event_id}Create an Event
POST /klaviyo/api/eventsExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'event', 'attributes': {'profile': {'data': {'type': 'profile', 'attributes': {'email': 'customer@example.com'}}}, 'metric': {'data': {'type': 'metric', 'attributes': {'name': 'Viewed Product'}}}, 'properties': {'product_id': 'SKU123', 'product_name': 'Blue T-Shirt', 'price': 29.99}}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/events', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFBulk Create Events
POST /klaviyo/api/event-bulk-create-jobsMetrics
Access performance data and analytics.
Get Metrics
GET /klaviyo/api/metricsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/metrics')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "metric",
"id": "TxVpCr",
"attributes": {
"name": "Placed Order",
"created": "2024-01-01T00:00:00Z",
"updated": "2024-03-01T00:00:00Z",
"integration": {
"object": "integration",
"id": "shopify",
"name": "Shopify"
}
}
}
]
}Get a Metric
GET /klaviyo/api/metrics/{metric_id}Query Metric Aggregates
POST /klaviyo/api/metric-aggregatesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'metric-aggregate', 'attributes': {'metric_id': 'TxVpCr', 'measurements': ['count', 'sum_value'], 'interval': 'day', 'filter': ['greater-or-equal(datetime,2024-01-01)', 'less-than(datetime,2024-04-01)']}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/metric-aggregates', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFTemplates
Manage email templates.
Get Templates
GET /klaviyo/api/templatesExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/templates?fields[template]=name,created,updated')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet a Template
GET /klaviyo/api/templates/{template_id}Create a Template
POST /klaviyo/api/templatesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'template', 'attributes': {'name': 'Welcome Email', 'editor_type': 'CODE', 'html': '<html><body><h1>Welcome!</h1></body></html>'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/templates', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFUpdate a Template
PATCH /klaviyo/api/templates/{template_id}Delete a Template
DELETE /klaviyo/api/templates/{template_id}Render a Template
POST /klaviyo/api/template-renderClone a Template
POST /klaviyo/api/template-cloneCatalogs
Manage product catalogs.
Get Catalog Items
GET /klaviyo/api/catalog-itemsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/catalog-items?fields[catalog-item]=title,price,url')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse:
{
"data": [
{
"type": "catalog-item",
"id": "$custom:::$default:::PROD-001",
"attributes": {
"title": "Blue Running Shoes",
"price": 129.99,
"url": "https://store.example.com/products/blue-running-shoes"
}
}
]
}Get a Catalog Item
GET /klaviyo/api/catalog-items/{catalog_item_id}Create Catalog Items
POST /klaviyo/api/catalog-itemsUpdate Catalog Item
PATCH /klaviyo/api/catalog-items/{catalog_item_id}Delete Catalog Item
DELETE /klaviyo/api/catalog-items/{catalog_item_id}Get Catalog Variants
GET /klaviyo/api/catalog-variantsGet Catalog Categories
GET /klaviyo/api/catalog-categoriesTags
Organize resources with tags.
Get Tags
GET /klaviyo/api/tagsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/tags')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate a Tag
POST /klaviyo/api/tagsUpdate a Tag
PATCH /klaviyo/api/tags/{tag_id}Delete a Tag
DELETE /klaviyo/api/tags/{tag_id}Tag a Campaign
POST /klaviyo/api/tag-campaign-relationshipsTag a Flow
POST /klaviyo/api/tag-flow-relationshipsGet Tag Groups
GET /klaviyo/api/tag-groupsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/tag-groups')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Tag Group
POST /klaviyo/api/tag-groupsUpdate Tag Group
PATCH /klaviyo/api/tag-groups/{tag_group_id}Delete Tag Group
DELETE /klaviyo/api/tag-groups/{tag_group_id}Coupons
Manage discount codes.
Get Coupons
GET /klaviyo/api/couponsCreate a Coupon
POST /klaviyo/api/couponsExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'coupon', 'attributes': {'external_id': 'SUMMER_SALE_2024', 'description': 'Summer sale discount coupon'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/coupons', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFNote: Theexternal_idmust match regex^[0-9_A-z]+$(alphanumeric and underscores only, no hyphens).
Get Coupon Codes
GET /klaviyo/api/coupon-codesNote: This endpoint requires a filter parameter. You must filter by coupon ID or profile ID.
Example:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/coupon-codes?filter=equals(coupon.id,"SUMMER_SALE_2024")')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Coupon Codes
POST /klaviyo/api/coupon-codesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'coupon-code', 'attributes': {'unique_code': 'SAVE20NOW', 'expires_at': '2025-12-31T23:59:59Z'}, 'relationships': {'coupon': {'data': {'type': 'coupon', 'id': 'SUMMER_SALE_2024'}}}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/coupon-codes', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFWebhooks
Configure event notifications.
Get Webhooks
GET /klaviyo/api/webhooksExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/webhooks')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Webhook
POST /klaviyo/api/webhooksExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'webhook', 'attributes': {'name': 'Order Placed Webhook', 'endpoint_url': 'https://example.com/webhooks/klaviyo', 'enabled': True}, 'relationships': {'webhook-topics': {'data': [{'type': 'webhook-topic', 'id': 'campaign:sent'}]}}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/webhooks', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet a Webhook
GET /klaviyo/api/webhooks/{webhook_id}Update a Webhook
PATCH /klaviyo/api/webhooks/{webhook_id}Delete a Webhook
DELETE /klaviyo/api/webhooks/{webhook_id}Get Webhook Topics
GET /klaviyo/api/webhook-topicsAccounts
Retrieve account information.
Get Accounts
GET /klaviyo/api/accountsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/accounts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFImages
Manage uploaded images.
Get Images
GET /klaviyo/api/imagesExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/images')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet an Image
GET /klaviyo/api/images/{image_id}Upload Image from URL
POST /klaviyo/api/imagesExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'data': {'type': 'image', 'attributes': {'import_from_url': 'https://example.com/image.jpg', 'name': 'Product Image'}}}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/images', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFForms
Manage signup forms.
Get Forms
GET /klaviyo/api/formsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/forms')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet a Form
GET /klaviyo/api/forms/{form_id}Get Form Versions
GET /klaviyo/api/forms/{form_id}/form-versionsReviews
Manage product reviews.
Get Reviews
GET /klaviyo/api/reviewsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/reviews')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFGet a Review
GET /klaviyo/api/reviews/{review_id}Update Review
PATCH /klaviyo/api/reviews/{review_id}Universal Content
Manage reusable email content blocks.
Get Universal Content
GET /klaviyo/api/template-universal-contentExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/template-universal-content')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Universal Content
POST /klaviyo/api/template-universal-contentUpdate Universal Content
PATCH /klaviyo/api/template-universal-content/{content_id}Delete Universal Content
DELETE /klaviyo/api/template-universal-content/{content_id}Bulk Profile Subscriptions
Manage email/SMS subscriptions in bulk.
Bulk Subscribe Profiles
POST /klaviyo/api/profile-subscription-bulk-create-jobsExample:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({
'data': {
'type': 'profile-subscription-bulk-create-job',
'attributes': {
'profiles': {
'data': [{
'type': 'profile',
'attributes': {
'email': 'newsubscriber@example.com',
'subscriptions': {
'email': {'marketing': {'consent': 'SUBSCRIBED'}}
}
}
}]
}
},
'relationships': {
'list': {'data': {'type': 'list', 'id': 'LIST_ID'}}
}
}
}).encode()
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profile-subscription-bulk-create-jobs', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFBulk Unsubscribe Profiles
POST /klaviyo/api/profile-subscription-bulk-delete-jobsBulk Suppress Profiles
POST /klaviyo/api/profile-suppression-bulk-create-jobsBulk Unsuppress Profiles
POST /klaviyo/api/profile-suppression-bulk-delete-jobsProfile Bulk Import
Import profiles in bulk.
Get Bulk Import Jobs
GET /klaviyo/api/profile-bulk-import-jobsExample:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profile-bulk-import-jobs')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFCreate Bulk Import Job
POST /klaviyo/api/profile-bulk-import-jobsFiltering
Klaviyo uses JSON:API filtering syntax. Common operators:
| Operator | Example |
|---|---|
equals | filter=equals(email,"test@example.com") |
contains | filter=contains(name,"newsletter") |
greater-than | filter=greater-than(datetime,2024-01-01T00:00:00Z) |
less-than | filter=less-than(created,2024-03-01) |
greater-or-equal | filter=greater-or-equal(updated,2024-01-01) |
any | filter=any(status,["draft","scheduled"]) |
Combine filters with and:
filter=and(equals(status,"active"),greater-than(created,2024-01-01))Pagination
Klaviyo uses cursor-based pagination:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/klaviyo/api/profiles?page[size]=50&page[cursor]=CURSOR_TOKEN')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('revision', '2026-01-15')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFResponse includes pagination links:
{
"data": [...],
"links": {
"self": "https://a.klaviyo.com/api/profiles",
"next": "https://a.klaviyo.com/api/profiles?page[cursor]=WzE2..."
}
}Sparse Fieldsets
Request only specific fields to reduce response size:
# Request only email and first_name for profiles
?fields[profile]=email,first_name
# Request specific fields for included relationships
?include=lists&fields[list]=name,createdCode Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/klaviyo/api/profiles?fields[profile]=email,first_name',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
'revision': '2024-10-15'
}
}
);
const data = await response.json();Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/klaviyo/api/profiles',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'revision': '2024-10-15'
},
params={'fields[profile]': 'email,first_name'}
)
data = response.json()Notes
- All requests use JSON:API specification
- Timestamps are in ISO 8601 RFC 3339 format (e.g.,
2024-01-16T23:20:50.52Z) - Resource IDs are strings (often base64-encoded)
- Use sparse fieldsets to optimize response size
- Include
revisionheader for API versioning (recommended:2026-01-15) - Some POST endpoints return
200instead of201for successful creation - Coupon
external_idmust match regex^[0-9_A-z]+$(no hyphens) - Coupon codes endpoint requires a filter (e.g.,
filter=equals(coupon.id,"...")) - Flow creation via API may be limited; flows are typically created in the Klaviyo UI
- IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets (fields[],page[]) to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.
Error Handling
| Status | Meaning |
|---|---|
| 400 | Bad request or missing Klaviyo connection |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - insufficient permissions |
| 404 | Resource not found |
| 429 | Rate limited (fixed-window algorithm) |
| 4xx/5xx | Passthrough error from Klaviyo API |
Troubleshooting: API Key Issues
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOFTroubleshooting: Invalid App Name
- Ensure your URL path starts with
klaviyo. For example:
- Correct:
https://gateway.maton.ai/klaviyo/api/profiles - Incorrect:
https://gateway.maton.ai/api/profiles