# Trials and plan changes

URL: /workflows/processes/plan-changes · Id: `process:plan-changes`

> Trials and plan changes converts each free trial to paid on its terms and moves a Customer between Offers with the period prorated.

Trials and plan changes converts each free trial to paid on its terms and moves a [Customer](/business/nouns/customer) between [Offers](/business/nouns/offer) with the period prorated.

## Outcome
| Part | This Process |
| --- | --- |
| Outcome | Each trial converts to paid or ends on its terms after one reminder, and each plan change takes effect with the period prorated. |
| Reads | [Subscription](/business/nouns/subscription), [Offer](/business/nouns/offer) |
| Leaves | [Invoice](/business/nouns/invoice), [Entitlement](/business/nouns/entitlement), [Message](/business/nouns/message), [Subscription](/business/nouns/subscription) |
| Runs in | Each Startup |

## Accountable
[Billing Specialist](/agents/finance/billing-specialist), [Finance Team](/agents/finance).

Responsible: [Billing Specialist](/agents/finance/billing-specialist).

Consulted: [Success Manager](/agents/customer/success-manager).

Informed: [Finance Lead](/agents/finance/finance-lead).

## Workflows
| Workflow | Runs | Team |
| --- | --- | --- |
| [Convert a trial](/workflows/processes/plan-changes/convert-trial) | every day | [Finance Team](/agents/finance) |
| [Change a plan](/workflows/processes/plan-changes/change-plan) | on every [Subscription.switch](/business/nouns/subscription/switch) call | [Finance Team](/agents/finance) |
| [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) | on every [Subscription.unsubscribe](/business/nouns/subscription/unsubscribe) call | [Finance Team](/agents/finance) |

## Who does each step

| Workflow | Step | Role | Calls | Approval |
| --- | --- | --- | --- | --- |
| [Convert a trial](/workflows/processes/plan-changes/convert-trial) | 1. Find trials that end within the reminder window. | [Billing Specialist](/agents/finance/billing-specialist) | [Subscription.list](/business/nouns/subscription/list) | None |
| [Convert a trial](/workflows/processes/plan-changes/convert-trial) | 2. Remind each Customer of the date, the Price and a one-step cancel link. | [Billing Specialist](/agents/finance/billing-specialist) | [Message.create](/business/nouns/message/create) | None |
| [Convert a trial](/workflows/processes/plan-changes/convert-trial) | 3. Charge the card on file when the trial ends. | [Billing Specialist](/agents/finance/billing-specialist) | [Invoice.collect](/business/nouns/invoice/collect) | Within a Mandate; waits 1 business hour |
| [Change a plan](/workflows/processes/plan-changes/change-plan) | 1. Prorate the current period and bill or credit the difference. | [Billing Specialist](/agents/finance/billing-specialist) | [Invoice.create](/business/nouns/invoice/create) | None |
| [Change a plan](/workflows/processes/plan-changes/change-plan) | 2. Move the Customer’s Entitlements to the new Offer. | [Billing Specialist](/agents/finance/billing-specialist) | [Entitlement.update](/business/nouns/entitlement/update) | None |
| [Change a plan](/workflows/processes/plan-changes/change-plan) | 3. Confirm the change, the new Price and the next charge date. | [Billing Specialist](/agents/finance/billing-specialist) | [Message.create](/business/nouns/message/create) | None |
| [Change a plan](/workflows/processes/plan-changes/change-plan) | 4. Hand a downgrade to the Success Manager to ask why. | [Success Manager](/agents/customer/success-manager) | [Renewal.open](/business/nouns/renewal/open) | None |
| [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) | 1. End renewal at the close of the paid period, at once, with no call or offer in the way. | [Billing Specialist](/agents/finance/billing-specialist) | [Subscription.update](/business/nouns/subscription/update) | None |
| [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) | 2. Confirm the cancellation with the last day of access and how to come back. | [Billing Specialist](/agents/finance/billing-specialist) | [Message.create](/business/nouns/message/create) | None |
| [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) | 3. Send the Customer an export of their data, kept available after access ends. | [Success Manager](/agents/customer/success-manager) | [Collection.export](/business/nouns/collection/export) | None |

