For AI agents and LLMs: a structured documentation index is available at /llms.txt. Every page has a Markdown sibling — append .md to any URL.

Skip to content
Docs

Create and manage discounts

Attract new customers and entice existing ones to upgrade using discounts. They're sometimes called promotions or coupons.

AI summary

Create and apply discounts to checkouts and transactions — choose from percentage, flat amount, or per-unit types, with optional recurrence, usage limits, item restrictions, and discount codes.

  • • Recurring discounts apply to the current and future billing periods; set recur: true and optionally maximum_recurring_intervals to limit how many periods the discount applies.
  • • Flat amount and per-unit (flat_per_seat) discounts are currency-specific — they can only be applied to transactions in the same currency as the discount.
  • • Non-catalog discounts are applied directly to a transaction via the API and are not visible in the dashboard or discount list — use them for one-off, private, or customer-specific offers.

Discounts let you reduce the amount that a customer has to pay. You may run discounts as part of promotions, or as a way to incentivize customers to upgrade or buy more.

How it works

Discounts are applied to the total value of the checkout or transaction. The type of discount determines how the total is impacted.

Percentage

Illustration of an example transaction with a discount applied to the total as a percentage.

A percentage taken from the full value of the checkout or transaction.

Example

If the total is $100 and the discount is 10%, the customer pays $90.

Flat amount

Illustration of an example transaction with a discount applied to the total as a flat amount.

A set amount that's subtracted from the full value of the checkout or transaction.

Example

If the total is $100 and the discount is $20, the customer pays $80.

Per unit amount

Illustration of an example transaction with a discount applied to each unit.

A set amount that's subtracted from each quantity of an item in the checkout or transaction.

Example

If there are 10 items at $10 each and the discount is $5, the customer pays $50.

Redemptions

You can discount a transaction in two ways:

  • Customer applying a discount code
    During checkout, the customer can enter a discount code. You can set whether discounts can be applied at checkout or whether they're turned off when you initialize Paddle.js or open the checkout.
  • Applying a discount to a transaction directly
    You can open a checkout with a discount already applied, or add a discount to any transaction that hasn't yet been billed.

Paddle counts when discounts are redeemed so you can keep track of how many times a discount has been used.

A redemption counts when a transaction is completed, or on the initial application against a subscription.

If a discount is present on a transaction created for subscription renewals, midcycle changes, and one-time charges, this doesn't count as a redemption.

Rules and limits

Discounts in Paddle are flexible and powerful. You can set specific rules and restrictions on how they're applied to a transaction or across multiple transactions to give you the freedom to run promotions and discounts in a way that works for you.

Recurring discounts

By default, discounts are one-time. This means they're only applied on the first transaction or checkout that you add them to.

You can create recurring discounts which apply to the current transaction and future transactions where a customer has a subscription. Discounts can recur forever, or for a number of billing periods you specify.

When recurring discounts start applying to transactions depends on whether a subscription has a trial period:

  • With a trial
    The discount isn't applied to the trial, whether it's free or paid. It's applied after the trial period ends. For example, a recurring discount set for 4x billing periods applies to the first billing period after the trial and the next 3x renewals.
  • Without a trial
    The discount applies immediately. For example, a recurring discount set for 4 billing periods applies to the initial transaction and the next 3 renewals.

In both cases, the discount applies to any subscription changes within those periods.

Usage limits

You can prevent discounts from being valid after certain conditions have been met.

  • Time-based
    Once a set date has passed, the discount can no longer be applied to checkouts or transactions.
  • Amount-based
    Once a discount has been redeemed a certain amount of times, the discount can no longer be applied to checkouts or transactions.

Amount-based limits are a total limit for the discount, rather than a per-customer limit.

Item restrictions

By default, a discount applies to all items on a transaction. You may want a discount to only be applied to specific items at checkout. For example, only annual plans, or specific regional price points.

To do this, you can provide a list of:

  • Products
    Restricts the discount to apply to all prices for that product.
  • Prices
    Restricts the discount to only apply to that specific price for a product.

Checkout restrictions

Customers can apply discounts to checkouts using a discount code. You can assign a discount code, or can have Paddle automatically generate one for you.

However, you may not want customers to be able to apply a discount at checkout. This is useful when you want to control who has access to a discount, like with non-transferable custom discounts only valid for particular customers. To achieve this, you can set a discount to be turned off at checkout.

If discounts aren't enabled for use at checkout, Paddle won't automatically generate a code. The discount can only be applied by passing the discount to the checkout or transaction directly using its id.

Currency restrictions

Discounts for a flat amount or per-seat amount are currency-specific. They have a currency and can only be applied to transactions in the same currency.

For example, you can't apply a flat amount type discount (type: flat) with a currency of USD (currency_code: USD) to a transaction with the currency of GBP (currency_code: GBP).

Discount groups

You can create groups to assign discounts under. Discounts could be categorized by usage or team, like:

  • Marketing and new customer prospects that would be used by the marketing team.
  • Retention or loyalty that would be used by customer service or operational teams.
  • Seasonal promotions or campaigns like Black Friday or Cyber Monday.

This makes your discounts more easily identifiable and easier to manage as your catalog grows or as discounts become redundant.

Non-catalog discounts

When you create a discount, it gets added to your discount catalog. These discounts can be used against any transaction, and at checkout by default. However, you may want to apply a discount to a single transaction which isn't recorded in your catalog.

Catalog discounts

For broadly distributed and repeatable discounts.

When you want to track, report, and attribute performance to the same discount.

When customers need to be able to add discounts at checkout.

For example, you may run a public seasonal promotion like for Black Friday, or allow all users in a specific segment to use a discount like non-profits or new customers.

Non-catalog discounts

For one-off, highly targeted, or private offers.

When a single customer should have access to a discount.

When you have many custom discounts of varying prices and amounts.

For example, you may agree on a discounted price for a specific customer's next transaction to prevent churn, or incentivize them to complete a renewal.

Non-catalog discounts can only be applied directly to a transaction and can't be added by customers using Paddle Checkout. They don't show in the Paddle dashboard or when listing discounts through the API.

Before you begin

To open a checkout with a discount, you'll need to first:

  • Set your default payment link under Paddle > Checkout > Checkout settings > Default payment link.
  • Get your default payment link domain approved, if you're working with the live environment.

Create a discount

Create discounts to add them to your catalog for usage against checkouts and transactions.

  1. Go to Paddle > Catalog > Discounts.
  2. Click New discount
  3. Enter the details for your new discount.
  4. Toggle Recurring discount and select from the dropdown if you want the discount to apply across subsequent transactions.
  5. Select Set an expiration date for the discount if you want to set a date and time the discount is no longer applicable.
  6. Select Limit the number of times this discount can be redeemed if you want to set an amount of redemptions before the discount is no longer applicable.
  7. Toggle Checkout discount code to set a discount code that customers can apply at checkout.
  8. Toggle Limit discount to selected products if you want to select products or prices which the discount should only be applicable to.
  9. Click Save

Illustration of the screen to create discounts in the dashboard, showing the core elements of the discount and a toggle for recurring discounts.

Illustration of the screen to create discounts in the dashboard, showing the core elements of the discount and a toggle for recurring discounts.

Send a POST request to the /discounts endpoint to create a discount.

In your request, include type, amount, and description.

  • For flat or flat_per_seat types, also include currency_code.
  • Optionally set code for customers to use at checkout. If enabled_for_checkout is true and no code is provided, Paddle generates one.
  • Set recur: true to apply the discount to future billing periods; optionally limit recurrences with maximum_recurring_intervals.
  • Set expires_at to expire after a datetime, or usage_limit to expire after a number of redemptions.
  • Use restrict_to with an array of product or price IDs to limit which items the discount applies to.

