Skip to main content

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.

Basic Campaign Structure
{
"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.

Product Campaign Structure
{
"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"
}
]
}
}

High-impact promotional banners for sales events.

Banner Campaign Structure
{
"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:

Segment Format
{
// 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:

StatusDescriptionConditions
scheduledFuture campaignstart_date > now
activeCurrently runningstart_date <= now <= end_date
inactiveEnded or disabledend_date < now OR enabled = false

Timing Control

Campaign Scheduling
{
"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:

Translation Structure
{
"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
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
}'
Node.js
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
curl https://api.gokarla.io/v1/shops/your-shop/campaigns \
-u username:api-key

Update Campaign

cURL
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
curl -X DELETE https://api.gokarla.io/v1/shops/your-shop/campaigns/{uuid} \
-u username:api-key

Required Fields

All Campaigns

  • name (string): Campaign identifier
  • segment (string): Target audience
  • promotion_type (string): basic, product, or banner
  • promotion_properties (object): Type-specific properties

Product Campaigns

Each product in the products array requires:

  • product_url (string): Product page URL
  • currency (string): ISO 4217 currency code

Translations

Each translation requires:

  • language (string): ISO 639-1 language code
  • values (object): Translated content

Best Practices

API Usage

  1. Segment Exclusivity: Only one active campaign per segment
  2. Timezone Handling: Use ISO 8601 format with timezone
  3. Error Handling: Check for 409 conflicts on segment violations
  4. Pagination: Use cursor-based pagination for large result sets

Performance

  1. Image Optimization: Use WebP format, max 500KB
  2. Product Limits: Maximum 10 products per campaign
  3. Translation Efficiency: Only translate active content
  4. Caching: Campaign data cached for 5 minutes

Security

  1. Authentication: Always use HTTPS with Basic Auth
  2. URL Validation: Ensure all URLs use HTTPS
  3. Input Sanitization: HTML tags stripped from text fields
  4. Rate Limiting: 100 requests per minute per shop

Error Handling

Common error responses:

409 Conflict - Segment Already Used
{
"error": "SEGMENT_CONFLICT",
"message": "An active campaign already exists for segment 'Shopify.tag.vip'"
}
400 Bad Request - Invalid Segment
{
"error": "INVALID_SEGMENT",
"message": "Segment format must be: source.category.name"
}
404 Not Found
{
"error": "NOT_FOUND",
"message": "Campaign not found"
}

Migration Notes

Deprecated Fields

  • discount_code in basic campaigns → use discount object
  • promotion_end_date → use end_date
  • promotion_start_date → use start_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:

After Order Fulfillment
// 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:

Low Stock Alert Campaign
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:

Holiday Campaign Scheduler
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:

Behavior-Based Targeting
// 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:

Cross-Platform Segmentation
# 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:

Dynamic Segmentation
// 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:

Webhook Integration
// 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:

A/B Testing Implementation
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:

Customer Lifecycle Campaigns
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: