v1

latestOpenAPI 3.0.02026-07-2475182625.5 KB
Coupons

Create or update a coupon

Creates a new coupon or updates an existing one. The operation is determined automatically based on whether the coupon path identifier already exists — no separate update endpoint is required.

The action field in the response confirms which operation was performed: coupon.create or coupon.update.

Warning: Including the codes array in an update request permanently replaces all existing codes. Omit the codes field to preserve existing codes.

post/coupons

Request body

couponstring required

Unique coupon path identifier. Accepts alphanumeric characters, hyphens, and underscores only.

orderLevelDiscountboolean

(Beta) Applies the discount to the entire order subtotal rather than individual line items. The discount is proportionally allocated across eligible items, excluding add-ons and fees. Taxes are calculated after the discount is applied.

This field is part of the closed, invite-only Order-Level Coupons beta. Only accounts enrolled in the beta can set this field to true.

When true, the following values are server-enforced regardless of what is sent in the request:

FieldEnforced value
combinetrue
applyDiscountImmediatelytrue
discountPeriodCount1

The discount.type must be flat when orderLevelDiscount is true.

hasMultiDiscountboolean

Enables multi-tier discount mode for tiered subscription offers. When true, the discounts array is required in place of the discount object. Cannot be true if orderLevelDiscount is true.

discountPeriodCountinteger

Number of billing periods the discount applies to. Accepts values from 0 to 365. 0 is treated as unlimited and stored as null in the response.

Ignored and forced to 1 when orderLevelDiscount is true.

applyDiscountImmediatelyboolean

Applies the discount starting in the first billing period rather than the next renewal period. Requires a feature flag on your account.

Ignored and forced to true when orderLevelDiscount is true.

combineboolean

Allows this discount to stack with other active discounts. Forced to true when orderLevelDiscount is true.

autoSelectDiscountboolean

Automatically selects the most favorable discount for the customer when multiple discounts are applicable. Only applies when combine is false. Requires a feature flag on your account.

Note: This field is accepted without error but has no effect until the feature flag is enabled. It is not returned in GET responses.

limitinteger

Maximum number of times this discount can be applied across all customers and codes. 0 means unlimited.

Note: This value is returned as a string in GET responses. 0 sent → "" received. Both represent unlimited.

codesstring[]

Coupon codes that activate this discount at checkout.

Code handling

  • Case: Codes are normalized to uppercase on storage. summer10 and SUMMER10 are stored as the same code.
  • Duplicates: Duplicate codes within this array are accepted without error and echoed verbatim in the response, but storage silently dedupes (case-insensitively) to a single entry per unique code. Call GET /coupons/{coupon_id}/codes after the write to confirm the stored state.
  • Format: Alphanumeric characters, hyphens, and underscores only. Spaces and other special characters are rejected.
productsstring[]

Product path identifiers this discount applies to. An empty array applies the discount to all eligible products.

Example request

{
  "coupon": "summer-sale-2026",
  "orderLevelDiscount": true,
  "discount": {
    "type": "percent",
    "percent": 25,
    "amount": {
      "USD": 10,
      "EUR": 9,
      "GBP": 8
    }
  },
  "discounts": [
    {
      "type": "percent",
      "percent": 50,
      "products": [
        "pro-plan-annual"
      ],
      "discountPeriodCount": 3,
      "applyDiscountImmediately": true
    },
    {
      "type": "percent",
      "percent": 25,
      "products": [
        "pro-plan-monthly"
      ],
      "discountPeriodCount": 6,
      "applyDiscountImmediately": false
    }
  ],
  "discountPeriodCount": 3,
  "applyDiscountImmediately": true,
  "autoSelectDiscount": true,
  "reason": {
    "en": "50% off for your first 3 months",
    "de": "50% Rabatt für die ersten 3 Monate"
  },
  "limit": 500,
  "available": {
    "start": "2026-06-01",
    "end": "2026-08-31"
  },
  "codes": [
    "SUMMER10",
    "SUMMER20"
  ],
  "products": [
    "pro-plan-monthly",
    "pro-plan-annual"
  ]
}

Response

Returned for both successful operations and validation errors. Always check the result field to determine the outcome.

OR

Example response

{
  "coupon": "summer-sale-2026",
  "action": "coupon.create",
  "result": "success"
}