Skip to main content

Promotion Management API

Overview

The Promotion Management API provides a comprehensive set of endpoints for managing promotions in the Nilo platform. This API allows you to create, update, and manage different types of promotions including simple discounts, multiple discounts, individual bonuses, and crossed bonuses.

Understanding Promotions

Promotion Structure

  • Internal Code: Unique identifier for the promotion (same as in your ERP)
  • Name: Descriptive name for the promotion
  • Type: Type of promotion (DISCOUNT_SIMPLE, DISCOUNT_MULTIPLE, BONUS_INDIVIDUAL, BONUS_CROSSED)
  • Status: Enabled/disabled state of the promotion
  • Validity Period: Start and end dates for the promotion
  • Tiers: Conditions for discounts or bonuses (quantity-based or amount-based)
  • Products: Products included in the promotion
  • Groupers: Promotion groupers that determine which stores see the promotion

Promotion Types Mapping

Promotion TypeNilo API TypeEndpoint
Direct Bonus (same product)BONUS_INDIVIDUALPUT /promotion/bonus/individual
Crossed Bonus (different product)BONUS_CROSSEDPUT /promotion/bonus/crossed
Group Discount (product combination)DISCOUNT_MULTIPLEPUT /promotion/discount/multiple
Tiered Simple DiscountDISCOUNT_SIMPLEPUT /promotion/discount/simple
Combos with discountDISCOUNT_MULTIPLEPUT /promotion/discount/multiple
Combos with bonusBONUS_CROSSEDPUT /promotion/bonus/crossed

Important Considerations

Mutually Exclusive Fields

The API defines certain fields as mutually exclusive:

  • Quantity vs Amount condition: Don't send discountTiersData/bonusTierData and discountTiersDataCash/bonusTierDataCash simultaneously
  • Discount type: Specify discountPercentage OR discountAmount, not both

Sending both fields will result in an error.

  1. Tier Types:

    • Quantity-based (discountTiersData/bonusTierData): Discount applies based on quantity purchased (e.g., buy 5+ units get 10% off)
    • Amount-based (discountTiersDataCash/bonusTierDataCash): Discount applies based on purchase amount (e.g., spend $100+ get 10% off)
  2. Discount Configuration:

    • Can be percentage-based (discountPercentage) or fixed amount (discountAmount)
    • Cannot mix percentage and fixed amount in the same tier
    • Multiple tiers can be configured with different thresholds
  3. Image Management:

    • The image field expects a public and accessible URL
    • Nilo will download, store, and distribute through CDN
    • Use high-quality images - optimized versions are auto-generated for different devices
  4. Date Handling:

    • All dates must be in YYYY-MM-DD format
    • Both start and end dates are required
    • End date must be after start date

Single Promotion Operations

Get Promotion Details

GET/promotion/{code}

Retrieve detailed information about a specific promotion.

Path Parameters

ParameterTypeRequiredDescription
codestringYesInternal code of the promotion

Response Example

{
"name": "Summer Sale",
"internalCode": "SUMMER2023",
"title": "Summer Sale",
"enabled": true,
"description": "Summer Sale 20%",
"image": "https://image.jpg",
"start": "2023-06-01",
"end": "2023-08-31",
"type": "DISCOUNT_SIMPLE",
"products": [
{
"internalCode": "PROD123",
"boxRatio": 1
}
],
"discountTiersData": [
{
"min": 1,
"max": 2,
"discountPercentage": 20
}
]
}

Example Usage

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
};

fetch(
"https://tm0cs5kjs6.execute-api.us-east-1.amazonaws.com/dev/promotion/SUMMER2023",
{
method: "GET",
headers: headers,
}
)
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

List All Promotions

GET/promotion

Retrieve a list of all promotions with pagination and filtering support.

Query Parameters