This example creates a new flat discount called "New Customers." It has a code of NEWCUST which can be applied at checkout to get $5 off every purchase. currency_code is required as the type is flat.

If successful, Paddle responds with a copy of the new discount entity. Paddle creates an id starting with dsc_ for you.

POST /discounts
Request
{
"description": "New Customers",
"type": "flat",
"amount": "500",
"currency_code": "USD",
"code": "NEWCUST"
}
Response (201 Created)
{
"data": {
"id": "dsc_01jz8dxadfqnnv74hymjq6nvkf",
"status": "active",
"description": "New Customers",
"enabled_for_checkout": false,
"code": "NEWCUST",
"type": "flat",
"amount": "500",
"currency_code": "USD",
"recur": false,
"maximum_recurring_intervals": null,
"usage_limit": null,
"restrict_to": null,
"expires_at": null,
"mode": "standard",
"times_used": 0,
"custom_data": null,
"import_meta": null,
"discount_group_id": null,
"created_at": "2025-07-03T15:19:02.831Z",
"updated_at": "2025-07-03T15:19:02.831Z"
},
"meta": {
"request_id": "6d69fd6b-8385-4c20-a401-e0ec1d05a7f7"
}
}

This example creates a new discount called "All orders (10% off)." It recurs for a maximum of 4 billing periods after the first transaction.

If successful, Paddle responds with a copy of the new discount entity. Paddle creates an id starting with dsc_ for you.

POST /discounts
Request
{
"description": "All orders (10% off)",
"type": "percentage",
"amount": "10",
"code": "BF10OFF",
"enabled_for_checkout": true,
"recur": true,
"maximum_recurring_intervals": 3,
"expires_at": "2024-12-03T00:00:00Z",
"discount_group_id": "dsg_01js2gqehzccfkywgx1jk2mtsp"
}
Response (201 Created)
{
"data": {
"id": "dsc_01hv6scyf7qdnzcdq01t2y8dx4",
"status": "active",
"description": "All orders (10% off)",
"enabled_for_checkout": true,
"code": "BF10OFF",
"type": "percentage",
"mode": "standard",
"amount": "10",
"currency_code": null,
"recur": true,
"maximum_recurring_intervals": 3,
"usage_limit": null,
"restrict_to": null,
"expires_at": "2024-12-03T00:00:00Z",
"times_used": 0,
"discount_group_id": "dsg_01js2gqehzccfkywgx1jk2mtsp",
"custom_data": null,
"import_meta": null,
"created_at": "2024-11-28T14:36:14.695Z",
"updated_at": "2024-11-28T14:36:14.695Z"
},
"meta": {
"request_id": "1681f87f-9c36-4557-a1da-bbb622afa0cc"
}
}

This example creates a new discount called "Limited July 2026 Promotion." It's set to expire at the end of July with a maximum of 1000 redemptions before it's invalid. currency_code is required as the type is flat_per_seat.

If successful, Paddle responds with a copy of the new discount entity. Paddle creates an id starting with dsc_ for you.

POST /discounts
Request
{
"description": "Limited July 2025 Promotion",
"type": "flat_per_seat",
"amount": "700",
"currency_code": "USD",
"code": "JULY2025PROMO",
"expires_at": "2026-07-31T23:59:59.999Z",
"usage_limit": 1000
}
Response (201 Created)
{
"data": {
"id": "dsc_01jz8f6p33mpkb9pk83xjx2ba6",
"status": "active",
"description": "Limited July 2025 Promotion",
"enabled_for_checkout": false,
"code": "JULY2025PROMO",
"type": "flat",
"amount": "700",
"currency_code": "USD",
"recur": false,
"maximum_recurring_intervals": null,
"usage_limit": 1000,
"restrict_to": null,
"expires_at": "2026-07-31T23:59:59.999Z",
"mode": "standard",
"times_used": 0,
"custom_data": null,
"import_meta": null,
"discount_group_id": null,
"created_at": "2026-07-03T15:41:38.275Z",
"updated_at": "2026-07-03T15:41:38.275Z"
},
"meta": {
"request_id": "a9f11e36-7b6b-446d-a007-6da676f3ecbf"
}
}

