ClawSkills logoClawSkills

Klaviyo

Klaviyo API integration with managed OAuth. Access profiles, lists, segments, campaigns, flows, events, metrics, templates, catalogs, and webhooks. Use this ski

Introduction

# 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

```bash # 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

## Base 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_KEY ```

**Environment Variable:** Set your API key as `MATON_API_KEY`:

```bash export MATON_API_KEY="YOUR_API_KEY" ```

### Getting Your API Key

1. Sign in or create an account at [maton.ai](https://maton.ai) 2. Go to [maton.ai/settings](https://maton.ai/settings) 3. Copy your API key

## API Versioning

Klaviyo uses date-based API versioning. Include the `revision` header in all requests:

``` revision: 2024-10-15 ```

## Connection Management

Manage your Klaviyo OAuth connections at `https://ctrl.maton.ai`.

### List Connections

```bash 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)) EOF ```

### Create Connection

```bash 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)) EOF ```

### Get Connection

```bash 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)) EOF ```

**Response:** ```json { "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

```bash 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)) EOF ```

### Specifying Connection

If you have multiple Klaviyo connections, specify which one to use with the `Maton-Connection` header:

```bash 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', '2024-10-15') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

If omitted, the gateway uses the default (oldest) active connection.

## API Reference

### Profiles

Manage customer data and consent.

#### Get Profiles

```bash GET /klaviyo/api/profiles ```

