Overview
A trial is a window where customers are on the paid plan schedule but billing has not begun yet in the recurring sense described below. Wheretrial_period_days comes from
- Pass
trial_period_daysonPOST /v1/subscriptionsto override the plan for that subscription only. - Or omit it. Every recurring fixed price on the linked plan contributes the same
trial_period_days(otherwise create fails validation).
- Trial start (
SUBSCRIPTION_TRIAL_START):$0, finalized at subscribe time with the same line-item shape as real advance billing fortrial_start→trial_end, but all amounts forced to0(preview + integrations).collection_methodcontrolsSUCCEEDEDvsPENDINGhere; details in Trial-start invoice. - Trial end (
SUBSCRIPTION_TRIAL_END): first payable billing windowtrial_end→trial_end+billing_period.payment_behaviordrives failure handling here; details in What happens at trial end.
- Product-led growth and self-serve upgrade paths
- Freemium-style evaluation before committing
- Time-boxed enterprise or partner pilots
How It Works
Trial subscriptions move through three statuses:
Period fields while trialing
current_period_start=trial_startcurrent_period_end=trial_end
trial_end, the billing anchor moves to trial_end. The first paid period is full-length: [trial_end, trial_end + billing_period]. There is no shortened first billing period after a trial.
Automation: trial-end processing is handled by Flexprice workflows. No manual cron or API is required for the trial_end transition itself.
Trial-start invoice
Billing reason (API string):SUBSCRIPTION_TRIAL_START.
Applies only when the subscription is created as non-draft trialing (trial window > 0 days).
What you get on create:
- Invoice period:
period_start=trial_start(same asstart_date),period_end=trial_end, matchingcurrent_period_*whilesubscription_statusistrialing. - Amounts:
subtotal,total,amount_due, and each line itemamountare0after compute. Quantity, price linkage, and display metadata stay, so customers see what will charge later. - Subscription status: Remains
trialing.SUBSCRIPTION_TRIAL_STARTdoes not gate activation. Moving toactivestill depends onSUBSCRIPTION_TRIAL_END(or a non-trial create path).
collection_method and payment_behavior
Use these fields deliberately: they clarify how trial start differs from trial end.
On
POST /v1/subscriptions, latest_invoice is this document when subscription_status is trialing.
Configuring a Trial Period
- Define
trial_period_dayson the plan’s recurring FIXED prices or - Override on
POST /v1/subscriptions.
trial_enabled flag. If trial_period_days > 0 after resolve (inherit vs override), the subscription enters trialing; 0 at subscription level disables trial even if the plan carries trial days.
Step 1: Set trial_period_days on the price
Constraints:
- Only
billing_cadence: RECURRING+price_type: FIXEDcombinations accepttrial_period_days. Usage-only or unsupported tier geometries fail validation upstream. - Omitted ⇒
0. That price contributes no inherited trial.
Step 2: Create a subscription (trial inherited automatically)
When all recurring fixed prices on a plan share the sametrial_period_days, that value is inherited by the subscription automatically. No trial fields are required in the subscription request.
plan, customer, line items with full pricing metadata, and other subscription fields):
subscription_status: "trialing"is the canonical lifecycle enum; the payload may also expose a separatestatusfield (SubscriptionResponse).latest_invoice.billing_reasonisSUBSCRIPTION_TRIAL_STARTon this$0opening invoice. It stays visible / finalized, notSKIPPED, unlike typical zero-amountSUBSCRIPTION_CREATEinvoices.- If you use
send_invoiceinstead ofcharge_automatically,payment_statuson that same invoice will usually bePENDINGuntil PSP / outbound sync settles the$0path.
Overriding trial days at subscription creation
Passtrial_period_days in the subscription request to override the plan-level value.
To shorten or lengthen the plan-level trial, pass a positive integer:
What Happens at Trial End
Trial end is detected automatically. Whentrial_end <= now:
- Subscription status changes to
incomplete. - Billing anchor resets to
trial_end. - A
SUBSCRIPTION_TRIAL_ENDinvoice is created covering[trial_end, trial_end + billing_period]. - If the invoice amount is zero: subscription immediately converts to
active. No payment event needed. - If the invoice amount is non-zero: subscription stays
incompleteuntil the invoice is paid.
An
incomplete subscription does not auto-expire. It remains incomplete
until the trial-end invoice is paid or the subscription is cancelled.payment_behavior at trial end:
Credit grants held pending activation are applied automatically when the subscription becomes
active.
API Reference
Price fields
Subscription create fields
Subscription response (trial-related fields)
Webhooks & Events
Trial → paid conversion:subscription.activatedwhensubscription_statusflipstrialing→active.- Raised after
SUBSCRIPTION_TRIAL_ENDsettles (paid) or auto-completes atamount_due = 0(no PSP event required). SUBSCRIPTION_TRIAL_STARTemits nosubscription.activated.subscription_statusremainstrialinguntilSUBSCRIPTION_TRIAL_ENDfinishes, even if the opening invoice showspayment_status: SUCCEEDED.
There is no dedicated
subscription.trialing,
subscription.trial_ended, or subscription.trial_ending webhook.
Use subscription.activated (and your own trial clock if needed) to
detect conversion.Edge Cases
Best Practices
- Payment ahead of trial end. You can onboard trialing subscriptions without storing a card, but
SUBSCRIPTION_TRIAL_ENDstill expects a collectible path wheneveramount_due > 0. send_invoice+ outbound PSP sync. KeepsSUBSCRIPTION_TRIAL_STARTinPENDINGuntil the hosted$0handshake finishes. Prefer this pattern when the gateway captures cards solely behind invoice artifacts.- Pin
payment_behaviorin production.SUBSCRIPTION_TRIAL_ENDobeys it when autopay retries fail (allow_incompletevsdefault_active, etc.). - Split entitlements cleanly. Fire
subscription.activatedonceSUBSCRIPTION_TRIAL_ENDsucceeded (or$0short-circuit).SUBSCRIPTION_TRIAL_STARTleavessubscription_statusattrialingeven whenpayment_statusreadsSUCCEEDED. - Cheap staging loops. Truly
$0plan prices acceleratetrialing → activebecauseSUBSCRIPTION_TRIAL_ENDcan finalize with nothing to capture. - Single trial episode. No built-in replay; cancel + recreate is the sanctioned reset.

