Skip to main content

Promotions Management

ACP supports managing promotion data through the REST API. Promotions can only be submitted via the API; SFTP file upload is not supported.

5.1 Promotion Object

FieldTypeRequiredDescription
idstringYesUnique promotion identifier
titlestringYesPromotion name
descriptionstringNoDetailed promotion description
statusenumYesPromotion status
active_periodDateTimeRangeNoActive time range
benefitsBenefit[]YesList of discount types
applies_toProductTargetNoApplicable product scope
urlURI stringNoPromotion details page URL

Promotion Status

StatusDescription
draftDraft, not yet active
scheduledScheduled, awaiting activation
activeCurrently active
expiredHas expired
disabledManually disabled

Active Time Range

active_period uses the DateTimeRange type, containing start_time and end_time fields:
{
  "active_period": {
    "start_time": "2026-04-01T00:00:00Z",
    "end_time": "2026-04-30T23:59:59Z"
  }
}

Product Targeting

applies_to uses the ProductTarget type to specify which products the promotion applies to:
{
  "applies_to": {
    "product_id": "prod_001",
    "variant_ids": ["var_001_black", "var_001_white"]
  }
}
If variant_ids is not specified, the promotion applies to all variants of that product.

5.2 Three Discount Types

Fixed Amount Discount (AmountOffBenefit)

{
  "type": "amount_off",
  "amount_off": {
    "amount": 1000,
    "currency": "USD"
  }
}
Deducts a fixed amount. The example above represents a $10.00 USD discount (amounts use minor units, i.e., cents).

Percentage Discount (PercentOffBenefit)

{
  "type": "percent_off",
  "percent_off": 20
}
Deducts by percentage. The example above represents a 20% discount.

Free Shipping (FreeShippingBenefit)

{
  "type": "free_shipping"
}
Waives shipping fees. No additional parameters required.

5.3 Complete Promotion Example

{
  "id": "promo_summer_2026",
  "title": "Summer Sale - 25% Off Electronics",
  "description": "All electronics 25% off during summer promotion",
  "status": "scheduled",
  "active_period": {
    "start_time": "2026-06-01T00:00:00Z",
    "end_time": "2026-08-31T23:59:59Z"
  },
  "benefits": [
    {
      "type": "percent_off",
      "percent_off": 25
    }
  ],
  "applies_to": {
    "product_id": "prod_electronics_bundle",
    "variant_ids": ["var_laptop_001", "var_tablet_001"]
  },
  "url": "https://store.example.com/summer-sale"
}

5.4 API Submission

Promotions are upserted via the PATCH endpoint:
PATCH /product_feeds/:feed_id/promotions
Content-Type: application/json
Authorization: Bearer api_key_123

{
  "promotions": [
    {
      "id": "promo_summer_2026",
      "title": "Summer Sale",
      "status": "active",
      "benefits": [
        {
          "type": "percent_off",
          "percent_off": 25
        }
      ]
    }
  ]
}
Matched by id: existing records are updated, non-existing records are created.

5.5 Discounts in Checkout Sessions

When an AI agent creates a Checkout Session, promotion discounts are communicated through the following fields.

Discount Codes

{
  "codes": ["SUMMER25", "WELCOME10"]
}
The codes array contains discount codes provided by the user.

Applied Discounts (AppliedDiscount)

FieldTypeDescription
idstringDiscount identifier
codestringDiscount code
couponCouponCoupon details
amountPriceDiscount amount
automaticbooleanWhether automatically applied
startdatetimeStart time
enddatetimeEnd time
methodenumeach (per-item discount) or across (total discount)
prioritynumberPriority (lower number means higher priority)
allocationsAllocation[]Breakdown allocated to each line item

Coupon Object

{
  "coupon": {
    "name": "Summer 25% Off",
    "percent_off": 25,
    "duration": "repeating",
    "max_redemptions": 1000,
    "times_redeemed": 342
  }
}
Coupons support either percent_off (percentage discount) or amount_off (fixed amount discount) modes.

Rejected Discounts (RejectedDiscount)

If a discount code is invalid or not applicable, it appears in the rejected array:
{
  "rejected": [
    {
      "code": "EXPIRED_CODE",
      "reason": "Coupon has expired"
    }
  ]
}

Complete Discount Structure Example

{
  "codes": ["SUMMER25"],
  "applied": [
    {
      "id": "disc_001",
      "code": "SUMMER25",
      "coupon": {
        "name": "Summer Sale",
        "percent_off": 25
      },
      "amount": {
        "amount": 2500,
        "currency": "USD"
      },
      "automatic": false,
      "method": "across",
      "priority": 1,
      "allocations": []
    }
  ],
  "rejected": []
}

5.6 Best Practices

PracticeDescription
Use stable promotion IDsKeep the ID unchanged when updating promotions
Set explicit time rangesAvoid promotions remaining in active status indefinitely
Update status promptlyMark expired promotions as disabled or expired
Test discount calculationsVerify that minor-unit amount calculations are correct
Specify applicable productsUse applies_to to precisely control promotion scope
Price consistencyPromotion prices must match actual discounts on your website

Next chapter: Chapter 6: Data Quality Best Practices — ID stability, URL conventions, prohibited content