ParameterTypeRequiredDescription
takenumberNoNumber of items per page (default: 50, max: 50)
pagestringNoPage number (default: 1)
cursorstringNoCursor for pagination. First call should pass 0, subsequent calls use the cursor from the last item of the previous response
enabledbooleanNoFilter by enabled status
fromstringNoStart date filter (YYYY-MM-DD)
tostringNoEnd date filter (YYYY-MM-DD)

Create/Update Simple Discount Promotion

PUT/promotion/discount/simple

Create or update a simple discount promotion for a single product with tiered discounts.

Request Body Parameters

ParameterTypeRequiredDescription
namestringYesName of the promotion
internalCodestringYesUnique identifier for the promotion (same as in ERP)
startstringYesStart date (YYYY-MM-DD)
endstringYesEnd date (YYYY-MM-DD)
productsobjectYesProduct included in the promotion
discountTiersDataarrayNo*Quantity-based discount tiers (min, max, discountPercentage OR discountAmount)
discountTiersDataCasharrayNo*Amount-based discount tiers (cashMinAmount, cashMaxAmount, discountPercentage OR discountAmount)
enabledbooleanYesWhether the promotion is active
promotionGrouperCodesarrayNoArray of promotion grouper codes
recommendationThresholdnumberNoThreshold value for the promotion to be suggested to users

*Either discountTiersData OR discountTiersDataCash must be provided, not both.

discountTiersData (quantity-based):

FieldTypeRequiredDescription
minintegerYesMinimum quantity to qualify
maxintegerNoMaximum quantity for this tier
discountPercentagenumberNo*Percentage discount (e.g., 10.5 for 10.5%)
discountAmountnumberNo*Fixed amount discount

discountTiersDataCash (amount-based):

FieldTypeRequiredDescription
cashMinAmountnumberYesMinimum purchase amount to qualify
cashMaxAmountnumberNoMaximum amount for this tier
discountPercentagenumberNo*Percentage discount
discountAmountnumberNo*Fixed amount discount

*Use discountPercentage OR discountAmount, not both.

Request Body Example (Quantity-based)

{
"name": "Summer Sale",
"internalCode": "SUMMER2023",
"start": "2025-06-01",
"end": "2025-08-31",
"products": {
"internalCode": "PROD123",
"boxRatio": 1
},
"discountTiersData": [
{
"min": 1,
"max": 5,
"discountPercentage": 10
},
{
"min": 6,
"max": 10,
"discountPercentage": 15
},
{
"min": 11,
"discountPercentage": 20
}
],
"enabled": true,
"promotionGrouperCodes": ["GROUP1", "GROUP2"],
"recommendationThreshold": 5
}

Request Body Example (Amount-based)

{
"name": "Spend & Save",
"internalCode": "SPEND2025",
"start": "2025-06-01",
"end": "2025-08-31",
"products": {
"internalCode": "PROD123",
"boxRatio": 1
},
"discountTiersDataCash": [
{
"cashMinAmount": 100,
"cashMaxAmount": 500,
"discountPercentage": 5
},
{
"cashMinAmount": 500,
"discountPercentage": 10
}
],
"enabled": true,
"promotionGrouperCodes": ["GROUP1"]
}

Example Usage for Simple Discount Promotion

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};

const data = {
name: "Summer Sale",
internalCode: "SUMMER2023",
start: "2023-06-01",
end: "2023-08-31",
products: {
internalCode: "PROD123",
boxRatio: 1,
},
discountTiersData: [
{
min: 1,
max: 2,
discountPercentage: 10.5,
},
],
enabled: true,
promotionGrouperCodes: ["GROUP1", "GROUP2"],
};

