---
title: "Create a coupon"
method: POST
path: "/api/v1/coupons"
tags: ["Coupons"]
---

# Create a coupon

`POST /api/v1/coupons`

## Request body

- CreateCouponRequest
  - `code` string, required
  - `description` string, nullable
  - `discount` union, required
    - PercentageDiscount
      - `percentage` string, required
    - FixedDiscount
      - `amount` string, required
      - `currency` string, required
  - `expires_at` string, date-time, nullable
  - `plan_ids` PlanId[]
  - `recurring_value` integer, nullable
  - `redemption_limit` integer, nullable
  - `reusable` boolean

## Response `201`

Coupon created

- Coupon
  - `archived_at` string, date-time, nullable
  - `code` string, required
  - `created_at` string, date-time, required
  - `description` string, nullable
  - `disabled` boolean, required
  - `discount` union, required
    - PercentageDiscount
      - `percentage` string, required
    - FixedDiscount
      - `amount` string, required
      - `currency` string, required
  - `expires_at` string, date-time, nullable
  - `id` string, MeteroidId, required
  - `plan_ids` PlanId[], required
  - `recurring_value` integer, nullable
  - `redemption_count` integer, required
  - `redemption_limit` integer, nullable
  - `reusable` boolean, required

## Other responses

- `400` — Bad request
- `401` — Unauthorized
- `429` — Too many requests

## Changes

> 54 revisions in range; 1 could not be searched.

- **2026-08-12** (v1) `4e013b4e4a8f` — 2 breaking, 4 info
  - the response property `description` became nullable for the status `201`
  - the response property `description` became optional for the status `201`
  - added the optional property `archived_at` to the response with the `201` status
  - added the required property `created_at` to the response with the `201` status
  - …2 more
- **2026-03-31** (v1) `ee465c53a423` — 3 breaking, 5 info
  - removed `#/components/schemas/CouponPercentageDiscount, #/components/schemas/CouponFixedDiscount` from the `discount` request property `oneOf` list
  - the `discount/oneOf[#/components/schemas/FixedDiscount]/amount` response's property type/format changed from `string`/`decimal` to `string`/`` for status `201`
  - the `discount/oneOf[#/components/schemas/PercentageDiscount]/percentage` response's property type/format changed from `string`/`decimal` to `string`/`` for status `201`
  - mapped value for discriminator key `FIXED` changed from `#/components/schemas/CouponFixedDiscount` to `#/components/schemas/FixedDiscount` for `discount` request property
  - …4 more
- …earlier changes not shown

[Full history](https://skmtc.dev/meteroid-oss/apis/meteroid/changes/api/v1/coupons/post.md)

---

[API](https://skmtc.dev/meteroid-oss/apis/meteroid.md) · [All operations](https://skmtc.dev/meteroid-oss/apis/meteroid/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/meteroid-oss/meteroid/revisions/03f9d8ae5c5e/schema)
