Campaigns
Campaigns enable management of promotional content that appears throughout the customer's post-purchase journey. Use campaigns to drive repeat purchases, increase customer lifetime value, and enhance brand engagement.
Via our API, you have total control of the campaigns that you show in the tracking page,
Overview
Campaigns are promotional units that can be:
- Targeted to specific customer segments
- Scheduled with precise timing controls
- Localized with multi-language support
- Measured with built-in analytics
Campaign Types
Basic Campaign
Simple promotional content with messaging and call-to-action.
{
"promotion_type": "basic",
"promotion_properties": {
"title": "Welcome back!",
"subtitle": "Thanks for being a loyal customer",
"cta_label": "Shop Now",
"cta_url": "https://shop.com/featured",
"image_url": "https://shop.com/banner.jpg"
}
}
Product Campaign
Showcase multiple products with rich metadata.
{
"promotion_type": "product",
"promotion_properties": {
"title": "You might also like",
"products": [
{
"title": "Premium Headphones",
"product_url": "https://shop.com/products/headphones", // Required
"currency": "EUR", // Required
"price": 99.99,
"image_url": "https://shop.com/headphones.jpg",
"category": "new", // "new" or "sale"
"sku": "HEADPHONES-001"
}
]
}
}
Banner Campaign
High-impact promotional banners for sales events.
{
"promotion_type": "banner",
"promotion_properties": {
"title": "BLACK FRIDAY SALE",
"subtitle": "Up to 50% off everything!",
"cta_label": "Shop Sale",
"cta_url": "https://shop.com/sale",
"discount": {
"value": 25,
"value_type": "percentage" // or "fixed"
}
}
}
API Endpoints
Core Concepts
Segmentation
Target specific customer groups using segment identifiers:
{
// Default - all customers
"segment": "default",
// Karla internal segments
"segment": "Karla.vip_customers",
// Platform-specific segments
"segment": "Shopify.tag.wholesale",
"segment": "Klaviyo.list.abandoned_cart",
"segment": "Shopware.segment.b2b_buyers"
}
Segment Format: <source>.[<category>.]?<name>
- source: Platform name (Karla, Shopify, Klaviyo, Shopware)
- category: Optional category (tag, list, segment)
- name: Segment identifier
Campaign Lifecycle
Campaigns automatically transition through status states:
Status | Description | Conditions |
---|---|---|
scheduled | Future campaign | start_date > now |
active | Currently running | start_date <= now <= end_date |
inactive | Ended or disabled | end_date < now OR enabled = false |
Timing Control
{
"enabled": true,
"start_date": "2024-03-15T00:00:00+00:00",
"end_date": "2024-03-31T23:59:59+00:00"
}
Multi-Language Support
Add translations for international audiences:
{
"promotion_properties": {
"title": "Welcome!",
"translations": [
{
"language": "de", // ISO 639-1 code
"values": {
"title": "Willkommen!",
"subtitle": "Schön, dass Sie da sind"
}
}
]
}
}
Code Examples
Create a Basic Campaign
curl -X POST https://api.gokarla.io/v1/shops/your-shop/campaigns \
-u username:api-key \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Campaign",
"segment": "Shopify.tag.new_customers",
"promotion_type": "basic",
"promotion_properties": {
"title": "Welcome to our store!",
"subtitle": "Enjoy 10% off your next order",
"cta_label": "Shop Now",
"cta_url": "https://shop.com"
},
"enabled": true
}'
const response = await fetch(
"https://api.gokarla.io/v1/shops/your-shop/campaigns",
{
method: "POST",
headers: {
Authorization:
"Basic " + Buffer.from("username:api-key").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Welcome Campaign",
segment: "Shopify.tag.new_customers",
promotion_type: "basic",
promotion_properties: {
title: "Welcome to our store!",
subtitle: "Enjoy 10% off your next order",
cta_label: "Shop Now",
cta_url: "https://shop.com",
},
enabled: true,
}),
},
);
List Active Campaigns
curl https://api.gokarla.io/v1/shops/your-shop/campaigns \
-u username:api-key
Update Campaign
curl -X PUT https://api.gokarla.io/v1/shops/your-shop/campaigns/{uuid} \
-u username:api-key \
-H "Content-Type: application/json" \
-d '{
"name": "Updated Campaign",
"enabled": false
}'
Delete Campaign
curl -X DELETE https://api.gokarla.io/v1/shops/your-shop/campaigns/{uuid} \
-u username:api-key
Required Fields
All Campaigns
name
(string): Campaign identifiersegment
(string): Target audiencepromotion_type
(string):basic
,product
, orbanner
promotion_properties
(object): Type-specific properties
Product Campaigns
Each product in the products
array requires:
product_url
(string): Product page URLcurrency
(string): ISO 4217 currency code
Translations
Each translation requires:
language
(string): ISO 639-1 language codevalues
(object): Translated content
Best Practices
API Usage
- Segment Exclusivity: Only one active campaign per segment
- Timezone Handling: Use ISO 8601 format with timezone
- Error Handling: Check for 409 conflicts on segment violations
- Pagination: Use cursor-based pagination for large result sets
Performance
- Image Optimization: Use WebP format, max 500KB
- Product Limits: Maximum 10 products per campaign
- Translation Efficiency: Only translate active content
- Caching: Campaign data cached for 5 minutes
Security
- Authentication: Always use HTTPS with Basic Auth
- URL Validation: Ensure all URLs use HTTPS
- Input Sanitization: HTML tags stripped from text fields
- Rate Limiting: 100 requests per minute per shop
Error Handling
Common error responses:
{
"error": "SEGMENT_CONFLICT",
"message": "An active campaign already exists for segment 'Shopify.tag.vip'"
}
{
"error": "INVALID_SEGMENT",
"message": "Segment format must be: source.category.name"
}
{
"error": "NOT_FOUND",
"message": "Campaign not found"
}
Migration Notes
Deprecated Fields
discount_code
in basic campaigns → usediscount
objectpromotion_end_date
→ useend_date
promotion_start_date
→ usestart_date
Real-World Use Cases
Event-Driven Campaign Automation
Integrate campaigns with your business events to create dynamic, responsive marketing:
1. Post-Purchase Upsell
Trigger campaigns based on purchase behavior:
// When order is fulfilled in your system
async function onOrderFulfilled(order) {
// Check order value and category
if (order.total > 100 && order.category === "electronics") {
// Create premium accessory campaign
await createCampaign({
name: `Premium Accessories - Order ${order.id}`,
segment: `Shopify.tag.order_${order.id}`,
promotion_type: "product",
promotion_properties: {
title: "Complete Your Setup",
products: [
{
title: "Premium Protection Plan",
product_url: "https://shop.com/protection",
currency: "USD",
price: 29.99,
category: "new",
},
{
title: "Extended Warranty",
product_url: "https://shop.com/warranty",
currency: "USD",
price: 49.99,
},
],
},
enabled: true,
start_date: new Date().toISOString(),
end_date: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // 30 days
});
}
}
2. Inventory-Based Campaigns
Automatically promote products based on stock levels:
import requests
from datetime import datetime, timedelta
def check_inventory_and_create_campaigns():
# Get products with low stock
low_stock_products = get_low_stock_products()
if low_stock_products:
campaign_data = {
"name": f"Limited Stock Alert - {datetime.now().strftime('%Y-%m-%d')}",
"segment": "Klaviyo.list.engaged_customers",
"promotion_type": "banner",
"promotion_properties": {
"title": "HURRY! Limited Stock Available",
"subtitle": f"Only {len(low_stock_products)} items left in popular products",
"cta_label": "Shop Now",
"cta_url": "https://shop.com/limited-stock",
"discount": {
"value": 10,
"value_type": "percentage"
}
},
"enabled": True,
"start_date": datetime.now().isoformat(),
"end_date": (datetime.now() + timedelta(days=3)).isoformat()
}
# Create campaign via API
response = requests.post(
'https://api.gokarla.io/v1/shops/your-shop/campaigns',
json=campaign_data,
auth=('username', 'api-key')
)
3. Seasonal Campaign Automation
Schedule campaigns based on calendar events:
const holidayCampaigns = [
{
holiday: "Black Friday",
daysBefore: 7,
duration: 4,
config: {
promotion_type: "banner",
promotion_properties: {
title: "BLACK FRIDAY PREVIEW",
subtitle: "Early access for loyal customers",
discount: { value: 30, value_type: "percentage" },
},
},
},
{
holiday: "Christmas",
daysBefore: 14,
duration: 21,
config: {
promotion_type: "product",
promotion_properties: {
title: "Perfect Christmas Gifts",
products: getGiftProducts(),
},
},
},
];
// Schedule campaigns automatically
holidayCampaigns.forEach((campaign) => {
const startDate = getHolidayDate(campaign.holiday).subtract(
campaign.daysBefore,
"days",
);
const endDate = startDate.add(campaign.duration, "days");
createCampaign({
name: `${campaign.holiday} Campaign ${new Date().getFullYear()}`,
segment: "default",
...campaign.config,
start_date: startDate.toISOString(),
end_date: endDate.toISOString(),
});
});
Advanced Segmentation Strategies
1. Behavioral Segmentation
Create dynamic segments based on customer behavior:
// Example: Target customers based on delivery experience
const segmentStrategies = {
// Customers who experienced delays
"Karla.delivery_delayed": {
campaign: {
promotion_type: "basic",
promotion_properties: {
title: "Sorry for the wait!",
subtitle: "Here's 15% off your next order",
cta_label: "Shop Again",
discount: { value: 15, value_type: "percentage" },
},
},
},
// VIP customers with fast delivery
"Karla.vip_fast_delivery": {
campaign: {
promotion_type: "product",
promotion_properties: {
title: "Exclusive VIP Collection",
products: getPremiumProducts(),
},
},
},
// First-time buyers
"Shopify.tag.first_purchase": {
campaign: {
promotion_type: "basic",
promotion_properties: {
title: "Welcome to our family!",
subtitle: "Get 10% off your second order",
cta_label: "Continue Shopping",
},
},
},
};
2. Multi-Platform Segment Combination
Leverage data from multiple platforms:
# Combine Shopify purchase data with Klaviyo engagement
def create_targeted_campaign(shop_slug):
segments = [
{
"segment": "Shopify.tag.high_value",
"klaviyo_list": "Klaviyo.list.email_engaged",
"campaign_type": "vip_exclusive"
},
{
"segment": "Shopify.tag.dormant_customer",
"klaviyo_list": "Klaviyo.list.win_back",
"campaign_type": "reactivation"
}
]
for seg in segments:
# Check if customer is in both segments
campaign = create_campaign_for_type(seg["campaign_type"])
campaign["segment"] = seg["segment"] # Primary segment
# Add email personalization if in Klaviyo list
if customer_in_segment(seg["klaviyo_list"]):
campaign["promotion_properties"]["subtitle"] = \
"Exclusive offer for our email subscribers"
3. Dynamic Segment Creation
Create segments on-the-fly based on real-time data:
// Create time-sensitive segments
async function createDynamicSegments() {
const now = new Date();
const dayOfWeek = now.getDay();
const hour = now.getHours();
// Weekend shoppers
if (dayOfWeek === 0 || dayOfWeek === 6) {
await createCampaign({
name: "Weekend Special",
segment: "Shopify.tag.weekend_shopper",
promotion_type: "banner",
promotion_properties: {
title: "WEEKEND FLASH SALE",
subtitle: "48 hours only!",
discount: { value: 20, value_type: "percentage" },
},
enabled: true,
end_date: getNextMonday(),
});
}
// Late night shoppers (10 PM - 2 AM)
if (hour >= 22 || hour <= 2) {
await createCampaign({
name: "Night Owl Special",
segment: "Shopify.tag.night_shopper",
promotion_type: "basic",
promotion_properties: {
title: "Night Owl Exclusive",
subtitle: "Free shipping on all orders tonight",
cta_label: "Shop Now",
},
enabled: true,
end_date: getNextMorning(),
});
}
}
Integration Patterns
1. Webhook-Driven Campaigns
React to events in real-time:
// Handle delivery status webhooks
app.post("/webhooks/delivery-status", async (req, res) => {
const { order_id, status, customer_tags } = req.body;
switch (status) {
case "delivered":
// Create satisfaction campaign
await createCampaign({
name: `Post-Delivery - ${order_id}`,
segment: `Shopify.tag.order_${order_id}`,
promotion_type: "basic",
promotion_properties: {
title: "How was your experience?",
subtitle: "Rate us and get 10% off",
cta_label: "Leave Review",
cta_url: `https://shop.com/review?order=${order_id}`,
},
enabled: true,
start_date: new Date().toISOString(),
end_date: addDays(new Date(), 7).toISOString(),
});
break;
case "delayed":
// Create apology campaign
await createCampaign({
name: `Delay Apology - ${order_id}`,
segment: `Shopify.tag.order_${order_id}`,
promotion_type: "banner",
promotion_properties: {
title: "We're Sorry for the Delay",
subtitle: "Here's 20% off your next order",
discount: { value: 20, value_type: "percentage" },
},
enabled: true,
});
break;
}
res.status(200).send("OK");
});
2. A/B Testing Campaigns
Test different campaign strategies:
import random
import uuid
def create_ab_test_campaigns(base_segment):
test_id = str(uuid.uuid4())[:8]
# Variant A: Discount focus
variant_a = {
"name": f"Test {test_id} - Variant A",
"segment": f"{base_segment}_test_{test_id}_a",
"promotion_type": "banner",
"promotion_properties": {
"title": "LIMITED TIME: 25% OFF",
"subtitle": "Shop now and save big!",
"discount": {"value": 25, "value_type": "percentage"}
}
}
# Variant B: Product focus
variant_b = {
"name": f"Test {test_id} - Variant B",
"segment": f"{base_segment}_test_{test_id}_b",
"promotion_type": "product",
"promotion_properties": {
"title": "Recommended for You",
"products": get_personalized_products()
}
}
# Create both campaigns
for variant in [variant_a, variant_b]:
create_campaign(variant)
# Track performance metrics
schedule_performance_check(test_id, days=7)
3. Lifecycle Campaign Automation
Automate campaigns based on customer lifecycle:
const lifecycleCampaigns = {
// Day 1: Welcome
onboarding: {
triggerDay: 1,
campaign: {
segment: "Shopify.tag.new_customer",
promotion_type: "basic",
promotion_properties: {
title: "Welcome aboard!",
subtitle: "Here's what to expect from your order",
},
},
},
// Day 30: Engagement
firstMonth: {
triggerDay: 30,
campaign: {
segment: "Shopify.tag.customer_30_days",
promotion_type: "product",
promotion_properties: {
title: "Based on your purchase",
products: getComplementaryProducts(),
},
},
},
// Day 90: Retention
quarterlyReview: {
triggerDay: 90,
campaign: {
segment: "Shopify.tag.customer_90_days",
promotion_type: "banner",
promotion_properties: {
title: "You're a valued customer!",
subtitle: "Enjoy VIP perks",
discount: { value: 15, value_type: "percentage" },
},
},
},
// Day 180: Win-back
reactivation: {
triggerDay: 180,
campaign: {
segment: "Shopify.tag.inactive_6_months",
promotion_type: "banner",
promotion_properties: {
title: "We miss you!",
subtitle: "Come back for 30% off",
discount: { value: 30, value_type: "percentage" },
},
},
},
};
// Automatically schedule lifecycle campaigns
async function scheduleLifecycleCampaigns(customerId, registrationDate) {
for (const [stage, config] of Object.entries(lifecycleCampaigns)) {
const campaignDate = addDays(registrationDate, config.triggerDay);
await scheduleCampaign({
...config.campaign,
name: `Lifecycle: ${stage} - Customer ${customerId}`,
start_date: campaignDate.toISOString(),
end_date: addDays(campaignDate, 7).toISOString(),
});
}
}
API Reference
For complete API specifications including request/response schemas, see: