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

# Create Coupon

> Creates a coupon.

<RequestExample>
  ```bash Create Coupon theme={"system"}
  curl -X POST \
    'https://api.appcharge.com/coupons/coupon' \
    -H 'Content-Type: application/json' \
    -H 'x-publisher-token: <x-publisher-token>' \
    -d '{
      "name": "summer26",
      "discountPercentage": 10,
      "maxRedemptionsPerCustomer": 2,
      "allowedPlayers": ["player123", "player456", "player789"],
      "supportedOfferExternalIds": ["bundle1", "rollingoffer3"],
      "expiredBy": "2025-04-02T06:54:51.670Z",
      "startsAt": "2025-02-02T06:54:51.670Z"
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json Create Coupon theme={"system"}
  {
      "name": "summer26",
      "active": true,
      "discountPercentage": 10,
      "maxRedemptionsPerCustomer": 2,
      "expiredBy": "2025-04-02T06:54:51.670Z",
      "startsAt": "2025-02-02T06:54:51.670Z",
      "supportedOfferExternalIds": ["bundle1", "rollingoffer3"],
      "firstTimePurchase": false,
      "allowedPlayers": ["player123", "player456", "player789"]
  }
  ```

  ```json 400 theme={"system"}
  {
      "error": "Invalid coupon name. Use only English letters and numbers."
  }
  ```

  ```json 400 theme={"system"}
  {
      "error": "Missing required field: discountPercentage."
  }
  ```

  ```json 400 theme={"system"}
  {
      "error": "startsAt must be in the future."
  }
  ```

  ```json 400 theme={"system"}
  {
      "error": "expiredBy must be after startsAt."
  }
  ```

  ```json 400 theme={"system"}
  {
      "error": "discountPercentage must be between 1 and 99."
  }
  ```

  ```json 409 theme={"system"}
  {
      "error": "Coupon name 'summer26' is already in use"
  }
  ```

  ```json 500 theme={"system"}
  {
      "error": "Unexpected error. Please contact support."
  }
  ```
</ResponseExample>


## OpenAPI

````yaml openapi-coupons.json post /coupons/coupon
openapi: 3.0.3
info:
  title: Coupons API
  version: 1.0.0
servers:
  - url: https://api.appcharge.com
security:
  - PublisherTokenAuth: []
tags:
  - name: Coupons
  - name: Promo Codes
paths:
  /coupons/coupon:
    post:
      tags:
        - Coupons
      description: Creates a coupon.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCouponRequest'
      responses:
        '200':
          description: Coupon created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CouponResponse'
        '400':
          description: Bad request. Invalid input or validation failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalidCouponName:
                  summary: Invalid coupon name
                  value:
                    error: Invalid coupon name. Use only English letters and numbers.
                missingRequiredField:
                  summary: Required field missing
                  value:
                    error: 'Missing required field: discountPercentage.'
                startsAtInPast:
                  summary: startsAt is in the past
                  value:
                    error: startsAt must be in the future.
                expiredByBeforeStartsAt:
                  summary: expiredBy is before startsAt
                  value:
                    error: expiredBy must be after startsAt.
                discountPercentageOutOfRange:
                  summary: discountPercentage out of range
                  value:
                    error: discountPercentage must be between 1 and 99.
        '409':
          description: Conflict. A coupon with the same name already exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                couponExists:
                  summary: Coupon name already in use.
                  value:
                    error: Coupon name 'summer26' is already in use.
        '500':
          description: Unexpected error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                unexpectedError:
                  summary: Unexpected error
                  value:
                    error: Unexpected error. Please contact support.
components:
  schemas:
    CreateCouponRequest:
      type: object
      properties:
        name:
          type: string
          description: Coupon name. Can't contain spaces or special characters.
          example: summer26
        discountPercentage:
          type: number
          description: Discount percentage applied by the coupon.
          example: 1
        active:
          type: boolean
          description: Whether the coupon is active.
          default: true
          example: true
        maxRedemptionsPerCustomer:
          type: integer
          description: Maximum number of times a customer can redeem this coupon.
          example: 2
        expiredBy:
          type: string
          format: date-time
          description: Expiration date of the coupon.
          example: '2025-04-02T06:54:51.670Z'
        startsAt:
          type: string
          format: date-time
          description: >-
            Start date of the coupon validity. If not provided, defaults to
            current date and time.
          example: '2025-02-02T06:54:51.670Z'
        supportedOfferExternalIds:
          type: array
          items:
            type: string
          description: >-
            List of offer IDs which this coupon applies. Empty array means all
            offers are supported. 

             **Note:** This represents both the `offer.sku` value in the [Create Checkout Session API](../checkout-session/create-checkout-session), and the `publisherOfferId` in the [Offers V2 API](../../webstore/offers-v2/introduction).
          example:
            - bundle1
            - rollingoffer3
        firstTimePurchase:
          type: boolean
          description: Whether the coupon is only valid for first-time purchases.
          default: false
          example: false
        allowedPlayers:
          type: array
          items:
            type: string
          description: List of player IDs that can redeem this coupon.
      required:
        - name
        - discountPercentage
    CouponResponse:
      $ref: '#/components/schemas/Coupon'
    Error:
      type: object
      properties:
        error:
          type: string
          description: Error message describing what went wrong.
    Coupon:
      type: object
      properties:
        name:
          type: string
          description: Coupon name.
          example: summer26
        active:
          type: boolean
          description: Whether the coupon is active.
          example: true
        discountPercentage:
          type: number
          description: Discount percentage applied by the coupon.
          example: 1
        maxRedemptionsPerCustomer:
          type: integer
          description: Maximum number of times a customer can redeem this coupon.
          example: 2
        expiredBy:
          type: string
          format: date-time
          description: Expiration date of the coupon.
          example: '2025-04-02T06:54:51.670Z'
        startsAt:
          type: string
          format: date-time
          description: Start date of the coupon validity.
          example: '2025-02-02T06:54:51.670Z'
        supportedOfferExternalIds:
          type: array
          items:
            type: string
          description: >-
            List of offer external IDs that support this coupon. Empty array
            means all offers are supported.
          example:
            - bundle1
            - rollingoffer3
        firstTimePurchase:
          type: boolean
          description: Whether the coupon is only valid for first-time purchases.
          example: false
        allowedPlayers:
          type: array
          items:
            type: string
          description: >-
            List of player IDs allowed to use this coupon. Empty array means all
            players are allowed.
          example:
            - player123
            - player456
            - player789
  securitySchemes:
    PublisherTokenAuth:
      type: apiKey
      in: header
      name: x-publisher-token
      description: Publisher token, as displayed in the Publisher Dashboard.

````