Skip to main content
POST
{promotions_service_api_base_url}
/
promotions
/
company
/
{company_id}
/
campaigns
/
{campaign_id}
/
promotions
Create Promotion
curl --request POST \
  --url 'https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions' \
  --header 'Content-Type: application/json' \
  --data '
{
  "promotion_name": "<string>",
  "promotion_type": "<string>",
  "description": "<string>",
  "promotion_code": "<string>",
  "discount_rules": {
    "discount_value": 123,
    "max_discount_amount": 123,
    "min_purchase_amount": 123,
    "applicable_categories": [
      {}
    ],
    "excluded_items": [
      {}
    ]
  },
  "eligibility_criteria": {
    "customer_segments": [
      {}
    ],
    "first_time_customers_only": true,
    "loyalty_tier_requirements": [
      {}
    ],
    "geographic_restrictions": [
      {}
    ]
  },
  "usage_limits": {
    "total_usage_limit": 123,
    "per_customer_limit": 123,
    "daily_usage_limit": 123
  },
  "schedule": {
    "start_date": "<string>",
    "end_date": "<string>",
    "time_restrictions": {}
  },
  "display_settings": {
    "promotional_message": "<string>",
    "banner_text": "<string>",
    "badge_style": "<string>",
    "priority_level": 123
  },
  "auto_apply": true,
  "stackable": true
}
'
import requests

url = "https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions"

payload = {
"promotion_name": "<string>",
"promotion_type": "<string>",
"description": "<string>",
"promotion_code": "<string>",
"discount_rules": {
"discount_value": 123,
"max_discount_amount": 123,
"min_purchase_amount": 123,
"applicable_categories": [{}],
"excluded_items": [{}]
},
"eligibility_criteria": {
"customer_segments": [{}],
"first_time_customers_only": True,
"loyalty_tier_requirements": [{}],
"geographic_restrictions": [{}]
},
"usage_limits": {
"total_usage_limit": 123,
"per_customer_limit": 123,
"daily_usage_limit": 123
},
"schedule": {
"start_date": "<string>",
"end_date": "<string>",
"time_restrictions": {}
},
"display_settings": {
"promotional_message": "<string>",
"banner_text": "<string>",
"badge_style": "<string>",
"priority_level": 123
},
"auto_apply": True,
"stackable": True
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
promotion_name: '<string>',
promotion_type: '<string>',
description: '<string>',
promotion_code: '<string>',
discount_rules: {
discount_value: 123,
max_discount_amount: 123,
min_purchase_amount: 123,
applicable_categories: [{}],
excluded_items: [{}]
},
eligibility_criteria: {
customer_segments: [{}],
first_time_customers_only: true,
loyalty_tier_requirements: [{}],
geographic_restrictions: [{}]
},
usage_limits: {total_usage_limit: 123, per_customer_limit: 123, daily_usage_limit: 123},
schedule: {start_date: '<string>', end_date: '<string>', time_restrictions: {}},
display_settings: {
promotional_message: '<string>',
banner_text: '<string>',
badge_style: '<string>',
priority_level: 123
},
auto_apply: true,
stackable: true
})
};