## Events
| Direction | When | What happens |
| --- | --- | --- |
| In | Every day | Starts [Convert a trial](/workflows/processes/plan-changes/convert-trial) |
| In | On every [Subscription.switch](/business/nouns/subscription/switch) call | Starts [Change a plan](/workflows/processes/plan-changes/change-plan) |
| In | On every [Subscription.unsubscribe](/business/nouns/subscription/unsubscribe) call | Starts [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) |
| In | On [`Offer.trialed`](/business/events/Offer.trialed) | Wakes this Process, the first time only. The first Customer starts a trial. |
| Out | `Message.created` | Raised by step 2 of [Convert a trial](/workflows/processes/plan-changes/convert-trial) |
| Out | [`Invoice.collected`](/business/events/Invoice.collected) | Raised by step 3 of [Convert a trial](/workflows/processes/plan-changes/convert-trial) |
| Out | `Invoice.created` | Raised by step 1 of [Change a plan](/workflows/processes/plan-changes/change-plan) |
| Out | `Entitlement.updated` | Raised by step 2 of [Change a plan](/workflows/processes/plan-changes/change-plan) |
| Out | [`Renewal.opened`](/business/events/Renewal.opened) | Raised by step 4 of [Change a plan](/workflows/processes/plan-changes/change-plan) |
| Out | `Subscription.updated` | Raised by step 1 of [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) |
| Out | [`Collection.exported`](/business/events/Collection.exported) | Raised by step 3 of [Cancel a subscription](/workflows/processes/plan-changes/cancel-subscription) |

## Plays
No Play names this Process.

## Controls
No Control names this Process or a Workflow of it.

## Settings
| Setting | Type | Default | Say | Set with |
| --- | --- | --- | --- | --- |
| `trials.remindDaysBefore` | `integer` | `3` | Remind trial users three days before they are charged | [Setting.update](/business/nouns/setting/update) |
| `plans.prorate` | `boolean` | `true` | Prorate every plan change | [Setting.update](/business/nouns/setting/update) |

## Failure
A failed step retries; when retries run out, the Action goes to the [Billing Specialist](/agents/finance/billing-specialist).

| Step | On failure |
| --- | --- |
| [Convert a trial](/workflows/processes/plan-changes/convert-trial) 3. Charge the card on file when the trial ends. | `noCard`: The trial has no card on file, so it ends and the Customer keeps their data. |

## Loop
| Step | Value |
| --- | --- |
| Hypothesis | Reminding a trial three days before it ends converts more trials to paid than reminding on the last day. |
| Measure | [Activation rate](/agents/product#activation-rate) over 30d, at least 100 observations |
| Learn | The learn step reads the Readout, records Evidence and a Decision, and drafts the next Variant. |

## Code

**Ask**

```text
Turn on trials and plan changes
```

**API**

```bash
curl -X POST https://api.sb/leaseline.app/processes/process_1/enable \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

**SDK**

```ts
import { $ } from 'startup-builder'

await $.Process.enable({ process: 'process_1' })
```

**CLI**

```bash
npx startup-builder do Process.enable --json '{"process":"process_1"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Process.enable({ process: 'process_1' })"
  }
}
```

## Enable
On by default for [SaaS](/products/templates/saas), [Headless SaaS](/products/templates/headless-saas), [Dataset API](/products/templates/dataset-api), [Agent as a Service](/products/templates/agent-as-a-service). [Process.pause](/business/nouns/process/pause) stops new Actions; Actions in progress finish.

**Ask**

```text
Remind trial users three days before they are charged
```

**API**

```bash
curl -X PATCH https://api.sb/leaseline.app/settings/setting_1 \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":3,"key":"trials.remindDaysBefore"}'

curl -X PATCH https://api.sb/leaseline.app/settings/setting_2 \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":true,"key":"plans.prorate"}'
```

**SDK**

```ts
import { $ } from 'startup-builder'

await $.Setting.update({ id: 'setting_1', value: 3, key: 'trials.remindDaysBefore' })
await $.Setting.update({ id: 'setting_2', value: true, key: 'plans.prorate' })
```

**CLI**

```bash
npx startup-builder do Setting.update --json '{"id":"setting_1","value":3,"key":"trials.remindDaysBefore"}'
npx startup-builder do Setting.update --json '{"id":"setting_2","value":true,"key":"plans.prorate"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "await $.Setting.update({ id: 'setting_1', value: 3, key: 'trials.remindDaysBefore' })\nreturn await $.Setting.update({ id: 'setting_2', value: true, key: 'plans.prorate' })"
  }
}
```

## Example
A [Customer](/business/nouns/customer) on a 14-day trial of a $29 plan gets a reminder on day 11 and converts on day 14. Another moves from monthly to annual mid-month and pays $290 minus the unused $14.