How to use Polar discounts as retention offers
How to turn Polar discounts into retention offers: discount types and durations, applying one to an active subscription, cancellation reasons, and pitfalls.
A customer about to cancel because of price is one of the few cases where a discount really is the right answer. Polar does not ship a retention offer screen of its own in the docs we reviewed, but it has the pieces to build one: discounts with durations, an API to attach a discount to an active subscription, and cancellation reasons on the subscription.
This guide shows how those pieces fit together, when a discount is the right offer, and the mistakes that turn retention discounts into a permanent price cut. It sticks to Polar’s documentation: discounts, the create discount API reference, manage subscriptions, the update subscription API reference and the webhook events page (all accessed November 2026).
What a Polar discount can be
Polar’s discounts have two types and three durations.
Types
- Percentage: in the API, expressed in basis points. 1,000 basis points is a 10% discount.
- Fixed: a fixed amount off.
Durations (for subscriptions)
| Duration | What it does |
|---|---|
once |
Applies one time |
repeating |
Applies for a set number of months; duration_in_months is required |
forever |
Applies indefinitely |
One-time purchases always apply a discount once, whatever the duration.
Restrictions
From the dashboard or the API, a discount can have:
- A code, if customers should enter it themselves.
- Starts at and ends at dates.
- Maximum redemptions.
- Products it applies to. Leaving this empty applies the discount to every product, including products you create later.
Polar notes that once a discount has been redeemed, its type, duration and amount cannot be changed. Get them right before you use a discount in a live offer.
Applying a discount to an active subscription
This is the key step for retention. Polar’s manage subscriptions guide shows a PATCH to /v1/subscriptions/:id with a discount_id in the body.
- The discount is attached to the active subscription.
- The change applies on the next billing cycle. Polar does not re-bill the current period.
- Passing
nullas thediscount_idremoves the current discount.
Because the change takes effect at the next cycle, say so in the offer: “Your next renewal will be 30% lower” is accurate. “We have refunded 30%” is not.
Knowing why the customer is leaving
A discount only helps when the reason is price. Polar stores the reason on the subscription:
customer_cancellation_reason, with values such astoo_expensive,missing_featuresandother.customer_cancellation_comment, the customer’s free text.
When a customer cancels from the Customer Portal or you cancel through the dashboard or API, Polar’s webhook events page says it sends subscription.updated and subscription.canceled immediately. The subscription keeps its active status with cancel_at_period_end set to true, and only moves to canceled when the period ends. Until then, the customer can undo the cancellation, which sends subscription.uncanceled.
That gives you two moments to make an offer:
- Before the cancellation, in your own app, when the customer clicks “Cancel” and you ask why.
- After a scheduled cancellation, while the subscription is still active, with an email offering the discount and a link to undo the cancellation.
Building the offer step
A simple retention step, in your own app, before the customer reaches Polar’s cancel action:
- Ask for the reason with a short list that maps to Polar’s values (too expensive, missing features, other) plus a free text field.
- If the reason is price, show one offer: for example, 30% off the next three months. Create this discount in advance as a
repeatingpercentage discount withduration_in_monthsset to 3, limited to the relevant products. - If the customer accepts, call the update subscription endpoint with the
discount_id. Confirm the new amount and when it starts. - If the customer declines, cancel. The cancel button must be visible at every step, and a refusal must lead straight to cancellation. See click to cancel rules.
- Record the outcome: reason, offer shown, accepted or declined. Store it next to Polar’s own
customer_cancellation_reason.
For other reasons, a discount is usually the wrong tool. “Missing features” calls for a roadmap note or a follow-up when the feature ships. “Not using it” calls for help or a smaller plan. Our guide on pause vs discount retention offers maps reasons to offers.
Pitfalls to avoid
Forever discounts
A forever retention discount is a permanent price cut for anyone who clicks Cancel. Word spreads. Prefer once or a short repeating discount.
Shared codes
A retention discount with a public code ends up on coupon sites. Apply retention discounts by ID through the API instead of handing out codes, and set maximum redemptions and an end date as a backstop.
Stacking with existing discounts
The update call sets the subscription’s discount_id, so attaching a retention discount can replace a discount the customer already has. Check for an existing discount before you make an offer, or you may raise their price by accident.
Offering the same thing twice
If a customer declined a discount while cancelling, do not send the same discount in the first win-back email. Change the offer or change the message.
Unclear timing
Because the discount starts on the next billing cycle, a customer who expects immediate savings may feel misled. Show the exact next renewal amount and date.
A worked example
Suppose a customer on a monthly plan clicks Cancel and picks “too expensive”.
- Your app shows: “Stay for 30% less on your next 3 renewals. Or cancel now.” Both buttons are equally visible.
- The customer accepts. Your backend calls the update subscription endpoint with the ID of your prepared
repeatingdiscount. - You confirm by email: the current period is unchanged, and the next three renewals are 30% lower, starting on the next billing date.
- You store the reason, the offer and the acceptance.
- Before the discount ends, you decide whether to say anything. A short note that the regular price resumes on a given date avoids a surprise and a possible refund request.
If the customer had declined, your app would cancel the subscription straight away, and Polar would keep it active until the end of the period with cancel_at_period_end set.
Measuring whether it works
For each offer, track:
- How often it was shown, and how often it was accepted.
- Of those who accepted, how many were still subscribed three and six months later.
- Revenue kept versus the discount given.
An offer that many accept but that only delays cancellation by one cycle is a cost, not a save. For the broader picture, see cancel flow best practices and cancellation reasons surveys.
Doing this with NoChurn
NoChurn’s cancel flow asks for the reason and shows a matching offer (a discount, or a pause or plan change where your billing setup supports it), with one-click cancel visible at every step. It runs hosted, or headless through the API so the step fits inside your own app. On Polar, the subscription and billing stay with Polar as merchant of record. Answers feed win-back emails at day 30, 60 and 90 and the churn score. See NoChurn + Polar.