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

# Create a Coupon

> Creates a coupon — the discount definition that promotional codes are built on.

Only `name` is required. Set `couponType` to `PERCENTAGE` and supply `percentOff` (1–100), or set it to `FLAT` and supply both `amountOff` and `currency`. When `couponType` is omitted the coupon is stored as `PERCENTAGE`, so send `percentOff` alongside it.

`duration` controls how long the discount keeps applying to a subscription: `once`, `forever` (the default here), or `repeating` — which additionally requires `durationInMonths`.

Fires the `coupon.created` webhook.

## Creating Coupons

Create a new coupon definition that can be used to generate promotional codes for your affiliates.

### Coupon Types

* **PERCENTAGE**: Discount based on a percentage (e.g., 20% off)
* **FLAT**: Fixed amount discount (e.g., \$10 off)

### Duration Options

* **once**: Applies to a single payment
* **forever**: Applies to all future payments
* **repeating**: Applies for a specific number of months

<Note>
  After creating a coupon, you'll need to create promotional codes linked to
  this coupon. Promotional codes are the actual discount codes that customers
  will enter at checkout.
</Note>


## OpenAPI

````yaml POST /coupons
openapi: 3.0.1
info:
  title: Referly API
  description: >-
    REST API for managing affiliates, referrals, sales, affiliate links, coupons
    and promotional codes in your Referly affiliate program.


    Every request must send `Authorization: Bearer <YOUR_API_KEY>`. The token is
    scoped to a single affiliate program, so no program ID is ever required in
    the request — every read and write is automatically limited to that program.


    Requests are rate limited per token, per endpoint and per method.
  version: 1.0.0
servers:
  - url: https://www.referly.so/api/v1
security:
  - bearerAuth: []
