Quickstart: Launch Your First Campaign

From configuring a promotion rule to generating 10,000 unique tracking codes — the full setup in 6 steps, in under 10 minutes.

1

Create the Promotion Rule

TypeWhen to useExample
**Percentage**Site-wide sales, seasonal events, category-wide promotions"20% off all hoodies"
**Fixed amount**Predictable margin loss, loyalty rewards, gift-card-style"$10 off any order over $50"
**Tiered spend**Encourage larger basket sizes"$5 off $50, $15 off $100, $40 off $200"
**BOGO**Move inventory, introduce new SKUs alongside bestsellers"Buy 2 t-shirts, get 1 free"
**Free shipping**Reduce cart abandonment"Free shipping over $75"
**Bundle**Combine related SKUs at a discount"Camera + lens + case for $899"
**Threshold**Cart-level rewards that unlock above a minimum"Free gift wrap on orders > $100"
2

Define Eligibility & Targeting

The targeting section restricts who and what the discount applies to. Combine filters for precise reach:

Product targeting:

  • Specific SKUs or product IDs
  • Entire categories or collections
  • Tag-based (new-arrival, clearance, summer-2026)
  • Exclusion lists ("everything except gift cards")

Customer targeting:

  • CRM segments (First-Time Buyers, VIP, At-Risk, Lapsed)
  • Loyalty tier (Bronze and above, Gold only, etc.)
  • Geographic (specific countries, states, or postal codes)
  • Order-history filters ("3+ previous orders", "spent > $500 lifetime")
  • Account age ("new accounts under 30 days")

Channel targeting:

  • Web only, POS only, mobile-app only
  • Specific store locations (multi-store retailers)
  • API / third-party order sources

typescript // Example: VIP-only promotion for a specific category const promo = await aeion.api.post("/v1/discounts/promotions", { name: "VIP Spring Apparel", type: "percentage", value: 25, targeting: { customerSegments: ["vip", "platinum-loyalty"], productCategories: ["apparel", "footwear"], channels: ["web", "mobile"], }, startsAt: "2026-03-01T00:00:00Z", endsAt: "2026-03-31T23:59:59Z", });

3

Configure Stacking & Usage Limits

LimitWhat it capsCommon use
Per-codeTotal times a single code can be redeemedOne-time-use influencer code
Per-customerTimes a single customer can redeem this promotion"First-time-buyer 20%" → 1 per customer
GlobalTotal redemptions across all customers"First 100 to use code SPRING get 50% off"
Per-day / hourTime-windowed redemption rate capFlash-sale rate limiting
Minimum cartDiscount only applies if cart subtotal exceeds threshold"Free shipping over $75"
4

Schedule & Publish

Set start and end dates with minute precision. The engine auto-activates and auto-deactivates without manual intervention — no cron job for you to write.

Recurring schedules (e.g., "Happy Hour every Tuesday 2–5pm"):

typescript const happyHour = await aeion.api.post("/v1/discounts/promotions", { name: "Tuesday Happy Hour", type: "percentage", value: 15, schedule: { recurring: true, daysOfWeek: ["tuesday"], startTime: "14:00", endTime: "17:00", timezone: "America/Los_Angeles", }, });

Geo-aware activation — the timezone field above is per-customer, not per-tenant. A customer in Tokyo sees the happy-hour discount during their Tuesday 14:00–17:00 local; a customer in NYC sees it during theirs. No manual timezone math.

5

Generate Codes (Or Run Automatic)

Automatic promotions — leave the code field empty. The engine evaluates eligibility on every checkout in real-time. Customer sees the discount applied at cart-line and checkout without entering anything.

Single-code promotions — set one human-friendly code. Good for marketing campaigns where the same code is broadcast to many customers.

typescript const broadcastCode = await aeion.api.post("/v1/discounts/promotions", { name: "Newsletter Launch", code: "WELCOME20", type: "percentage", value: 20, });

Bulk code generation — for influencer / affiliate / partner campaigns where you want unique tracking codes. Generate up to 10,000 codes in one call:

```typescript const partnerCampaign = await aeion.api.post("/v1/discounts/promotions", { name: "Influencer Q3 Campaign", type: "percentage", value: 15, codePrefix: "SUMMER-", generateCodes: 10000, usageLimitPerCustomer: 1, });

// Returns: { promotionId, codes: [{code, status, generatedAt, ...}], ... } // Each code is unique, single-use, and tracking-attributable ```

Codes are exported as CSV for partner distribution. Each redemption is logged with the redeeming customer, order, timestamp, and code — full attribution chain.

6

Monitor & Optimize

The Discounts Analytics dashboard (Admin → Commerce → Promotions → Analytics) surfaces:

  • Redemption rate — code usage vs codes distributed
  • Revenue impact — gross sales attributable to the promotion
  • Margin impact — net effect on margin after discount
  • Cohort behavior — do discount-users come back at full price?
  • Per-code performance — for bulk campaigns, which influencer codes drove the most revenue
  • Time-of-day patterns — when redemptions cluster (informs future scheduling)

