Before you start
The coupon must be:- Status:
active - Within its
redeem_after/redeem_beforewindow (if set) - Below its
max_redemptionslimit (if set)
At subscription creation
Pass coupons in thesubscription_coupons array. Each entry takes a coupon_code (the human-readable code from the coupon object), optional start_date/end_date, and an optional price_id to target a specific line item.
Subscription-level coupon
Discounts the full invoice subtotal. Omitprice_id:
start_date defaults to the subscription start date. end_date is optional: omit it to let the coupon run until its own cadence ends or the subscription cancels.
Line-item coupon
Discounts one specific price in the plan only. Setprice_id to the target price:
Scheduled discounts via phases
Subscription phases are the recommended way to apply time-bounded coupons. Each phase has its ownstart_date and optional end_date. Coupons in a phase inherit those dates as their association window.
Example: introductory discount for Q1 only
Example: line-item discount scoped to a phase
Common scheduling patterns
| Goal | Phase configuration |
|---|---|
| Discount for first 3 months | Phase 1: end_date = 3 months out, coupons: [id]. Phase 2: no coupon. |
| Discount starting 6 months in | Phase 1: no coupon. Phase 2: start_date = 6 months in, coupons: [id]. |
| Remove a discount on a known future date | Phase 1: today to removal date with coupon. Phase 2: from removal date, no coupon. |
| Discount on one charge only | In subscription_coupons, set price_id to the target price ID. |
Add or remove a coupon after subscription creation
Use the subscription modification API withtype: "coupon".
Add a coupon
start_date defaults to now if omitted. end_date is optional: omit it to apply the coupon indefinitely.
To target a specific line item instead of the full invoice, add subscription_line_item_id (mutually exclusive with subscription_id):
Remove a coupon
coupon_association_id from the subscription response with expand=coupon_associations.
Removal affects only invoices generated after the request. Previously issued invoices are not changed.
Preview before executing
subscription_coupons fields (at creation)
| Field | Type | Required | Description |
|---|---|---|---|
coupon_code | string | Yes | The coupon’s code value (case-insensitive) |
start_date | timestamp | No | When the association starts. Defaults to the subscription or phase start date. |
end_date | timestamp | No | When the association ends. Omit for indefinite. |
price_id | string | No | Target a specific line item. Omit for subscription-level. |
coupon_params fields (post-creation modification)
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | add or remove |
coupon_code | string | When action=add | Code of the coupon to attach |
coupon_association_id | string | When action=remove | ID of the coupon association to detach |
start_date | timestamp | No | When the association starts. Defaults to now. |
end_date | timestamp | No | When the association ends. Omit for indefinite. |
subscription_line_item_id | string | No | Target a specific line item. Mutually exclusive with subscription_id. |
How discounts appear on invoices
Discount amounts are tracked at two levels on each line item:| Field | Description |
|---|---|
line_item_discount | Discount applied directly to this line item (from a line-item coupon targeting this price) |
invoice_level_discount | Invoice-wide coupon discount prorated to this line item |
total_discount is the sum of all coupon discounts across all line items.
The discount terms are snapshotted when the coupon is applied, so they are preserved even if the coupon definition is later updated.
Check active coupons on a subscription
Validation errors
| Error | Cause |
|---|---|
coupon_not_active | Coupon is not in active status |
coupon_expired | Current time is after redeem_before |
coupon_not_yet_valid | Current time is before redeem_after |
max_redemptions_reached | total_redemptions >= max_redemptions |