paths:
  /coupons:
    post:
      summary: Create a coupon
      description: >-
        Creates a coupon — the discount definition that promotional codes are
        built on.


        Only `name` is required. Set `couponType` to `PERCENTAGE` and supply
        `percentOff` (1–100), or set it to `FLAT` and supply both `amountOff`
        and `currency`. When `couponType` is omitted the coupon is stored as
        `PERCENTAGE`, so send `percentOff` alongside it.


        `duration` controls how long the discount keeps applying to a
        subscription: `once`, `forever` (the default here), or `repeating` —
        which additionally requires `durationInMonths`.


        Fires the `coupon.created` webhook.
      requestBody:
        description: The coupon to create
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewCoupon'
        required: true
      responses:
        '200':
          description: The created coupon.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Coupon'
        '400':
          description: >-
            `name` was missing; `couponType` is `PERCENTAGE` and `percentOff` is
            missing or outside 1–100; `couponType` is `FLAT` and `amountOff` or
            `currency` is missing; `duration` is `repeating` and
            `durationInMonths` is missing; or a coupon with this `externalId`
            already exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/ProgramNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          description: The coupon could not be created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    NewCoupon:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: Name of the coupon
          example: Launch 20%
        couponType:
          type: string
          enum:
            - PERCENTAGE
            - FLAT
          default: PERCENTAGE
          description: Whether the discount is a percentage or a fixed amount
        percentOff:
          type: number
          format: float
          description: >-
            Percentage taken off, 1–100. Required when `couponType` is
            `PERCENTAGE`.
        amountOff:
          type: number
          format: float
          description: Fixed amount taken off. Required when `couponType` is `FLAT`.
        currency:
          type: string
          description: Currency for `amountOff`. Required when `couponType` is `FLAT`.
          example: USD
        duration:
          type: string
          enum:
            - once
            - forever
            - repeating
          default: forever
          description: How long the discount keeps applying to a subscription
        durationInMonths:
          type: integer
          description: >-
            Number of months the discount repeats for. Required when `duration`
            is `repeating`.
        maxRedemptions:
          type: integer
          description: >-
            Total redemptions allowed across every promotional code on this
            coupon. Omit for unlimited.
        limitToProducts:
          type: boolean
          default: false
          description: Restrict the coupon to `productIds`
        productIds:
          type: array
          items:
            type: string
          description: Products the coupon applies to
        valid:
          type: boolean
          default: true
          description: Whether the coupon can be redeemed straight away
        redeemBy:
          type: string
          format: date-time
          description: Last date the coupon can be redeemed
        externalId:
          type: string
          description: The coupon's ID in the connected billing provider. Must be unique.
        integrationType:
          type: string
          enum:
            - NONE
            - STRIPE
            - CHARGEBEE
            - PADDLE
            - SHOPIFY
            - WOOCOMMERCE
            - ZYLVIE
            - POLAR
          description: The billing provider this coupon is synced with
    Coupon:
      type: object
      description: >-
        A discount definition. Promotional codes point at a coupon for their
        value.
      properties:
        id:
          type: string
          format: uuid
          description: The coupon ID
        name:
          type: string
          nullable: true
          description: Name of the coupon
        externalId:
          type: string
          nullable: true
          description: >-
            The coupon's ID in the connected billing provider, for example a
            Stripe coupon ID
        couponType:
          type: string
          enum:
            - PERCENTAGE
            - FLAT
          description: Whether the discount is a percentage or a fixed amount
        percentOff:
          type: number
          format: float
          nullable: true
          description: Percentage taken off, 1–100. Used when `couponType` is `PERCENTAGE`.
        amountOff:
          type: number
          format: float
          nullable: true
          description: Fixed amount taken off. Used when `couponType` is `FLAT`.
        currency:
          type: string
          nullable: true
          description: Currency for `amountOff`, for example `USD`
        duration:
          type: string
          enum:
            - once
            - forever
            - repeating
          description: How long the discount keeps applying to a subscription
        durationInMonths:
          type: integer
          nullable: true
          description: >-
            Number of months the discount repeats for. Only set when `duration`
            is `repeating`.
        maxRedemptions:
          type: integer
          nullable: true
          description: >-
            Total redemptions allowed across every promotional code on this
            coupon. `null` means unlimited.
        timesRedeemed:
          type: integer
          description: How many times this coupon has been redeemed so far
        couponCategory:
          type: string
          enum:
            - CUSTOMER
            - PAYOUT
          description: >-
            Whether the coupon discounts customers or is used to pay affiliates
            as a non-cash reward
        limitToProducts:
          type: boolean
          description: Whether the coupon only applies to `productIds`
        productIds:
          type: array
          items:
            type: string
          description: Products the coupon is restricted to
        collectionIds:
          type: array
          items:
            type: string
          description: Collections the coupon is restricted to
        valid:
          type: boolean
          description: Whether the coupon can currently be redeemed
        redeemBy:
          type: string
          format: date-time
          nullable: true
          description: Last date the coupon can be redeemed
        integrationType:
          type: string
          enum:
            - NONE
            - STRIPE
            - CHARGEBEE
            - PADDLE
            - SHOPIFY
            - WOOCOMMERCE
            - ZYLVIE
            - POLAR
          nullable: true
          description: The billing provider this coupon is synced with
        affiliateProgramId:
          type: string
          format: uuid
          description: The affiliate program this coupon belongs to
        createdAt:
          type: string
          format: date-time
          description: When the coupon was created
        updatedAt:
          type: string
          format: date-time
          description: When the coupon was last updated
        promotionalCodes:
          type: array
          items:
            $ref: '#/components/schemas/PromotionalCode'
          description: Promotional codes that point at this coupon
        autoCouponRule:
          type: object
          nullable: true
          description: >-
            Rule used to generate codes automatically for affiliates, if
            configured
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human readable description of what went wrong
    PromotionalCode:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The promotional code ID
        code:
          type: string
          description: The actual promotional code string
        couponId:
          type: string
          format: uuid
          description: The parent coupon ID
        affiliateId:
          type: string
          format: uuid
          nullable: true
          description: The affiliate ID this code is assigned to
        externalId:
          type: string
          nullable: true
          description: External ID (e.g., Stripe promotion code ID)
        active:
          type: boolean
          description: Whether the promotional code is active
        expiresAt:
          type: string
          format: date-time
          nullable: true
          description: Expiration date for the code
        maxRedemptions:
          type: integer
          nullable: true
          description: >-
            How many times this code can be redeemed. `null` means unlimited.
            Redemptions are also capped by the parent coupon's own limit.
        timesRedeemed:
          type: integer
          description: Number of times this code has been redeemed
        firstTimeOrder:
          type: boolean
          description: Whether this code is limited to first-time orders
        minimumAmount:
          type: number
          format: float
          nullable: true
          description: Minimum purchase amount required
        minimumAmountCurrency:
          type: string
          nullable: true
          description: Currency for minimum amount
        limitToCustomers:
          type: boolean
          description: Whether code is limited to specific customers
        customerId:
          type: string
          nullable: true
          description: Specific customer ID this code is limited to
        limitToAffiliate:
          type: boolean
          description: Whether only the assigned affiliate may redeem this code
        isAutoGenerated:
          type: boolean
          description: >-
            Whether this code was generated from a `codeStructure` rather than
            supplied by hand
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the code was created
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the code was last updated
        coupon:
          description: The coupon this code takes its discount from
          allOf:
            - $ref: '#/components/schemas/Coupon'
        affiliate:
          type: object
          nullable: true
          properties:
            id:
              type: string
              format: uuid
            firstName:
              type: string
            lastName:
              type: string
            email:
              type: string
              format: email
          description: Affiliate details
        isAffiliateGenerated:
          type: boolean
          description: Whether the affiliate created this code themselves from their portal
      description: >-
        A code customers enter at checkout. Its discount comes from the coupon
        it belongs to.
  responses:
    Unauthorized:
      description: >-
        The `Authorization` header is missing, is not a `Bearer` header, or the
        token is not valid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: API access is not enabled for this account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ProgramNotFound:
      description: The affiliate program this token belongs to no longer exists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Too many requests for this token on this endpoint. Please slow down.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````