# Add a free trial to a plan

URL: /products/offers/add-a-free-trial-to-a-plan · Id: `guide:add-a-free-trial-to-a-plan`

> Say "give every new customer on this plan 14 days free" and each sign-up starts a trial, with a reminder before the first charge.

A trial on an [Offer](/business/nouns/offer) starts every new [Customer](/business/nouns/customer) free for a set number of days. With a card up front, it turns into a paid [Subscription](/business/nouns/subscription) on its own.

Needs: [Charge monthly](/systems/finance/charge-monthly) · [Open a bank account](/systems/finance/open-a-bank-account)

**Before it runs**

- You leave the chat: Never: it all happens in the chat.

## What you get
- 1 trial of 14 days on the Pro Offer for every new customer (Offer)
- 1 card taken at sign-up and charged on day 15 (Subscription)
- 1 reminder three days before the first charge (Message)
- 1 one trial per customer; a second sign-up from the same account starts paid (Customer)

## Your agent does
**For agents**

- Guide: `guide:add-a-free-trial-to-a-plan`, status `live`. Page: [/products/offers/add-a-free-trial-to-a-plan.md](/products/offers/add-a-free-trial-to-a-plan.md).
- Approval: none. Run it when the founder asks.
- Leaves the chat: never.
- Needs first: [Charge monthly](/systems/finance/charge-monthly), [Open a bank account](/systems/finance/open-a-bank-account).
- Run: call the steps in order, each through the API, SDK, CLI or MCP tab below; a later step passes the `$id` an earlier one returns. Each value marked example is the sample business’s: pass the founder’s own.

| Step | Verb | Inputs (type, required, this guide’s value) | Returns |
| --- | --- | --- | --- |
| 1 | [`Offer.update`](/business/nouns/offer/update) (`verb:Offer.update`) | `id` string, required: example `"offer_pro_monthly"`; `price` money: example `{"amount":29,"currency":"USD"}`; `trial` json: example `{"days":14,"card":true}` | `offer` Offer |

Returns: the last call answers with `offer` and its `action`, whose `status` is `done`, `pending` (waiting on an Approval or a Worker), `failed`, `canceled` or `refused`:

```json
{
  "api": "https://api.sb/leaseline.app",
  "offer": {
    "$id": "https://api.sb/leaseline.app/offers/offer_pro_monthly",
    "$type": "Offer",
    "trial": {
      "days": 14,
      "card": true
    }
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Offer.update",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/action_1"
  }
}
```

Next: offer “Drop the card requirement”, or “Make it 30 days for annual plans”.

Calls: `Offer.update`

Ask:

```text
Give every new Pro customer 14 days free.
Add a free trial to Pro.
Let people try it before they pay.
```

API:

```bash
# Offer.update
curl -X PATCH https://api.sb/leaseline.app/offers/offer_pro_monthly \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"price":{"amount":29,"currency":"USD"},"trial":{"days":14,"card":true}}'
```

SDK:

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

await $.Offer.update({ id: 'offer_pro_monthly', price: { amount: 29, currency: 'USD' }, trial: { days: 14, card: true } })
```

CLI:

```bash
npx startup-builder do Offer.update --json '{"id":"offer_pro_monthly","price":{"amount":29,"currency":"USD"},"trial":{"days":14,"card":true}}'
```

MCP:

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Offer.update({ id: 'offer_pro_monthly', price: { amount: 29, currency: 'USD' }, trial: { days: 14, card: true } })"
  }
}
```

## Change it
- Drop the card requirement.
- Make it 30 days for annual plans.
- How many trials turned into paying customers last month?

## Under the hood
- Systems: [Billing](/systems/billing)
- Nouns: [Offer](/business/nouns/offer), [Subscription](/business/nouns/subscription), [Customer](/business/nouns/customer)
- Events: `Offer.updated`, [`Offer.trialed`](/business/events/Offer.trialed)
- Stripe objects: `Subscription`