This example creates a new discount called "Annual renewals (20% off)." It's restricted to only be applicable to transactions for annual prices across multiple products, and not available for customers to insert at checkout.

If successful, Paddle responds with a copy of the new discount entity. Paddle creates an id starting with dsc_ for you.

POST /discounts
Request
{
"description": "Annual renewals (20% off)",
"type": "percentage",
"amount": "20",
"enabled_for_checkout": false,
"restrict_to": [
"pri_01jv7cypftwz5da2zxggr6sxfa",
"pri_01jv76qc4e46yxgjksp88y7fpy"
]
}
Response (201 Created)
{
"data": {
"id": "dsc_01jz8fnwmdpq9prsadz7gc4hqb",
"status": "active",
"description": "Annual renewals (20% off)",
"enabled_for_checkout": false,
"code": null,
"type": "percentage",
"amount": "20",
"currency_code": null,
"recur": false,
"maximum_recurring_intervals": null,
"usage_limit": null,
"restrict_to": [
"pri_01jv7cypftwz5da2zxggr6sxfa",
"pri_01jv76qc4e46yxgjksp88y7fpy"
],
"expires_at": null,
"mode": "standard",
"times_used": 0,
"custom_data": null,
"import_meta": null,
"discount_group_id": null,
"created_at": "2025-07-03T15:49:56.493Z",
"updated_at": "2025-07-03T15:49:56.493Z"
},
"meta": {
"request_id": "1c20ae9c-6ba2-4545-a244-716dfc85fe55"
}
}

Apply a discount

Customers can apply discounts to a checkout by using a discount code during their transaction. You can also automatically apply a discount to a checkout when you open it in your frontend, or directly to a transaction using the API.

You can apply non-catalog discounts directly to transactions through the API. Non-catalog discounts are intended as custom, one-off discounts which aren't part of your catalog. They can't be applied at checkout by customers, or applied automatically to a checkout when opened.

You can pass either a discountCode or discountId when opening a Paddle Checkout using Paddle.js.

Pass parameters to the Paddle.Checkout.open() method to prefill those values on a checkout.

Paddle.js example
Paddle.Checkout.open({
settings: {
theme: "light",
locale: "en"
},
discountId: "dsc_01gp0ynsntfpyw2spd2md1wqx1",
items: [
{
priceId: 'pri_01gm81eqze2vmmvhpjg13bfeqg',
quantity: 1
},
{
priceId: 'pri_01gm82kny0ad1tk358gxmsq87m',
quantity: 1
},
{
priceId: 'pri_01gm82v81g69n9hdb0v9sw6j40',
quantity: 1
}
]
});

To learn more, see Paddle.Checkout.open()

You can pass either a discountCode or discountId when opening a Paddle Checkout using Paddle.js.

Add data attributes to your checkout launcher to prefill those values on a checkout.

Checkout launcher element
<a href='#'
class='paddle_button'
data-display-mode='overlay'
data-theme='light'
data-locale='en'
data-discount-id='dsc_01gp0ynsntfpyw2spd2md1wqx1'
data-discount-code='10OFF'
data-items='[
{
"priceId": "pri_01gm81eqze2vmmvhpjg13bfeqg",
"quantity": 1
},
{
"priceId": "pri_01gm82kny0ad1tk358gxmsq87m",
"quantity": 1
},
{
"priceId": "pri_01gm82v81g69n9hdb0v9sw6j40",
"quantity": 1
}
]'
>
Buy now
</a>

To learn more, see HTML data attributes

Send a request to the /transactions endpoint to create a transaction.

In your request, include either a discount_id to apply a discount from your catalog or a discount object with type, amount, description.

Optionally include recur, maximum_recurring_intervals, and restrict_to for a non-catalog discount.

This request creates a new transaction with a discount from your catalog applied using the id of the discount.

