Skip to content

Discounts & coupons

A coupon is a reusable discount template. Apply it to a customer or a subscription and the discount flows through to invoices automatically.

Coupon shape

{
"code": "SUMMER25",
"type": "percent",
"amount_off": "25",
"duration": "repeating",
"duration_in_months": 3,
"max_redemptions": 1000,
"applies_to": { "plan_codes": ["pro-monthly-usd"] },
"valid_until": "2026-08-31T23:59:59Z"
}
FieldNotes
typepercent or amount.
amount_offEither a percentage (0–100) or a money amount string.
durationonce, repeating, or forever.
duration_in_monthsRequired when duration: repeating.
max_redemptionsOptional cap across all customers.
applies_toOptional restriction by plan_codes or product_codes.
valid_untilOptional expiry; redemptions after this date fail.

Applying a coupon

To a subscription:

POST /v1/subscriptions/{id}/discounts
{ "coupon_code": "SUMMER25" }

Or at create time:

{
"customer_id": "cus_…",
"plan_code": "pro-monthly-usd",
"coupons": ["SUMMER25"]
}

To a customer (applies to every subscription they own):

POST /v1/customers/{id}/discounts
{ "coupon_code": "PARTNER10" }

Stacking

Multiple discounts apply in a fixed order:

  1. Customer-level coupons.
  2. Subscription-level coupons, in created_at order.
  3. One-off invoice discounts (added directly to a draft invoice).

Each discount applies to the running subtotal after the previous discount, never to the original. A 25% then 10% stack does not equal 35% — it equals 32.5%.

Per-line vs invoice-level

By default, a discount applies to the whole invoice subtotal. To restrict it to specific components, use applies_to.components:

{
"code": "SEATS50",
"type": "percent",
"amount_off": "50",
"applies_to": {
"plan_codes": ["pro-monthly-usd"],
"components": ["seats"]
}
}

The discount is allocated to the matching line items only; tax is recomputed against the discounted amount.

Currency handling

Coupons of type: amount carry an explicit currency. They are only valid on invoices in that currency:

{
"code": "USD10OFF",
"type": "amount",
"amount_off": "10.00",
"currency": "USD"
}

percent coupons are currency-agnostic.

Removing a discount

DELETE /v1/subscriptions/{id}/discounts/{discount_id}

A removed discount stops applying from the next invoice. Already-issued invoices are not changed; if you need to remediate, issue a credit note.

Promo codes vs coupons

A promo code is a public-facing name (SUMMER25, WELCOME) that maps to a coupon. The dashboard lets you create a coupon and one or more promo codes that redeem it. Use promo codes when you want the same discount on multiple campaigns; use a coupon directly when you’ll only use it once.

Common pitfalls

  • A coupon applied to a customer applies to every subscription they ever create. If you want it on one only, apply it at the subscription level.
  • duration: forever means forever for that subscription, not for that customer. Cancel-and-resubscribe loses it.
  • applies_to.plan_codes matches the plan in effect at invoice time. An upgrade to a non-matching plan ends the discount silently.

Webhook events

EventWhen
coupon.created / coupon.updated / coupon.deletedCoupon CRUD.
discount.appliedA coupon redemption attached to a customer or subscription.
discount.removedA discount was detached.
discount.expiredA repeating discount reached its last cycle.