# How to build a SaaS trial-conversion email sequence with product events

Canonical: https://brew.new/blog/how-to-build-a-saas-trial-conversion-email-sequence-with-product-events
Author: Thomas Park
Published: 2026-09-26
Updated: 2026-09-29

A trial-conversion email should respond to what the user has done. Someone who has not created a project needs setup help. Someone who has used the product daily needs a clear explanation of the paid plan. Sending both people the same countdown misses that distinction.

This guide separates sequence design from the application logic that decides who should receive each email.

## Choose an activation event

Pick one action that shows the user has reached the product's first useful result. Make it specific enough for your backend to record: a project created, an import completed, or a teammate invited. A page view is rarely enough on its own.

Record signup time, trial end, activation, and paid status in the system that owns those facts. Treat contact fields in the email platform as synchronized data, not as proof that an earlier flow is reading fresh state.

## Give each message one job

| Message | When it is useful | Eligibility checked when due |
| --- | --- | --- |
| Welcome | After signup or verification | Account exists and may receive this message |
| Setup help | About two days later, adjusted to your product | Has not activated |
| Next useful action | After activation | Has activated and has not completed that action |
| Trial ending | Before the actual trial deadline | Trial is still active and account is not paid |
| Final check-in | After the trial ends, if appropriate | Still unpaid, eligible, and permitted to receive marketing |

These timings are starting points for a test, not measured best-performing intervals. State the actual trial deadline and what happens next. Do not invent scarcity or imply a charge will happen when no payment method is on file.

## Choose the source for eligibility checks

In a Brew event-triggered flow, `payload.activated` reads the original event, while `contact.activated` reads the recipient's current Brew contact field when a Filter or condition Split executes. To skip setup reminders after activation, declare that boolean field, keep it synced from your product, and check `contact.activated equals false` after each relevant Wait. Missing values are not false; test them separately.

These reads use Brew's stored contact, not your application's database or a live Stripe request. Receiving an activation or payment event does not automatically cancel an earlier run. The graph needs a condition before each state-dependent send.

For facts outside Brew, have your application schedule a job. When it becomes due, read the current account or invoice and fire a separate Brew custom event only if the recipient still qualifies. Include the current data needed for personalization in that new event.

For example, an application-scheduled reminder works like this:

```text
Signup committed → fire welcome event
Reminder job becomes due → read current account
  Already activated or paid → finish without firing an email event
  Still eligible → fire setup-reminder event with current data
```

Use the actual trigger ID returned by Brew and the trigger's declared schema. Follow the [automation setup guide](https://docs.brew.new/create-emails/build-an-automation) and [typed payload contracts](https://docs.brew.new/api-reference/guides/typed-payload-contracts). Use the documented idempotency mechanism for retried event fires.

## Use Stripe for the facts it owns

If Stripe manages the trial, its subscription events provide billing context. The [Stripe integration](/browse/integrations/stripe) exposes supported event triggers, including `customer.subscription.trial_will_end`. Your application still owns product activation unless you send that information separately.

For a later payment-related reminder, check the current Stripe record. A successful card update is not proof that an invoice has been paid. Coordinate with Stripe's own emails so the customer gets one notice for each purpose.

## Write the email after the eligibility rule

Start with the recipient's actual situation. Explain one useful action and link directly to it. A setup email can offer a short example and a reply address. A paid-plan email should describe the relevant limit or feature and the real price, with a link to current pricing.

Keep marketing consent, unsubscribe behavior, and domain purpose aligned with the message. A trial signup does not justify unrelated promotional email.

## Prove that the exits work

Test activation and payment before each eligibility check. With contact conditions, update the relevant Brew fields during the wait and confirm the reminder is skipped. With application-scheduled checks, confirm ineligible accounts do not produce a reminder event. Also test retries, trial extensions, account deletion, unsubscribes, and missing fields. Check both the application logs and Brew execution history.

Evaluate activation and paid conversion using your product data, and delivery failures using the email platform. Open rates alone do not show whether the sequence helped a trial user. See [welcome sequence design](/blog/welcome-email-sequence) for examples and [MCP versus REST](/blog/mcp-vs-rest-api-for-email-marketing-which-workflow-should-you-use) for the implementation split.