Set up alerts to fire when:

  • Redemption rate exceeds projection (you may have set the discount too aggressively)
  • Margin impact crosses a threshold (cap your downside before damage is done)
  • A specific code is being abused (e.g., 100+ redemptions on a code meant for one influencer's audience)

Cross-reference with CRM (Admin → CRM → Customer Segments) to see if the discount is attracting your target segment or being absorbed by existing high-value customers.

Integration Recipes

Promotion → CRM segment auto-flag. When a customer redeems a "First-Time Buyer" promotion, the CRM automatically tags them with acquired-via-discount-FY26-Q3 for future retention campaigns. No code required — set up the segment-tag in CRM settings.

Email triggers via Marketing. Schedule a campaign to fire when a promotion launches: marketing.campaign.send subscribes to discounts.promotion.activated. Customers see the discount in their inbox the moment it goes live, without a separate scheduling step.

Loyalty stacking. Loyalty-tier discounts (Gold = 10% off) stack with marketing promotions (SPRING20 = 20% off) by default. Configure the stacking precedence to "additive" (30% off) or "multiplicative" (1 − 0.9 × 0.8 = 28% off) depending on your margin policy.

Affiliates → bulk codes. When a new affiliate joins the Affiliates module, their personal tracking code is auto-generated from the configured discount. Commissions are paid on revenue attributed to that code without any manual setup.

A/B testing promotions. Marketing's Wilson Score A/B engine lets you test two competing promotions on different customer segments. Winner gets auto-promoted to the broader audience based on the lower-bound conversion rate.

Troubleshooting

Discount not applying at checkout. Check (1) promotion is active in the current window, (2) cart meets the minimum threshold, (3) customer matches the targeting segments, (4) no exclusive higher-priority promotion is blocking it. The Admin → Promotions → Test page lets you simulate a cart against any promotion and see the eligibility decision tree.

Customer reports their bulk code was already used. Bulk codes are single-use by default. If a customer redeemed it once and it then says "invalid," they may be trying to redeem on a second order. Check the redemption history for that code (Admin → Promotions → Usage) — you'll see the redemption record with timestamp + order.

Refund processed but discount-usage didn't release. Full refunds release the usage slot automatically. Partial refunds DO NOT — the original promotion stays counted as used. To manually release a usage slot, use the admin Promotion Usage → Reverse action.

Stacking math came out unexpected. The order of operations is: (1) eligibility filter, (2) priority sort, (3) stackable group selection, (4) math application in priority order. If you have BOGO + percentage stacking weirdly, check the priority sort — usually a quick fix.

Bulk code generation timed out. For batches above 10,000 codes, switch to the async API: POST /v1/discounts/promotions/{id}/codes/generate-async queues the generation as a background job and emits discounts.codes.generated when complete.

Frequently Asked Questions

Leave the code field empty. The engine evaluates the cart in real-time on every line-item change. If the customer meets the criteria (cart > $100, lives in eligible region, etc.), the discount is applied to their subtotal and shown clearly in their cart. The customer doesn't need to do anything — the discount appears as "Applied: 20% Loyalty Discount".

Yes. Change Schedule Type to "Recurring", select days of week, hours, and timezone. The discount autonomously activates and deactivates per customer's local time. Useful for "Tuesday lunch specials", "weekend brunch promos", or "every-third-Friday VIP previews".

Because Discounts is natively integrated with Commerce, a full refund automatically releases that usage slot. A partial refund leaves the promotion counted as used — the customer DID complete a transaction with that promotion, even if part was refunded later. The admin can manually reverse a partial-refund's slot if business rules require it.

Yes. Configure an exclusion list of customer IDs or domains (e.g., everything @yourcompany.com) on the promotion. Or target by CRM segment, excluding the `internal-test-accounts` segment. The exclusion applies at eligibility-filter time so QA orders won't burn redemption slots.

Loyalty discounts are first-class promotions in the engine. Stacking precedence is configurable per tenant — most retailers run "loyalty stacks with marketing promotions, BUT loyalty stacks exclusively with itself" (so a Gold customer can use one marketing promo + their tier discount, but not two marketing promos). Configure under Promotions → Settings → Stacking Defaults.

Higher-priority promotion applies first. If both are stackable, the second math runs against the discounted subtotal (multiplicative) or against the original subtotal (additive) depending on the configured stacking-math mode.

Yes. When a customer's cart is within $5 of a "free shipping over $50" threshold, the cart auto-suggests products to push them over. Configurable on the promotion under "Upsell prompt → eligible when cart total in range $X-$Y". Drives 10-15% average uplift in cart size.

Admin → Promotions → Export, choose date range, format (CSV / JSON / Excel). Includes one row per redemption: promotion ID, code, customer, order ID, redeemed-at, gross sale, discount amount, net sale. Finance teams reconcile against the GL via the linked `commerce.order` records.

Yes — admin tool at Promotions → Retroactive Apply. Specify date range and customer filter; the engine simulates applying the promotion against each historical order, calculates the credit owed, and issues either a refund to the original payment method or a store credit. Audit-trail logged.

Ready to optimize your margins?