fetch("https://api.nilo.com/promotion/discount/simple", {
method: "PUT",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

Create/Update Multiple Discount Promotion

PUT/promotion/discount/multiple

Create or update a promotion with multiple discount tiers.

Request Body Parameters

ParameterTypeRequiredDescription
namestringYesName of the promotion
internalCodestringYesUnique identifier for the promotion
titlestringNoDisplay title for the promotion
descriptionstringNoDetailed description
imagestringNoURL of promotion image
startstringYesStart date (YYYY-MM-DD)
endstringYesEnd date (YYYY-MM-DD)
productsarrayYesArray of products in promotion
discountTiersDataarrayYesDiscount tiers configuration
enabledbooleanYesWhether the promotion is active

Request Body Example

{
"name": "Bulk Purchase Discount",
"internalCode": "BULK2023",
"title": "Buy More, Save More",
"description": "Progressive discounts on bulk purchases",
"image": "https://example.com/promo.jpg",
"start": "2023-06-01",
"end": "2023-08-31",
"products": [
{
"internalCode": "PROD123",
"boxRatio": 1
},
{
"internalCode": "PROD124",
"boxRatio": 1
}
],
"discountTiersData": [
{
"min": 1,
"max": 5,
"discountPercentage": 10
},
{
"min": 6,
"max": 10,
"discountPercentage": 15
}
],
"enabled": true
}

Example Usage for Multiple Discount Promotion

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};

const data = {
name: "Bulk Purchase Discount",
internalCode: "BULK2023",
title: "Buy More, Save More",
description: "Progressive discounts on bulk purchases",
image: "https://example.com/promo.jpg",
start: "2023-06-01",
end: "2023-08-31",
products: [
{
internalCode: "PROD123",
boxRatio: 1,
},
{
internalCode: "PROD124",
boxRatio: 1,
},
],
discountTiersData: [
{
min: 1,
max: 5,
discountPercentage: 10,
},
{
min: 6,
max: 10,
discountPercentage: 15,
},
],
enabled: true,
};

fetch("https://api.nilo.com/promotion/discount/multiple", {
method: "PUT",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

Create/Update Individual Bonus Promotion

PUT/promotion/bonus/individual

Create or update a buy X get Y promotion for the same product.

Request Body Parameters

ParameterTypeRequiredDescription
namestringYesName of the promotion
internalCodestringYesUnique identifier for the promotion
startstringYesStart date (YYYY-MM-DD)
endstringYesEnd date (YYYY-MM-DD)
productsobjectYesProduct configuration
bonusTierDataobjectYesBonus configuration
enabledbooleanYesWhether the promotion is active

Request Body Example

{
"name": "Buy 2 Get 1 Free",
"internalCode": "B2G1FREE",
"start": "2023-06-01",
"end": "2023-08-31",
"products": {
"internalCode": "PROD123",
"boxRatio": 1
},
"bonusTierData": {
"quantityRequired": 2,
"quantityGiven": 1,
"units": 1
},
"enabled": true
}

Example Usage for Individual Bonus Promotion

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};

const data = {
name: "Buy 2 Get 1 Free",
internalCode: "B2G1FREE",
start: "2023-06-01",
end: "2023-08-31",
products: {
internalCode: "PROD123",
boxRatio: 1,
},
bonusTierData: {
quantityRequired: 2,
quantityGiven: 1,
units: 1,
},
enabled: true,
};

fetch("https://api.nilo.com/promotion/bonus/individual", {
method: "PUT",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

Create/Update Crossed Bonus Promotion

PUT/promotion/bonus/crossed

Create or update a promotion where buying one product gives a bonus of a different product.

Request Body Parameters

ParameterTypeRequiredDescription
namestringYesName of the promotion
internalCodestringYesUnique identifier for the promotion
titlestringNoDisplay title for the promotion
descriptionstringNoDetailed description
imagestringNoURL of promotion image
startstringYesStart date (YYYY-MM-DD)
endstringYesEnd date (YYYY-MM-DD)
productsarrayYesProducts that trigger the bonus
bonusTierDataobjectYesBonus product configuration
enabledbooleanYesWhether the promotion is active

Request Body Example

{
"name": "Buy X Get Y Free",
"internalCode": "CROSSPROMO",
"title": "Special Cross Promotion",
"description": "Buy Product A, Get Product B Free",
"image": "https://example.com/cross-promo.jpg",
"start": "2023-06-01",
"end": "2023-08-31",
"products": [
{
"internalCode": "PRODA",
"boxRatio": 1
}
],
"bonusTierData": {
"quantityRequired": 2,
"quantityGiven": 1,
"productInternalCode": "PRODB",
"units": 1
},
"enabled": true
}

Example Usage for Crossed Bonus Promotion

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};

const data = {
name: "Buy X Get Y Free",
internalCode: "CROSSPROMO",
title: "Special Cross Promotion",
description: "Buy Product A, Get Product B Free",
image: "https://example.com/cross-promo.jpg",
start: "2023-06-01",
end: "2023-08-31",
products: [
{
internalCode: "PRODA",
boxRatio: 1,
},
],
bonusTierData: {
quantityRequired: 2,
quantityGiven: 1,
productInternalCode: "PRODB",
units: 1,
},
enabled: true,
};

fetch("https://api.nilo.com/promotion/bonus/crossed", {
method: "PUT",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

Change Promotion Status

PUT/promotion/{code}/status

Enable or disable a specific promotion.

Path Parameters

ParameterTypeRequiredDescription
codestringYesInternal code of the promotion

Request Body Parameters

ParameterTypeRequiredDescription
enabledbooleanYesNew status for the promotion

Request Body Example

{
"enabled": true
}

Batch Operations

Batch Update Promotions

POST/batch/promotion

Update multiple promotions in a single operation.

Request Body Parameters

ParameterTypeRequiredDescription
upsertobjectNoContains promotions to create or update
removeobjectNoContains promotions to remove

Request Body Example

{
"upsert": {
"discount": {
"simple": [
{
"name": "Simple Discount 1",
"internalCode": "SD1",
"start": "2023-06-01",
"end": "2023-08-31",
"products": {
"internalCode": "PROD1",
"boxRatio": 1
},
"discountTiersData": [
{
"min": 1,
"discountPercentage": 10
}
],
"enabled": true
}
],
"multiple": []
},
"bonus": {
"individual": [],
"crossed": []
}
}
}

Example Usage for Batch Operations

const headers = {
Authorization: "YOUR_AUTH_TOKEN",
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json",
};

const data = {
upsert: {
discount: {
simple: [
{
name: "Simple Discount 1",
internalCode: "SD1",
start: "2023-06-01",
end: "2023-08-31",
products: {
internalCode: "PROD1",
boxRatio: 1,
},
discountTiersData: [
{
min: 1,
discountPercentage: 10,
},
],
enabled: true,
},
],
multiple: [],
},
bonus: {
individual: [],
crossed: [],
},
},
};

fetch("https://api.nilo.com/batch/promotion", {
method: "POST",
headers: headers,
body: JSON.stringify(data),
})
.then((response) => response.json())
.then((result) => console.log(result))
.catch((error) => console.log("error", error));

Batch Update Promotion Groupers

POST/batch/promotion/update/grouper

Add or remove promotion groupers from promotions in bulk. This is useful for changing which stores can see specific promotions.

Request Body Parameters

ParameterTypeRequiredDescription
addobjectNoContains groups to add to promotions
removeobjectNoContains groups to remove from promotions

groups array items:

ParameterTypeRequiredDescription
internalCodestringYesInternal code of the promotion
groupInternalCodestringYesInternal code of the grouper

Request Body Example

{
"add": {
"groups": [
{
"internalCode": "PROMO123",
"groupInternalCode": "GROUP1"
},
{
"internalCode": "PROMO123",
"groupInternalCode": "GROUP2"
}
]
},
"remove": {
"groups": [
{
"internalCode": "PROMO456",
"groupInternalCode": "GROUP3"
}
]
}
}

Response Codes

CodeDescription
202Request accepted, processing initiated
402Bad request

Security

Authentication

All endpoints require two types of authentication:

  • API Key in header: x-api-key
  • Authorization token in header: Authorization

Required Permissions

  • For reading operations: supplier/promotion.read
  • For writing operations: supplier/promotion.write
  • For batch operations: supplier/promotion.bulkwrite