Skip to main content

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. Where trial_period_days comes from
  • Pass trial_period_days on POST /v1/subscriptions to 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).
Two invoices developers care about
  • Trial start (SUBSCRIPTION_TRIAL_START): $0, finalized at subscribe time with the same line-item shape as real advance billing for trial_starttrial_end, but all amounts forced to 0 (preview + integrations). collection_method controls SUCCEEDED vs PENDING here; details in Trial-start invoice.
  • Trial end (SUBSCRIPTION_TRIAL_END): first payable billing window trial_endtrial_end + billing_period. payment_behavior drives failure handling here; details in What happens at trial end.
Typical reasons to use trials
  • 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_start
  • current_period_end = trial_end
After 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 as start_date), period_end = trial_end, matching current_period_* while subscription_status is trialing.
  • Amounts: subtotal, total, amount_due, and each line item amount are 0 after compute. Quantity, price linkage, and display metadata stay, so customers see what will charge later.
  • Subscription status: Remains trialing. SUBSCRIPTION_TRIAL_START does not gate activation. Moving to active still depends on SUBSCRIPTION_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

  1. Define trial_period_days on the plan’s recurring FIXED prices or
  2. Override on POST /v1/subscriptions.
There is no 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: FIXED combinations accept trial_period_days. Usage-only or unsupported tier geometries fail validation upstream.
  • Omitted ⇒ 0. That price contributes no inherited trial.
Response (abbreviated):

Step 2: Create a subscription (trial inherited automatically)

When all recurring fixed prices on a plan share the same trial_period_days, that value is inherited by the subscription automatically. No trial fields are required in the subscription request.
Response (abbreviated; real payloads also include plan, customer, line items with full pricing metadata, and other subscription fields):
Notes on the abbreviated response:
  • subscription_status: "trialing" is the canonical lifecycle enum; the payload may also expose a separate status field (SubscriptionResponse).
  • latest_invoice.billing_reason is SUBSCRIPTION_TRIAL_START on this $0 opening invoice. It stays visible / finalized, not SKIPPED, unlike typical zero-amount SUBSCRIPTION_CREATE invoices.
  • If you use send_invoice instead of charge_automatically, payment_status on that same invoice will usually be PENDING until PSP / outbound sync settles the $0 path.

Overriding trial days at subscription creation

Pass trial_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. When trial_end <= now:
  1. Subscription status changes to incomplete.
  2. Billing anchor resets to trial_end.
  3. A SUBSCRIPTION_TRIAL_END invoice is created covering [trial_end, trial_end + billing_period].
  4. If the invoice amount is zero: subscription immediately converts to active. No payment event needed.
  5. If the invoice amount is non-zero: subscription stays incomplete until 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

Webhooks & Events

Trial → paid conversion:
  • subscription.activated when subscription_status flips trialingactive.
  • Raised after SUBSCRIPTION_TRIAL_END settles (paid) or auto-completes at amount_due = 0 (no PSP event required).
  • SUBSCRIPTION_TRIAL_START emits no subscription.activated. subscription_status remains trialing until SUBSCRIPTION_TRIAL_END finishes, even if the opening invoice shows payment_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.
Example payload shape (truncated; your handler may receive more fields):
For information on configuring webhook endpoints, see Webhooks.

Edge Cases

Best Practices

  • Payment ahead of trial end. You can onboard trialing subscriptions without storing a card, but SUBSCRIPTION_TRIAL_END still expects a collectible path whenever amount_due > 0.
  • send_invoice + outbound PSP sync. Keeps SUBSCRIPTION_TRIAL_START in PENDING until the hosted $0 handshake finishes. Prefer this pattern when the gateway captures cards solely behind invoice artifacts.
  • Pin payment_behavior in production. SUBSCRIPTION_TRIAL_END obeys it when autopay retries fail (allow_incomplete vs default_active, etc.).
  • Split entitlements cleanly. Fire subscription.activated once SUBSCRIPTION_TRIAL_END succeeded (or $0 short-circuit). SUBSCRIPTION_TRIAL_START leaves subscription_status at trialing even when payment_status reads SUCCEEDED.
  • Cheap staging loops. Truly $0 plan prices accelerate trialing → active because SUBSCRIPTION_TRIAL_END can finalize with nothing to capture.
  • Single trial episode. No built-in replay; cancel + recreate is the sanctioned reset.
Configure webhook destinations in Webhooks (events: Webhooks & Events above).