If successful, Paddle responds with a copy of the updated transaction entity with the id of the discount as discount_id.

POST /transactions
Request
{
"items": [
{
"quantity": 10,
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke"
}
],
"customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p",
"address_id": "add_01gzkce0amtjsqv8xxd1rv3dna",
"currency_code": "GBP",
"discount_id": "dsc_01gy7qp5pqhnyd22yspwane77h"
}
Response (201 Created)
{
"data": {
"id": "txn_01gzkcdstcwq4cj8waj812v9my",
"status": "ready",
"customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p",
"address_id": "add_01gzkce0amtjsqv8xxd1rv3dna",
"business_id": null,
"custom_data": null,
"origin": "api",
"collection_mode": "automatic",
"subscription_id": null,
"invoice_id": null,
"invoice_number": null,
"billing_details": null,
"billing_period": null,
"currency_code": "GBP",
"discount_id": "dsc_01gy7qp5pqhnyd22yspwane77h",
"created_at": "2025-05-04T12:40:07.834144Z",
"updated_at": "2025-05-04T12:40:07.834144Z",
"billed_at": null,
"items": [
{
"price": {
"id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"description": "Monthly (per seat)",
"name": "Monthly (per seat)",
"product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"tax_mode": "account_setting",
"unit_price": {
"amount": "3000",
"currency_code": "GBP"
},
"unit_price_overrides": [],
"quantity": {
"minimum": 10,
"maximum": 999
},
"status": "active"
},
"quantity": 10
}
],
"details": {
"tax_rates_used": [
{
"tax_rate": "0.2",
"totals": {
"subtotal": "30000",
"discount": "3000",
"tax": "5400",
"total": "32400"
}
}
],
"totals": {
"subtotal": "30000",
"tax": "5400",
"discount": "3000",
"total": "32400",
"grand_total": "32400",
"fee": null,
"credit": "0",
"balance": "32400",
"earnings": null,
"currency_code": "GBP"
},
"adjusted_totals": {
"subtotal": "30000",
"tax": "5400",
"total": "32400",
"grand_total": "32400",
"fee": "0",
"earnings": "0",
"currency_code": "GBP"
},
"payout_totals": null,
"adjusted_payout_totals": null,
"line_items": [
{
"id": "txnitm_01h0qjj0ds7arpp88m5b2c399g",
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"quantity": 10,
"totals": {
"subtotal": "30000",
"tax": "5400",
"discount": "3000",
"total": "32400"
},
"product": {
"id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"name": "ChatApp Pro",
"description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level.",
"tax_category": "standard",
"image_url": "https://twemoji.maxcdn.com/v/latest/72x72/2708.png",
"status": "active"
},
"tax_rate": "0.2",
"unit_totals": {
"subtotal": "3000",
"tax": "540",
"discount": "300",
"total": "3240"
}
}
]
},
"payments": [],
"checkout": {
"url": "https://aeroedit.com/pay?_ptxn=txn_01gzkcdstcwq4cj8waj812v9my"
}
},
"meta": {
"request_id": "415a5995-bece-4775-8fb6-54be15c004d6"
}
}

This request creates a new transaction with a non-catalog discount applied called "Custom loyalty discount", giving 10% off the next 6 billing periods. A currency_code is included on the transaction as the discount type is flat.

If successful, Paddle responds with a copy of the updated transaction entity with the id of the discount as discount_id. Non-catalog discounts still have a discount entity created for them so you can see their details when fetching them through the API. They have a mode of custom.

POST /transactions
Request
{
"items": [
{
"quantity": 10,
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke"
}
],
"customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p",
"address_id": "add_01gzkce0amtjsqv8xxd1rv3dna",
"currency_code": "GBP",
"discount": {
"type": "flat",
"description": "Custom loyalty discount",
"amount": "500",
"recur": true,
"maximum_recurring_intervals": 6
}
}
Response (201 Created)
{
"data": {
"id": "txn_01gzkcdstcwq4cj8waj812v9my",
"status": "ready",
"customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p",
"address_id": "add_01gzkce0amtjsqv8xxd1rv3dna",
"business_id": null,
"custom_data": null,
"origin": "api",
"collection_mode": "automatic",
"subscription_id": null,
"invoice_id": null,
"invoice_number": null,
"billing_details": null,
"billing_period": null,
"currency_code": "GBP",
"discount_id": "dsc_01gy7s3d0n20p1m8b8q8v7e5k4",
"created_at": "2025-05-04T12:40:07.834144Z",
"updated_at": "2025-05-04T12:40:07.834144Z",
"billed_at": null,
"items": [
{
"price": {
"id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"description": "Monthly (per seat)",
"name": "Monthly (per seat)",
"product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"billing_cycle": {
"interval": "month",
"frequency": 1
},
"trial_period": null,
"tax_mode": "account_setting",
"unit_price": {
"amount": "3000",
"currency_code": "GBP"
},
"unit_price_overrides": [],
"quantity": {
"minimum": 10,
"maximum": 999
},
"status": "active"
},
"quantity": 10
}
],
"details": {
"tax_rates_used": [
{
"tax_rate": "0.2",
"totals": {
"subtotal": "30000",
"discount": "500",
"tax": "5900",
"total": "35400"
}
}
],
"totals": {
"subtotal": "30000",
"tax": "5900",
"discount": "500",
"total": "35400",
"grand_total": "35400",
"fee": null,
"credit": "0",
"balance": "35400",
"earnings": null,
"currency_code": "GBP"
},
"adjusted_totals": {
"subtotal": "30000",
"tax": "5900",
"total": "35400",
"grand_total": "35400",
"fee": "0",
"earnings": "0",
"currency_code": "GBP"
},
"payout_totals": null,
"adjusted_payout_totals": null,
"line_items": [
{
"id": "txnitm_01h0qjj0ds7arpp88m5b2c399g",
"price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke",
"quantity": 10,
"totals": {
"subtotal": "30000",
"tax": "5900",
"discount": "500",
"total": "35400"
},
"product": {
"id": "pro_01gsz4t5hdjse780zja8vvr7jg",
"name": "ChatApp Pro",
"description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level.",
"tax_category": "standard",
"image_url": "https://twemoji.maxcdn.com/v/latest/72x72/2708.png",
"status": "active"
},
"tax_rate": "0.2",
"unit_totals": {
"subtotal": "3000",
"tax": "590",
"discount": "50",
"total": "3540"
}
}
]
},
"payments": [],
"checkout": {
"url": "https://aeroedit.com/pay?_ptxn=txn_01gzkcdstcwq4cj8waj812v9my"
}
},
"meta": {
"request_id": "415a5995-bece-4775-8fb6-54be15c004d6"
}
}

See how many times a discount has been redeemed

You may want to understand how many times a discount has been redeemed to understand its performance, track how many usages it has left, or expose it to customers to promote a sense of urgency against a limit to the discount.

You can see this against a discount entity when you fetch or list discounts as times_used. If a discount has a limit, you can compare this to the value of usage_limit to calculate and show how many redemptions are left.

This example is a discount entity with a usage limit for how many times this discount can be redeemed as usage_limit. It shows how many times the discount has been redeemed as times_used.

GET /discounts/{discount_id}
Response (200 OK)
{
"data": {
"id": "dsc_01jxw1svzg816ptbzkzf7w12rw",
"status": "active",
"description": "25% off (All)",
"enabled_for_checkout": true,
"code": "138ETPB5NN",
"type": "percentage",
"amount": "25",
"currency_code": null,
"recur": false,
"maximum_recurring_intervals": null,
"usage_limit": 100,
"times_used": 79,
"restrict_to": null,
"expires_at": null,
"mode": "standard",
"custom_data": null,
"import_meta": null,
"discount_group_id": "dsg_01jxyv6jh22m3bav2e3srk1a2t",
"created_at": "2025-06-16T09:40:51.824Z",
"updated_at": "2025-06-26T13:36:56.314Z"
},
"meta": {
"request_id": "7ba4139f-fc18-412f-b08e-08aabc14fd1c"
}
}

