Pricing Phases
Breeze's pricing phases let a single subscription bill through an ordered list of prices before settling on its default price — the top-level priceId on the subscription. Each phase bills its own amount and interval for a fixed number of billing cycles; once every phase is exhausted, billing continues at that default price.
Phases cover introductory pricing, step-up (or step-down) pricing, and multi-stage promotions. The whole schedule is declared once, at creation — a live subscription cannot be re-priced — and Breeze advances to the next phase as it generates each invoice.
How It Works
A phase is a cycleCount plus a price. The price is either a reference to an existing recurring price on the same product (priceId) or an inline price defined in the request (price) — exactly one of the two per phase.
Prices are snapshotted at creation: the amount and billing cycle stored on the subscription are the ones used for billing, so later edits to a referenced price do not change an existing subscription.
Billing walks the phases in order:
| Step | Behavior |
|---|---|
| First charge | The invoice created with the subscription is the first phase's invoice, so the customer's first charge is phase 1's amount. |
| Within phases | Each invoice is priced by the phase that owns that cycle, and the next bill date uses that phase's billingCycleConfig. |
| Phase advance | Once a phase has billed cycleCount cycles, the next invoice uses the next phase. |
| Phases exhausted | Billing falls back to the subscription's default price and its billing cycle, indefinitely. |
Phases do not introduce a new subscription status. A phases-only subscription becomes ACTIVE on the first successful payment and stays ACTIVE through every phase.
Request shape
curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"phases": [
{ "cycleCount": 2, "priceId": "prc_intro123xyz" }
],
"successReturnUrl": "<optional:the-redirect-url-after-the-1st-payment-is-done>"
}'curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"phases": [
{
"cycleCount": 2,
"price": {
"unitAmount": 90,
"currency": "USD",
"billingCycleConfig": { "interval": "day", "frequency": 1 }
}
}
]
}'curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"phases": [
{
"cycleCount": 3,
"price": {
"unitAmount": 100,
"currency": "USD",
"billingCycleConfig": { "interval": "month", "frequency": 1 }
}
},
{
"cycleCount": 3,
"price": {
"unitAmount": 500,
"currency": "USD",
"billingCycleConfig": { "interval": "month", "frequency": 1 }
}
}
]
}'curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"startAt": 1759950506000,
"phases": [
{ "cycleCount": 2, "priceId": "prc_intro123xyz" }
]
}'curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"trial": {
"duration": 7,
"durationType": "day"
},
"phases": [
{ "cycleCount": 2, "priceId": "prc_intro123xyz" }
]
}'curl -X POST 'https://api.breeze.cash/v1/subscriptions' \
-u "YOUR_API_KEY:" \
--header 'Content-Type: application/json' \
--data-raw '{
"clientReferenceId": "your-unique-subscription-reference-id",
"productId": "prd_abc123xyz",
"priceId": "prc_abc123xyz",
"customer": {
"id": "cus_123xyz"
},
"startAt": 1759950506000,
"trial": {
"duration": 7,
"durationType": "day"
},
"phases": [
{ "cycleCount": 2, "priceId": "prc_intro123xyz" }
]
}'priceId(top level) is still required — it is the default price billed once all phases are exhausted.phases[].cycleCount: number of billing cycles this phase bills before advancing. Minimum1.phases[].priceId: an existing price to bill during this phase. Mutually exclusive withphases[].price.phases[].price.unitAmount: amount in minor units / cents (e.g.10000= USD 100.00).phases[].price.billingCycleConfig.interval:hour,day,week,month, oryear.houris sandbox-only.- Inline phase prices are not persisted as reusable
Priceentities; they exist only on the subscription.
Validation rules
| Rule | Detail |
|---|---|
| Phase count | 1–10 phases per subscription. |
| Price source | Each phase defines exactly one of priceId or inline price. |
| Referenced price | Must be ACTIVE, of type RECURRING, belong to the same product as the subscription, and use the subscription's currency. |
| Currency | Every phase currency must match the subscription's currency. |
| Interval | hour billing is rejected in live mode (sandbox only). |
| Mutual exclusivity | phases and discountedTrial cannot be sent together. |
Sample Scenarios
Scenario 1: Introductory pricing
Today: 2025-05-01
Merchant: Creates a subscription with:
- Default price: $9/month (
priceId) - Phase 1: $0.90/day × 2 cycles
Flow:
- 2025-05-01: Customer completes the payment page → charged $0.90 (phase 1, cycle 1)
- 2025-05-02: Breeze charges $0.90 (phase 1, cycle 2)
- 2025-05-03: Breeze charges $9 (phases exhausted → default price, first monthly cycle)
- 2025-06-03: Breeze charges $9
Behavior: the subscription is ACTIVE from the first successful payment onward. No status change happens when the phase is exhausted.
Scenario 2: Multi-phase step-up
Today: 2025-05-01
Merchant: Creates a subscription with:
- Default price: $9/month (
priceId) - Phase 1: $1/month × 3 cycles
- Phase 2: $5/month × 3 cycles
Flow:
- 2025-05-01 → 2025-07-01: charged $1/month (3 cycles)
- 2025-08-01 → 2025-10-01: charged $5/month (3 cycles)
- 2025-11-01 onward: charged $9/month (default price)
Phases can be combined with
trial,startAt, or both. The verification invoice created for those does not consume a phase — phase 1 prices the first real charge, and the phases after it follow from there. For when that first charge falls, see Scheduled & Free Trial.
Scenario 3: Phases + scheduled start
Today: 2025-04-01
Merchant: Creates a subscription with:
- Default price: $9/month (
priceId) - Phase 1: $0.90/day × 2 cycles
- Scheduled start: 2025-05-01
Flow:
- 2025-04-01: Customer completes card verification (no phase charge yet)
- 2025-05-01: Breeze charges $0.90 (phase 1, cycle 1)
- 2025-05-02: Breeze charges $0.90 (phase 1, cycle 2)
- 2025-05-03: Breeze charges $9 (default price)
Behavior:
- 2025-04-01 → 2025-05-01: subscription is
SCHEDULED - 2025-05-01 onward: subscription is
ACTIVE
Scenario 4: Phases + free trial
Today: 2025-05-01
Merchant: Creates a subscription with:
- Default price: $9/month (
priceId) - Phase 1: $0.90/day × 2 cycles
- Free trial: 7 days
Flow:
- 2025-05-01: Customer completes the payment page — no charge; the trial starts
- 2025-05-08: Trial ends → charged $0.90 (phase 1, cycle 1)
- 2025-05-09: Breeze charges $0.90 (phase 1, cycle 2)
- 2025-05-10: Breeze charges $9 (phases exhausted → default price)
Behavior:
- 2025-05-01 → 2025-05-08: subscription is
TRIALING - 2025-05-08 onward: subscription is
ACTIVE
Scenario 5: Phases + scheduled start + free trial
Today: 2025-04-01
Merchant: Creates a subscription with:
- Default price: $9/month (
priceId) - Phase 1: $0.90/day × 2 cycles
- Scheduled start: 2025-05-01
- Free trial: 7 days
Flow:
- 2025-04-01: Customer completes card verification (no charge)
- 2025-05-01: Trial starts — still no charge
- 2025-05-08: Trial ends → charged $0.90 (phase 1, cycle 1)
- 2025-05-09: Breeze charges $0.90 (phase 1, cycle 2)
- 2025-05-10: Breeze charges $9 (phases exhausted → default price)
Behavior:
- 2025-04-01 → 2025-05-01: subscription is
SCHEDULED - 2025-05-01 → 2025-05-08: subscription is
TRIALING - 2025-05-08 onward: subscription is
ACTIVE
Reading Phases Back
GET /v1/subscriptions/{subscriptionId} returns the snapshotted phases, in order. price.id is present only for phases that referenced an existing price.
billingCycleAnchor is the Unix timestamp (ms) the subscription's billing cycles are anchored to — the time of the first payment, or startAt for a scheduled subscription. It is absent until the first payment completes.
{
"status": "SUCCEEDED",
"data": {
"id": "subs_abc123xyz",
"status": "ACTIVE",
"priceId": "prc_abc123xyz",
"amountStr": "9",
"currency": "USD",
"billingCycleConfig": { "interval": "month", "frequency": 1 },
"billingCycleAnchor": 1746057600000,
"phases": [
{
"cycleCount": 2,
"price": {
"id": "prc_intro123xyz",
"unitAmount": 90,
"currency": "USD",
"billingCycleConfig": { "interval": "day", "frequency": 1 }
}
}
]
}
}Migrating from discountedTrial
discountedTrialA discountedTrial is a single phase. Map it directly:
discountedTrial | phases equivalent |
|---|---|
cycleCount | phases[0].cycleCount |
billingCycleConfig | phases[0].price.billingCycleConfig |
price.unitAmount / price.currency | phases[0].price.unitAmount / phases[0].price.currency |
Two behavioral differences to expect:
- A phases subscription reports
ACTIVEduring its introductory cycles, notDISCOUNTED_TRIALING. - Phases support up to 10 stages, so an introductory period no longer has to be a single price.
Existing discountedTrial subscriptions are unaffected and continue to bill and report DISCOUNTED_TRIALING as before.
Key Takeaways
phasesis the supported way to bill introductory, promotional, or stepped pricing;discountedTrialis deprecated.- Phases are ordered, snapshotted at creation, and fall back to the subscription's default price once exhausted.
- Each phase can reference an existing recurring price or define an inline one, but not both.
- Phases add no new subscription status — billing runs in
ACTIVE.
Updated 18 days ago
