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

# Coupon Endpoints

> Create and manage coupons and the codes buyers type at checkout

A coupon defines a discount — a percentage, or a fixed amount per currency — and how many subscription billing periods it applies to. Every coupon has its own `code` (set it when creating the coupon, or let Pancake generate one), and buyers can type it at checkout. To hand out more codes for the same discount, create [promotion codes](https://docs.waffo.ai/api-reference/endpoints/promotion-codes/overview.md) — up to 20 together with the coupon, and more at any time. A coupon also applies by its ID (`couponId`) on a checkout session. A coupon only limits redemptions by its expiry and total uses; buyer restrictions — buyer emails, uses per buyer and a minimum amount — are set on promotion codes, so the coupon's own code has none.

Coupons belong to a store and to one environment: a coupon created in `test` does not exist in `prod`, and the other way around.

## Coupon Status Values

| Status | Description |
| - | - |
| `active` | Usable at checkout |
| `inactive` | Deactivated. This is permanent — an inactive coupon cannot be reactivated |
| `failed` | Creation failed: the payment provider rejected the coupon or did not confirm it. The codes of the request have been released. Create the coupon again — the same codes can be used |

## Discount Rules

| Rule | Field | Description |
| - | - | - |
| Discount | `discount` | `percentage` (`percentOff`, 0 \< x ≤ 100, up to 2 decimals) or `fixed_amount` (`amountOff` per currency). A fixed-amount coupon does not apply to an order whose currency is not listed — there is no currency conversion |
| Subscription duration | `duration`, `durationInPeriods` | `once` (default), `repeating` (for `durationInPeriods` billing periods) or `forever`. One-time orders are discounted once |
| Products | `productIds` | Limit the coupon to these products. Empty or omitted means the whole store |
| Expiry | `redeemBy` | After this time the coupon can no longer be redeemed, and discounts already attached to subscriptions also end |
| Total uses | `maxRedemptions` | Redemption limit across the coupon's code and all its promotion codes. Refunds do not give uses back |

Only `name` can change after creation. To change the discount, create a new coupon and deactivate the old one.

## Code Format

The same rules apply to coupon codes and promotion codes:

| Rule | Detail |
| - | - |
| Characters | Letters, digits and `-`. No spaces, `_` or other symbols |
| Length | 3–32 characters |
| Case | Case-insensitive. Codes are stored and returned in uppercase (`bf2026` becomes `BF2026`) |
| Uniqueness | Unique among the store's **active** codes in the same environment, across coupons and promotion codes |
| Reuse | Deactivating a coupon or promotion code releases its codes immediately; a new coupon or promotion code can then use them |

## Deactivation

Deactivation is **permanent** — there is no reactivate and no delete. Deactivating a coupon also deactivates all of its promotion codes and releases their codes. Existing orders are not affected. Discounts already attached to subscriptions keep applying until the subscription's next plan change.

## Safe Retries

Send an `X-Idempotency-Key` header (SDK: the `idempotencyKey` option) when you create a coupon, and reuse the same key when you retry. Without a key, a retry after a timeout returns `409` only when you specified the codes (`code` or `promotionCodes[].code`): the first request already created the coupon and took them. If you let Pancake generate the codes, the retry creates a second coupon. See [Errors](https://docs.waffo.ai/api-reference/errors.md) for the key requirements.

## Reading Coupons

These endpoints only write. List and read coupons with [GraphQL](https://docs.waffo.ai/api-reference/endpoints/graphql/overview.md): `coupons`, `couponsCount` and `coupon(id)`; their promotion codes with `promotionCodes` and `promotionCodesCount`.

```graphql theme={"system"}
query Coupons($storeId: String!) {
  coupons(storeId: $storeId, limit: 20, offset: 0, filter: { status: { eq: active } }) {
    id
    name
    code
    status
    timesRedeemed
    promotionCodesCount
  }
  couponsCount(storeId: $storeId, filter: { status: { eq: active } })
}
```

## Endpoints

> **[Create Coupon](https://docs.waffo.ai/api-reference/endpoints/coupons/create-coupon.md)**
>
> Create a coupon with its code and, optionally, its promotion codes.

> **[Update Coupon](https://docs.waffo.ai/api-reference/endpoints/coupons/update-coupon.md)**
>
> Rename a coupon.

> **[Deactivate Coupon](https://docs.waffo.ai/api-reference/endpoints/coupons/deactivate-coupon.md)**
>
> Permanently deactivate a coupon and all of its promotion codes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.