Query parameters: - `filter` - Filter profiles (e.g., `filter=equals(email,"[email protected]")`) - `fields[profile]` - Comma-separated list of fields to include - `page[cursor]` - Cursor for pagination - `page[size]` - Number of results per page (max 100) - `sort` - Sort field (prefix with `-` for descending)

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "data": [ { "type": "profile", "id": "01GDDKASAP8TKDDA2GRZDSVP4H", "attributes": { "email": "[email protected]", "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

```bash GET /klaviyo/api/profiles/{profile_id} ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Create a Profile

```bash POST /klaviyo/api/profiles Content-Type: application/json

{ "data": { "type": "profile", "attributes": { "email": "[email protected]", "first_name": "John", "last_name": "Doe", "phone_number": "+15551234567", "properties": { "custom_field": "value" } } } } ```

**Example:**

```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'data': {'type': 'profile', 'attributes': {'email': '[email protected]', '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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update a Profile

```bash PATCH /klaviyo/api/profiles/{profile_id} ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Merge Profiles

```bash POST /klaviyo/api/profile-merge ```

#### Get Profile Lists

```bash GET /klaviyo/api/profiles/{profile_id}/lists ```

#### Get Profile Segments

```bash GET /klaviyo/api/profiles/{profile_id}/segments ```

### Lists

Organize subscribers into static lists.

#### Get Lists

```bash GET /klaviyo/api/lists ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "data": [ { "type": "list", "id": "Y6nRLr", "attributes": { "name": "Newsletter Subscribers", "created": "2024-01-15T10:30:00Z", "updated": "2024-03-01T14:22:00Z" } } ] } ```

#### Get a List

```bash GET /klaviyo/api/lists/{list_id} ```

#### Create a List

```bash POST /klaviyo/api/lists ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update a List

```bash PATCH /klaviyo/api/lists/{list_id} ```

#### Delete a List

```bash DELETE /klaviyo/api/lists/{list_id} ```

#### Add Profiles to List

```bash POST /klaviyo/api/lists/{list_id}/relationships/profiles ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Remove Profiles from List

```bash DELETE /klaviyo/api/lists/{list_id}/relationships/profiles ```

#### Get List Profiles

```bash GET /klaviyo/api/lists/{list_id}/profiles ```

### Segments

Create dynamic audiences based on conditions.

#### Get Segments

```bash GET /klaviyo/api/segments ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Get a Segment

```bash GET /klaviyo/api/segments/{segment_id} ```

#### Create a Segment

```bash POST /klaviyo/api/segments ```

#### Update a Segment

```bash PATCH /klaviyo/api/segments/{segment_id} ```

#### Delete a Segment

```bash DELETE /klaviyo/api/segments/{segment_id} ```

#### Get Segment Profiles

```bash GET /klaviyo/api/segments/{segment_id}/profiles ```

### Campaigns

Design and send email campaigns.

#### Get Campaigns

```bash GET /klaviyo/api/campaigns ```

Query parameters: - `filter` - Filter campaigns (e.g., `filter=equals(messages.channel,'email')`) - `fields[campaign]` - Fields to include - `sort` - Sort by field

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "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

```bash GET /klaviyo/api/campaigns/{campaign_id} ```

#### Create a Campaign

```bash POST /klaviyo/api/campaigns ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update a Campaign

```bash PATCH /klaviyo/api/campaigns/{campaign_id} ```

#### Delete a Campaign

```bash DELETE /klaviyo/api/campaigns/{campaign_id} ```

#### Send a Campaign

```bash POST /klaviyo/api/campaign-send-jobs ```

#### Get Recipient Estimation

```bash POST /klaviyo/api/campaign-recipient-estimations ```

### Flows

Build automated customer journeys.

#### Get Flows

```bash GET /klaviyo/api/flows ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "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

```bash GET /klaviyo/api/flows/{flow_id} ```

#### Create a Flow

```bash POST /klaviyo/api/flows ```

> **Note:** 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

```bash PATCH /klaviyo/api/flows/{flow_id} ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Delete a Flow

```bash DELETE /klaviyo/api/flows/{flow_id} ```

#### Get Flow Actions

```bash GET /klaviyo/api/flows/{flow_id}/flow-actions ```

#### Get Flow Messages

```bash GET /klaviyo/api/flows/{flow_id}/flow-messages ```

### Events

Track customer interactions and behaviors.

#### Get Events

```bash GET /klaviyo/api/events ```

Query parameters: - `filter` - Filter events (e.g., `filter=equals(metric_id,"ABC123")`) - `fields[event]` - Fields to include - `sort` - Sort by field (default: `-datetime`)

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "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

```bash GET /klaviyo/api/events/{event_id} ```

#### Create an Event

```bash POST /klaviyo/api/events ```

**Example:**

```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'data': {'type': 'event', 'attributes': {'profile': {'data': {'type': 'profile', 'attributes': {'email': '[email protected]'}}}, '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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Bulk Create Events

```bash POST /klaviyo/api/event-bulk-create-jobs ```

### Metrics

Access performance data and analytics.

#### Get Metrics

```bash GET /klaviyo/api/metrics ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "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

```bash GET /klaviyo/api/metrics/{metric_id} ```

#### Query Metric Aggregates

```bash POST /klaviyo/api/metric-aggregates ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Templates

Manage email templates.

#### Get Templates

```bash GET /klaviyo/api/templates ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Get a Template

```bash GET /klaviyo/api/templates/{template_id} ```

#### Create a Template

```bash POST /klaviyo/api/templates ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update a Template

```bash PATCH /klaviyo/api/templates/{template_id} ```

#### Delete a Template

```bash DELETE /klaviyo/api/templates/{template_id} ```

#### Render a Template

```bash POST /klaviyo/api/template-render ```

#### Clone a Template

```bash POST /klaviyo/api/template-clone ```

### Catalogs

Manage product catalogs.

#### Get Catalog Items

```bash GET /klaviyo/api/catalog-items ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "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

```bash GET /klaviyo/api/catalog-items/{catalog_item_id} ```

#### Create Catalog Items

```bash POST /klaviyo/api/catalog-items ```

#### Update Catalog Item

```bash PATCH /klaviyo/api/catalog-items/{catalog_item_id} ```

#### Delete Catalog Item

```bash DELETE /klaviyo/api/catalog-items/{catalog_item_id} ```

#### Get Catalog Variants

```bash GET /klaviyo/api/catalog-variants ```

#### Get Catalog Categories

```bash GET /klaviyo/api/catalog-categories ```

### Tags

Organize resources with tags.

#### Get Tags

```bash GET /klaviyo/api/tags ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Create a Tag

```bash POST /klaviyo/api/tags ```

#### Update a Tag

```bash PATCH /klaviyo/api/tags/{tag_id} ```

#### Delete a Tag

```bash DELETE /klaviyo/api/tags/{tag_id} ```

#### Tag a Campaign

```bash POST /klaviyo/api/tag-campaign-relationships ```

#### Tag a Flow

```bash POST /klaviyo/api/tag-flow-relationships ```

### Coupons

Manage discount codes.

#### Get Coupons

```bash GET /klaviyo/api/coupons ```

#### Create a Coupon

```bash POST /klaviyo/api/coupons ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

> **Note:** The `external_id` must match regex `^[0-9_A-z]+$` (alphanumeric and underscores only, no hyphens).

#### Get Coupon Codes

```bash GET /klaviyo/api/coupon-codes ```

> **Note:** This endpoint requires a filter parameter. You must filter by coupon ID or profile ID.

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Create Coupon Codes

```bash POST /klaviyo/api/coupon-codes ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Webhooks

Configure event notifications.

#### Get Webhooks

```bash GET /klaviyo/api/webhooks ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Create Webhook

```bash POST /klaviyo/api/webhooks ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Get a Webhook

```bash GET /klaviyo/api/webhooks/{webhook_id} ```

#### Update a Webhook

```bash PATCH /klaviyo/api/webhooks/{webhook_id} ```

#### Delete a Webhook

```bash DELETE /klaviyo/api/webhooks/{webhook_id} ```

#### Get Webhook Topics

```bash GET /klaviyo/api/webhook-topics ```

### Accounts

Retrieve account information.

#### Get Accounts

```bash GET /klaviyo/api/accounts ```

**Example:**

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

## Filtering

Klaviyo uses JSON:API filtering syntax. Common operators:

| Operator | Example | |----------|---------| | `equals` | `filter=equals(email,"[email protected]")` | | `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:

```bash 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', '2024-10-15') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

Response includes pagination links:

```json { "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:

```bash # Request only email and first_name for profiles ?fields[profile]=email,first_name

# Request specific fields for included relationships ?include=lists&fields[list]=name,created ```

## Code Examples

### JavaScript

```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

```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 `revision` header for API versioning (recommended: `2024-10-15`) - Some POST endpoints return `200` instead of `201` for successful creation - Coupon `external_id` must 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 -g` when URLs contain brackets (`fields[]`, `page[]`) to disable glob parsing - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may 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

1. Check that the `MATON_API_KEY` environment variable is set:

```bash echo $MATON_API_KEY ```

2. Verify the API key is valid by listing connections:

```bash 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)) EOF ```

### Troubleshooting: Invalid App Name

1. Ensure your URL path starts with `klaviyo`. For example:

- Correct: `https://gateway.maton.ai/klaviyo/api/profiles` - Incorrect: `https://gateway.maton.ai/api/profiles`

## Resources

- [Klaviyo API Documentation](https://developers.klaviyo.com) - [API Reference](https://developers.klaviyo.com/en/reference/api_overview) - [Klaviyo Developer Portal](https://developers.klaviyo.com/en) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[email protected])

More Products