Stripe's Trial Offers API Just Reached GA. The Setting It Shipped With Can Quietly Move Your Customer's Renewal Date.
Stripe's item-level Trial Offers API hit GA on Sept 30. One setting decides if a trial conversion resets your renewal date or just prorates it.
Stripe's September 30 Endive release took Trial Offers out of preview and into general availability — a feature that's been quietly sitting at 2026-03-25.preview since March. It lets you put a trial on a single subscription item instead of an entire subscription: trial an AI credits pack for 14 days while the base plan keeps billing, then roll that one item onto its regular price. The API is clean. The part that'll actually decide how your customers experience the conversion is a single nested setting most teams will never read the docs page for.
Trial mechanics aren't a niche corner of subscription billing — they're something close to a universal entry point. That's exactly why a setting that changes what happens the moment a trial converts deserves more attention than a changelog line item usually gets. Get it wrong and you're not debugging an edge case; you're shipping a confusing invoice to most of your customer base at some point in their lifecycle.
What Trial Offers actually does
A ProductCatalog.TrialOffer object specifies a price to charge during the trial and a price to charge after it ends, plus a duration — either a fixed end timestamp or a number of billing intervals. You assign it to a subscription item with the new current_trial parameter, either when creating the item or updating an existing one. Stripe's own framing for the use case is specific: sell an add-on, an AI credits pack, or a feature bundle with its own trial, layered onto a subscription that's already billing for something else.
That's a meaningfully different shape than the trial_period_days or trial_end fields most SaaS products already use on Subscription#create. Those trial the whole subscription — nothing gets invoiced until the trial ends, full stop. Trial Offers trials one line item while the rest of the subscription keeps billing on schedule. If you've read our guide to mixed interval subscriptions, this will feel familiar: Stripe keeps shipping features that let one subscription contain several independently-timed billing behaviors, and each one adds a new way for a single invoice to contain pieces a customer reads as separate transactions in their head, even though Stripe treats them as one object.
The setting that decides what the conversion invoice looks like
Here's the part worth sitting with. Alongside Trial Offers, Stripe added a new parameter: trial_settings.end_behavior.billing_cycle_anchor. It governs what happens to the subscription's billing date the instant a trial-offer item rolls onto its regular price.
Leave it on the default, now, and the subscription's billing_cycle_anchor resets to the moment the trial ends. Every item on the subscription — not just the one that was trialing — gets re-anchored to a new cycle starting right then, and the next invoice is the full regular amount with no proration involved. Set it to unchanged instead, and the original anchor date stays exactly where it was before the trial ever started. The gap between the trial ending and the next time that original anchor date rolls around gets billed as a prorated partial-period charge.
billing_cycle_anchor: now → anchor resets to the 24th. Full invoice, no proration — but next month's charge now lands on the 24th, not the 1st.
billing_cycle_anchor: unchanged → anchor stays on the 1st. Invoice for the 24th–30th gap is a 7-day prorated line item.
Neither option is wrong. They're two different trade-offs, and Stripe doesn't pick one for you beyond the default. now gives you a clean, round invoice amount — but it moves the date your customer has mentally filed away as "when I get charged," for the whole subscription, not just the item that was trialing. unchanged preserves the date they expect, at the cost of handing them exactly the kind of oddly-sized prorated line item we've written about before — a number that's mathematically correct and reads as a mistake anyway.
| end_behavior setting | What happens to the anchor | Customer-visible risk |
|---|---|---|
| now (default) | Subscription's billing_cycle_anchor resets to the trial-end timestamp | Renewal date silently moves — next month's charge lands on a day they don't expect |
| unchanged | Original anchor date is preserved exactly as it was | Partial-period proration charge for the trial-end-to-anchor gap, with an odd dollar amount |
| Either setting | Only the trial-offer item's price actually changes at trial end | If support doesn't know which setting is active, they can't explain the invoice that follows |
Why this reaches further than one add-on's billing line
The detail that makes this worth a full post rather than a release note: billing_cycle_anchor is a subscription-level field. A trial you placed on a single $19 add-on item can reset the renewal date for the customer's entire subscription — base plan, seats, every other line item included — the moment that one trial completes. If a customer added the add-on mid-cycle without paying close attention to when its trial would end, the first they'll hear about their renewal date moving is the next invoice itself.
That's a genuinely different failure mode than classic proration confusion, where at least the charge amount is the only surprise. Here the date moves. A customer who built a mental model of "I get charged on the 1st" and is now getting charged on the 24th has no obvious way to tell that apart from a billing error — and per our coverage of Stripe's newer pause and resume endpoints, which touch this same billing_cycle_anchor field from a different angle, this is becoming one of the more consequential knobs in Stripe's subscription model precisely because so many newer features now route through it.
Source: Chargebacks911, 2025 Cardholder Dispute Index (1,200+ cardholders, US/UK)
That last number is the one that should worry anyone shipping a trial-to-paid conversion they haven't fully mapped out: a meaningful share of cardholders already say they'd rather have their bank handle a cancellation than deal with the merchant directly. A renewal date that moves without warning is precisely the kind of event that pushes someone toward their bank's dispute button instead of your support inbox or your cancellation flow — and once it's a chargeback instead of a cancellation, you've lost the chance to offer a save at all.
What to actually set, and what to build around it
Pick the setting based on what you're trialing, not the default
If the trialed item is a small, optional add-on and the base subscription is the thing your customer actually tracks the renewal date for, unchanged is usually the safer choice — it keeps the date they know about stable and confines the surprise to a prorated line item, which is a narrower, more explainable problem than a moved renewal date. If the add-on effectively is the subscription, or you're comfortable re-anchoring because every item converts around the same time anyway, now gives you a cleaner invoice at the cost of a date shift you need to actively communicate.
Preview the invoice before the trial ends, not after
Stripe's upcoming invoice endpoint will return the post-trial amount and the resulting billing period before the conversion happens. There's no good reason for a customer to learn their renewal date changed from the invoice itself — surface it in-app a few days before the trial-offer item converts, with the actual next charge date and amount, the same way you'd want to flag a price increase before it hits.
Give trial-offer conversions their own tag in dunning and churn reporting
A cancellation or dispute that lands within a few days of a trial-offer item converting is a different signal than one that lands mid-cycle with no billing event nearby. If your dunning and churn tooling can't separate "this invoice followed a trial conversion with a changed anchor date" from an ordinary renewal, you'll keep attributing this churn to generic price sensitivity or product dissatisfaction instead of the actual, fixable trigger: a billing surprise with a name and a root cause. Our churn calculator is a quick way to see how much a few percentage points of this kind of preventable churn is actually worth chasing down.
None of this requires avoiding Trial Offers — item-level trials on add-ons are a genuinely useful way to let customers try an expansion item without committing to it blind. It just means the end_behavior choice deserves the same deliberate attention you'd give a pricing page, not the Stripe default left untouched because nobody noticed it existed. And if a trial conversion does send someone to your cancel page confused about why their bill or their date changed, that's exactly the moment a CancelFlow cancellation flow earns its keep — surfacing the actual reason for the charge before offering a discount nobody asked for.
Frequently asked questions
What is Stripe's Trial Offers API?+
Trial Offers is a Stripe API object that lets you set a different price on an individual subscription item during a trial period and a separate price for after the trial ends, with the trial's length set either as a fixed end date or a number of price intervals. You attach it to a specific line item with the current_trial parameter, which is what makes it different from the trial_period_days field most SaaS products already use — that older field trials an entire subscription, not one item within it.
How is an item-level trial offer different from a normal Stripe trial?+
A normal Stripe trial (trial_period_days or trial_end) delays the first invoice for the whole subscription — every item on it is free until the trial ends. Trial Offers work at the subscription-item level instead, so you can trial a single add-on or usage-based line item — an AI credits pack, a premium module — while every other item on the same subscription keeps billing normally the whole time. It's built for upsell and expansion pricing, not for a product's main free trial.
What does trial_settings.end_behavior.billing_cycle_anchor actually control?+
It decides what happens to the subscription's overall billing date the moment a trial offer item converts to its regular price. Set to now (the default), the subscription's billing_cycle_anchor resets to that exact moment, every item re-anchors to a fresh cycle, and the next invoice is a full, non-prorated charge. Set to unchanged, the original anchor date stays put, and the gap between the trial ending and the next natural anchor gets billed as a prorated partial-period charge instead.
Do I need to migrate my existing free trials to Trial Offers?+
No. Trial Offers and trial_period_days solve different problems and can run side by side — trial_period_days for your standard signup trial, Trial Offers for item-level introductory pricing on an add-on or expansion item you sell into an existing subscription. There's no deprecation here, and most SaaS products using a simple whole-account free trial have no reason to touch this API at all.
Stop losing subscribers today
One script tag. One function call. A live cancellation flow in under 10 minutes.
Start free trial →