Easy Labs
SDKsNode.jsResources

Promotion Codes

Promotion Codes — methods, parameters, and examples for @easylabs/node.

Promotion codes are the buyer-facing strings ("SPRING25") that resolve to a coupon. One coupon can have multiple codes (e.g. campaign- or partner-specific), each with its own redemption limits, expiry, and eligibility rules.

Methods

easy.createPromotionCode(body);                // POST   /promotion-codes
easy.listPromotionCodes(params?);              // GET    /promotion-codes
easy.getPromotionCode(promotionCodeId);        // GET    /promotion-codes/:id
easy.updatePromotionCode(promotionCodeId, body); // PATCH  /promotion-codes/:id
easy.deletePromotionCode(promotionCodeId);     // DELETE /promotion-codes/:id
easy.validatePromotionCode(body);              // POST   /promotion-codes/validate
const promo = await easy.createPromotionCode({
  coupon_id: coupon.data.id,
  code: "SPRING25",
  active: true,
  max_redemptions: 500,
  valid_until: "2026-06-30T23:59:59Z",
  first_time_only: true,
  minimum_amount: 5000,        // require $50 minimum cart
  metadata: { campaign: "spring_2026" },
});

UpdatePromotionCode is narrow: only active and metadata are mutable. To change the coupon, code, or redemption rules, create a new promotion code.

Validation

validatePromotionCode previews whether a code would apply for a given customer / amount before you let them apply it. Returns { valid, promotion_code?, coupon?, discount_preview?, reason? }:

const { data } = await easy.validatePromotionCode({
  code: userInput,
  identity_id: customer.id,    // optional
  amount: cartTotalCents,      // optional
});

if (!data.valid) {
  throw new Error(data.reason ?? "Invalid promo code");
}
console.log(data.discount_preview); // { amount_off } or { percent_off }

The corresponding redemption happens when you call applySubscriptionDiscount(subId, { promotion_code: "SPRING25" }).

Object shape

PromotionCodeData:

FieldTypeNotes
idstring
coupon_idstringThe coupon this code resolves to.
codestringThe buyer-facing string.
activeboolean
max_redemptionsnumber | nullPer-code cap.
times_redeemednumber
valid_untilstring | nullISO timestamp.
first_time_onlybooleanIf true, only redeemable on a customer's first subscription.
minimum_amountnumber | nullSmallest currency unit.
metadataRecord<string, unknown>

Examples

Validate-then-apply at checkout

const validation = await easy.validatePromotionCode({
  code: input,
  identity_id: customer.id,
  amount: cart.totalCents,
});
if (!validation.data.valid) return reply.code(400).send({ error: validation.data.reason });
await easy.applySubscriptionDiscount(subId, { promotion_code: input });

Disable a code mid-campaign

await easy.updatePromotionCode(promoId, { active: false });

Per-partner unique codes

const codes = ["PARTNERA", "PARTNERB", "PARTNERC"];
for (const code of codes) {
  await easy.createPromotionCode({
    coupon_id: couponId,
    code,
    metadata: { partner: code.toLowerCase() },
  });
}

On this page