fetch('https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'promotion_name' => '<string>',
'promotion_type' => '<string>',
'description' => '<string>',
'promotion_code' => '<string>',
'discount_rules' => [
'discount_value' => 123,
'max_discount_amount' => 123,
'min_purchase_amount' => 123,
'applicable_categories' => [
[

]
],
'excluded_items' => [
[

]
]
],
'eligibility_criteria' => [
'customer_segments' => [
[

]
],
'first_time_customers_only' => true,
'loyalty_tier_requirements' => [
[

]
],
'geographic_restrictions' => [
[

]
]
],
'usage_limits' => [
'total_usage_limit' => 123,
'per_customer_limit' => 123,
'daily_usage_limit' => 123
],
'schedule' => [
'start_date' => '<string>',
'end_date' => '<string>',
'time_restrictions' => [

]
],
'display_settings' => [
'promotional_message' => '<string>',
'banner_text' => '<string>',
'badge_style' => '<string>',
'priority_level' => 123
],
'auto_apply' => true,
'stackable' => true
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions"

payload := strings.NewReader("{\n \"promotion_name\": \"<string>\",\n \"promotion_type\": \"<string>\",\n \"description\": \"<string>\",\n \"promotion_code\": \"<string>\",\n \"discount_rules\": {\n \"discount_value\": 123,\n \"max_discount_amount\": 123,\n \"min_purchase_amount\": 123,\n \"applicable_categories\": [\n {}\n ],\n \"excluded_items\": [\n {}\n ]\n },\n \"eligibility_criteria\": {\n \"customer_segments\": [\n {}\n ],\n \"first_time_customers_only\": true,\n \"loyalty_tier_requirements\": [\n {}\n ],\n \"geographic_restrictions\": [\n {}\n ]\n },\n \"usage_limits\": {\n \"total_usage_limit\": 123,\n \"per_customer_limit\": 123,\n \"daily_usage_limit\": 123\n },\n \"schedule\": {\n \"start_date\": \"<string>\",\n \"end_date\": \"<string>\",\n \"time_restrictions\": {}\n },\n \"display_settings\": {\n \"promotional_message\": \"<string>\",\n \"banner_text\": \"<string>\",\n \"badge_style\": \"<string>\",\n \"priority_level\": 123\n },\n \"auto_apply\": true,\n \"stackable\": true\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions")
.header("Content-Type", "application/json")
.body("{\n \"promotion_name\": \"<string>\",\n \"promotion_type\": \"<string>\",\n \"description\": \"<string>\",\n \"promotion_code\": \"<string>\",\n \"discount_rules\": {\n \"discount_value\": 123,\n \"max_discount_amount\": 123,\n \"min_purchase_amount\": 123,\n \"applicable_categories\": [\n {}\n ],\n \"excluded_items\": [\n {}\n ]\n },\n \"eligibility_criteria\": {\n \"customer_segments\": [\n {}\n ],\n \"first_time_customers_only\": true,\n \"loyalty_tier_requirements\": [\n {}\n ],\n \"geographic_restrictions\": [\n {}\n ]\n },\n \"usage_limits\": {\n \"total_usage_limit\": 123,\n \"per_customer_limit\": 123,\n \"daily_usage_limit\": 123\n },\n \"schedule\": {\n \"start_date\": \"<string>\",\n \"end_date\": \"<string>\",\n \"time_restrictions\": {}\n },\n \"display_settings\": {\n \"promotional_message\": \"<string>\",\n \"banner_text\": \"<string>\",\n \"badge_style\": \"<string>\",\n \"priority_level\": 123\n },\n \"auto_apply\": true,\n \"stackable\": true\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/{{promotions_service_api_base_url}}/promotions/company/{{company_id}}/campaigns/{{campaign_id}}/promotions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"promotion_name\": \"<string>\",\n \"promotion_type\": \"<string>\",\n \"description\": \"<string>\",\n \"promotion_code\": \"<string>\",\n \"discount_rules\": {\n \"discount_value\": 123,\n \"max_discount_amount\": 123,\n \"min_purchase_amount\": 123,\n \"applicable_categories\": [\n {}\n ],\n \"excluded_items\": [\n {}\n ]\n },\n \"eligibility_criteria\": {\n \"customer_segments\": [\n {}\n ],\n \"first_time_customers_only\": true,\n \"loyalty_tier_requirements\": [\n {}\n ],\n \"geographic_restrictions\": [\n {}\n ]\n },\n \"usage_limits\": {\n \"total_usage_limit\": 123,\n \"per_customer_limit\": 123,\n \"daily_usage_limit\": 123\n },\n \"schedule\": {\n \"start_date\": \"<string>\",\n \"end_date\": \"<string>\",\n \"time_restrictions\": {}\n },\n \"display_settings\": {\n \"promotional_message\": \"<string>\",\n \"banner_text\": \"<string>\",\n \"badge_style\": \"<string>\",\n \"priority_level\": 123\n },\n \"auto_apply\": true,\n \"stackable\": true\n}"

response = http.request(request)
puts response.read_body
{
  "promotion_id": "<string>",
  "campaign_id": "<string>",
  "promotion_name": "<string>",
  "promotion_type": "<string>",
  "promotion_code": "<string>",
  "status": "<string>",
  "discount_rules": {},
  "eligibility_criteria": {},
  "usage_limits": {},
  "schedule": {},
  "display_settings": {},
  "performance_metrics": {
    "total_uses": 123,
    "unique_customers": 123,
    "total_discount_given": 123,
    "conversion_rate": 123
  },
  "created_at": "<string>",
  "created_by": "<string>"
}
This endpoint creates promotional offers within campaigns, enabling businesses to offer discounts, special deals, and incentives to drive customer engagement and sales.
Promotions are campaign-specific marketing tools that provide customers with discounts, special offers, or incentives. Each promotion operates within the context of a parent campaign.

Path Parameters

company_id
string
required
The unique identifier of the company creating the promotion
campaign_id
string
required
The unique identifier of the campaign that will contain this promotion

Request Body

promotion_name
string
required
Display name for the promotion (e.g., “Spring Sale 20% Off”)
promotion_type
string
required
Type of promotion: “percentage_discount”, “fixed_amount_discount”, “buy_x_get_y”, “free_shipping”, “bundle_deal”, “loyalty_bonus”
description
string
required
Detailed description of the promotion offer
promotion_code
string
Unique promotional code customers can use (auto-generated if not provided)
discount_rules
object
required
Discount calculation rules and parameters
eligibility_criteria
object
Customer and order eligibility requirements
usage_limits
object
Promotion usage restrictions and limits
schedule
object
required
Promotion timing and availability schedule
display_settings
object
Visual presentation and marketing settings
auto_apply
boolean
default:"false"
Whether to automatically apply the promotion without requiring a code
stackable
boolean
default:"false"
Whether this promotion can be combined with other promotions

Request Example

{
  "promotion_name": "Spring Fresh 20% Off",
  "promotion_type": "percentage_discount",
  "description": "Get 20% off all fresh produce items during our Spring Fresh campaign",
  "promotion_code": "SPRING20",
  "discount_rules": {
    "discount_value": 20,
    "max_discount_amount": 50.00,
    "min_purchase_amount": 25.00,
    "applicable_categories": ["fresh_produce", "organic_items"],
    "excluded_items": ["premium_organics"]
  },
  "eligibility_criteria": {
    "customer_segments": ["regular_customers", "premium_members"],
    "first_time_customers_only": false,
    "loyalty_tier_requirements": ["bronze", "silver", "gold"],
    "geographic_restrictions": ["northeast_region"]
  },
  "usage_limits": {
    "total_usage_limit": 1000,
    "per_customer_limit": 3,
    "daily_usage_limit": 100
  },
  "schedule": {
    "start_date": "2025-04-14T00:00:00.000Z",
    "end_date": "2025-05-14T23:59:59.000Z",
    "time_restrictions": {
      "days_of_week": ["monday", "tuesday", "wednesday", "thursday", "friday"],
      "hours_of_day": {
        "start": "08:00",
        "end": "20:00"
      }
    }
  },
  "display_settings": {
    "promotional_message": "Save 20% on Fresh Spring Produce!",
    "banner_text": "SPRING20 - Fresh Savings All Month Long",
    "badge_style": "seasonal_green",
    "priority_level": 8
  },
  "auto_apply": false,
  "stackable": true
}

Response

promotion_id
string
Unique identifier for the created promotion
campaign_id
string
Parent campaign identifier
promotion_name
string
Display name of the promotion
promotion_type
string
Type of promotion created
promotion_code
string
Promotional code (generated if not provided)
status
string
Current promotion status (“draft”, “scheduled”, “active”, “paused”, “expired”)
discount_rules
object
Complete discount configuration as created
eligibility_criteria
object
Customer eligibility requirements
usage_limits
object
Usage restrictions and current usage statistics
schedule
object
Promotion timing and availability
display_settings
object
Visual presentation configuration
performance_metrics
object
Initial promotion tracking metrics
created_at
string
Timestamp when the promotion was created
created_by
string
User who created the promotion

Response Example

{
  "promotion_id": "promo_spring_001",
  "campaign_id": "1000010",
  "promotion_name": "Spring Fresh 20% Off",
  "promotion_type": "percentage_discount",
  "promotion_code": "SPRING20",
  "status": "scheduled",
  "discount_rules": {
    "discount_value": 20,
    "max_discount_amount": 50.00,
    "min_purchase_amount": 25.00,
    "applicable_categories": ["fresh_produce", "organic_items"],
    "excluded_items": ["premium_organics"]
  },
  "eligibility_criteria": {
    "customer_segments": ["regular_customers", "premium_members"],
    "first_time_customers_only": false,
    "loyalty_tier_requirements": ["bronze", "silver", "gold"],
    "geographic_restrictions": ["northeast_region"]
  },
  "usage_limits": {
    "total_usage_limit": 1000,
    "per_customer_limit": 3,
    "daily_usage_limit": 100,
    "current_usage": {
      "total_used": 0,
      "today_used": 0,
      "remaining_uses": 1000
    }
  },
  "schedule": {
    "start_date": "2025-04-14T00:00:00.000Z",
    "end_date": "2025-05-14T23:59:59.000Z",
    "time_restrictions": {
      "days_of_week": ["monday", "tuesday", "wednesday", "thursday", "friday"],
      "hours_of_day": {
        "start": "08:00",
        "end": "20:00"
      }
    }
  },
  "display_settings": {
    "promotional_message": "Save 20% on Fresh Spring Produce!",
    "banner_text": "SPRING20 - Fresh Savings All Month Long",
    "badge_style": "seasonal_green",
    "priority_level": 8
  },
  "auto_apply": false,
  "stackable": true,
  "performance_metrics": {
    "total_uses": 0,
    "unique_customers": 0,
    "total_discount_given": 0.00,
    "conversion_rate": 0.00
  },
  "created_at": "2025-04-14T01:00:00.000Z",
  "created_by": "marketing_admin_001"
}
Percentage Discounts
  • Most common promotion type
  • Easy for customers to understand
  • Can include maximum discount caps
Fixed Amount Discounts
  • Specific dollar amount off purchase
  • Effective for higher-value items
  • Clear value proposition
Buy X Get Y Promotions
  • Encourage bulk purchases
  • Drive inventory movement
  • Increase average order value
Free Shipping Offers
  • Reduce cart abandonment
  • Increase online conversion rates
  • Often combined with minimum purchase requirements
Bundle Deals
  • Cross-sell related products
  • Increase transaction value
  • Simplify customer decision-making
Loyalty Bonuses
  • Reward repeat customers
  • Increase customer retention
  • Build long-term relationships
Promotion Codes: If no promotion code is provided, the system will auto-generate a unique code based on the promotion name and type. Custom codes must be unique within the company.
Performance Optimization: Set appropriate usage limits to control promotion costs while maximizing customer engagement. Monitor performance metrics to optimize future promotions.

Validation Rules

Naming Requirements
  • Promotion names must be unique within the campaign
  • Names should be descriptive and customer-friendly
  • Maximum length of 100 characters
Discount Rules Validation
  • Percentage discounts must be between 0.01% and 100%
  • Fixed amounts must be positive values
  • Minimum purchase amounts must be greater than discount amounts
Schedule Validation
  • Start date must be in the future or current date
  • End date must be after start date
  • Maximum promotion duration of 365 days
Usage Limits Validation
  • All usage limits must be positive integers
  • Per-customer limits cannot exceed total usage limits
  • Daily limits should consider expected traffic
Code Validation
  • Promotion codes must be alphanumeric
  • Minimum length of 4 characters, maximum of 20
  • Cannot contain profanity or reserved words

Error Responses

Invalid Discount Configuration
{
  "error": "Invalid discount rules",
  "message": "Discount percentage cannot exceed 100%",
  "code": "INVALID_DISCOUNT_RULES"
}
Duplicate Promotion Code
{
  "error": "Promotion code already exists",
  "message": "The promotion code 'SPRING20' is already in use",
  "code": "DUPLICATE_PROMOTION_CODE"
}
Invalid Schedule
{
  "error": "Invalid promotion schedule",
  "message": "End date must be after start date",
  "code": "INVALID_SCHEDULE"
}
Campaign Not Found
{
  "error": "Campaign not found",
  "message": "The specified campaign does not exist or is not accessible",
  "code": "CAMPAIGN_NOT_FOUND"
}
Budget Considerations: Carefully configure usage limits and maximum discount amounts to control promotional costs. Monitor usage patterns to prevent budget overruns.

Best Practices

Strategic Planning
  • Align promotions with business objectives
  • Consider seasonal trends and customer behavior
  • Set realistic but attractive discount levels
Technical Configuration
  • Use meaningful promotion codes
  • Set appropriate usage limits
  • Configure proper eligibility criteria
Performance Monitoring
  • Track key metrics from launch
  • Monitor usage patterns for optimization
  • Adjust limits based on performance
Customer Experience
  • Write clear, compelling promotional messages
  • Ensure easy redemption process
  • Provide transparent terms and conditions
Legal Compliance
  • Include necessary disclaimers
  • Comply with regional promotion regulations
  • Maintain fair and transparent practices