Create a discount group

Discounts can be grouped together to make them easier to manage. For example, you might create a group for your Black Friday discounts, and then add all your Black Friday discounts to the group.

Create a discount group the API in two steps:

  1. Create a discount group
    Build and send a request to create your discount group.
  2. Add discounts to your group
    Update discounts to add them to the group you just created.

Create a discount group

Send a POST request to the /discount-groups endpoint to a create a discount group.

In your request, include a name for the discount group. Make it descriptive, short, and memorable — this isn't shown to customers.

This example creates a discount group called "Black Friday 2024." If successful, Paddle responds with a copy of the new discount group entity. Take the id of the discount group if you want to add a discount to it.

POST /discount-groups
Request
{
"name": "Black Friday 2026"
}
Response (201 Created)
{
"data": {
"id": "dsg_01js2gqehzccfkywgx1jk2mtsp",
"status": "active",
"name": "Black Friday 2026",
"import_meta": null,
"created_at": "2026-11-28T14:36:14.695Z",
"updated_at": "2026-11-28T14:36:14.695Z"
},
"meta": {
"request_id": "1681f87f-9c36-4557-a1da-bbb622afa0cc"
}
}

Add a discount to a discount group

Send a PATCH request to the /discounts/{discount_id} endpoint to add an existing discount to a discount group, or send a POST request to the /discounts endpoint to create a new discount.

Provide the discount_group_id you just created in the payload, with the value of id of the discount group.

This example updates a discount called "All orders (10% off)" to add it to the "Black Friday 2024" discount group. If successful, Paddle responds with a copy of the created or updated discount entity, containing the discount_group_id field.

PATCH /discounts/{discount_id}
Request
{
"discount_group_id": "dsg_01js2gqehzccfkywgx1jk2mtsp"
}
Response (200 OK)
{
"data": {
"id": "dsc_01hv6scyf7qdnzcdq01t2y8dx4",
"status": "active",
"description": "All orders (10% off)",
"enabled_for_checkout": true,
"code": "BF10OFF",
"type": "percentage",
"mode": "standard",
"amount": "10",
"currency_code": null,
"recur": true,
"maximum_recurring_intervals": 3,
"usage_limit": null,
"restrict_to": [
"pro_01gsz4t5hdjse780zja8vvr7jg",
"pro_01gsz4s0w61y0pp88528f1wvvb"
],
"expires_at": "2024-12-03T00:00:00Z",
"times_used": 0,
"discount_group_id": "dsg_01js2gqehzccfkywgx1jk2mtsp",
"custom_data": null,
"import_meta": null,
"created_at": "2024-11-28T14:36:14.695Z",
"updated_at": "2024-11-28T14:38:12.331Z"
},
"meta": {
"request_id": "dd850364-99f7-4e27-bb1e-0a477bdb320b"
}
}

Events

discount.created Occurs when a discount is created.
discount.updated

Occurs when a discount is updated.

Payload includes the complete discount entity, except times_used. This field changes frequently, so isn't included in payloads. Get a discount using the API to see the latest value.

discount_group.created Occurs when a discount group is created.
discount_group.updated Occurs when a discount group is updated.
transaction.created Occurs when a transaction is created initially with a discount.
transaction.updated Occurs when a discount is applied to an existing transaction.

Common errors

discount_expired
You are trying to apply a discount which has passed its expiration date.
discount_usage_limit_exceeded
You are trying to apply a discount which has exceeded the maximum usage limit.
discount_code_conflict
Each of your Discounts must have a unique code, the requested code is in conflict with another Discount.
transaction_requires_currency_code_for_custom_discount
You are trying to create a transaction with a custom discount that requires a currency_code to be included.

Was this page helpful?