> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexprice.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Apply Coupon to a Subscription

> Link coupons to subscriptions at creation or post-creation. Use subscription phases to schedule discount windows.

You can attach coupons at subscription creation time. For post-creation changes (add, remove, or schedule a future removal), use the subscription modification API.

## Before you start

The coupon must be:

* Status: `active`
* Within its `redeem_after` / `redeem_before` window (if set)
* Below its `max_redemptions` limit (if set)

Validation runs at association time. If any condition fails, you get a validation error before the association is created.

## At subscription creation

Pass coupons in the `subscription_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. Omit `price_id`:

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "<customer_id>",
    "plan_id": "<plan_id>",
    "start_date": "2025-01-01T00:00:00Z",
    "subscription_coupons": [
      {
        "coupon_code": "SUMMER15"
      }
    ]
  }'
```

`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. Set `price_id` to the target price:

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "<customer_id>",
    "plan_id": "<plan_id>",
    "start_date": "2025-01-01T00:00:00Z",
    "subscription_coupons": [
      {
        "coupon_code": "USAGE10",
        "price_id": "<price_id>"
      }
    ]
  }'
```

## Scheduled discounts via phases

Subscription phases are the recommended way to apply time-bounded coupons. Each phase has its own `start_date` and optional `end_date`. Coupons in a phase inherit those dates as their association window.

### Example: introductory discount for Q1 only

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "<customer_id>",
    "plan_id": "<plan_id>",
    "start_date": "2025-01-01T00:00:00Z",
    "phases": [
      {
        "start_date": "2025-01-01T00:00:00Z",
        "end_date": "2025-03-31T23:59:59Z",
        "subscription_coupons": [
          { "coupon_code": "Q1PROMO" }
        ]
      },
      {
        "start_date": "2025-04-01T00:00:00Z"
      }
    ]
  }'
```

The coupon is active during Phase 1 only. Phase 2 has no coupon, so invoices from April onwards are at full price.

### Example: line-item discount scoped to a phase

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "<customer_id>",
    "plan_id": "<plan_id>",
    "start_date": "2025-01-01T00:00:00Z",
    "phases": [
      {
        "start_date": "2025-01-01T00:00:00Z",
        "end_date": "2025-06-30T23:59:59Z",
        "subscription_coupons": [
          {
            "coupon_code": "USAGE10",
            "price_id": "<price_id>"
          }
        ]
      },
      {
        "start_date": "2025-07-01T00:00:00Z"
      }
    ]
  }'
```

## 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 with `type: "coupon"`.

### Add a coupon

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions/<subscription_id>/modify/execute \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "coupon",
    "coupon_params": {
      "action": "add",
      "coupon_code": "<coupon_code>",
      "start_date": "2025-06-01T00:00:00Z",
      "end_date": "2025-08-31T23:59:59Z"
    }
  }'
```

`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`):

```bash theme={null}
{
  "type": "coupon",
  "coupon_params": {
    "action": "add",
    "coupon_code": "<coupon_code>",
    "start_date": "2025-06-01T00:00:00Z",
    "subscription_line_item_id": "<line_item_id>"
  }
}
```

### Remove a coupon

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions/<subscription_id>/modify/execute \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "coupon",
    "coupon_params": {
      "action": "remove",
      "coupon_association_id": "<coupon_association_id>"
    }
  }'
```

Get the `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

```bash theme={null}
curl -X POST https://api.flexprice.io/v1/subscriptions/<subscription_id>/modify/preview \
  -H "x-api-key: <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "coupon",
    "coupon_params": {
      "action": "add",
      "coupon_code": "<coupon_code>",
      "start_date": "2025-06-01T00:00:00Z"
    }
  }'
```

## 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                                    |

At the invoice level, `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

```bash theme={null}
curl "https://api.flexprice.io/v1/subscriptions/<subscription_id>?expand=coupon_associations" \
  -H "x-api-key: <API_KEY>"
```

## 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` |
