---
ref: workflow:free-to-paid-activation
title: Email a trial offer to active free users
author: thedogwiththedataonit
tools: [tool:posthog/run-sql-query, tool:stripe/list-customers, tool:stripe/list-subscriptions, tool:brew/generate-email, tool:brew/send-email]
tags: [capability:analyze-product-usage, capability:send-email, capability:track-revenue, capability:write-copy, channel:email, has:api, has:cli, has:mcp, motion:plg]
updated: 2026-10-11
---

# Email a trial offer to active free users

Finds opted-in free users in PostHog who reached your activation event, skips paying Stripe customers, and emails a trial offer with Brew.

Set up the tools below, then run the steps in order for the user, carrying each step's results into the next. The run is done when the user has the outcome below.

## Outcome

- One approved trial-offer email, queued for eligible opted-in users who reached your activation event, excluding paying customers.
- The number of accepted recipients and the send IDs for tracking delivery.

## Inputs

Ask the user for these before you start.

- `activation_event`: the event that marks real usage, e.g. campaign_sent
- `min_events`: how many times they must fire it, e.g. 3
- `lookback_days`: the window to count in, e.g. 14
- `consent_property`: the PostHog person property that is true when someone opted in to marketing email, e.g. marketing_opt_in
- `trial_plan`: the plan to offer, e.g. Pro, 14-day trial
- `trial_url`: where they start it, e.g. https://acme.example/upgrade

## Set up

### Run a SQL query (PostHog, tool:posthog/run-sql-query)

Use the first option your agent supports.

Note: Needs a personal API key with the `query:read` scope. Returns up to 100 rows by default and up to 50,000 with an explicit `LIMIT`; it is for ad-hoc analysis, not bulk export.

#### MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

```json
{ "mcpServers": { "posthog": { "url": "https://mcp.posthog.com/mcp" } } }
```

Call the MCP tool `execute-sql`.

#### CLI (official)

Install the command, then confirm it runs.

```sh
npm install -g @posthog/cli@latest
posthog-cli --version
```

Run `posthog-cli api call execute-sql`.

Set `$POSTHOG_CLI_API_KEY` in your environment first (get a key: https://app.posthog.com/settings/user-api-keys?preset=mcp_server).

### Stripe (tool:stripe/list-customers, tool:stripe/list-subscriptions)

Use the first option your agent supports.

Notes:

- List customers: The `email` filter is case-sensitive.

#### MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

```json
{ "mcpServers": { "stripe": { "url": "https://mcp.stripe.com" } } }
```

- List customers: call the MCP tool `stripe_api_read` with `GET /v1/customers`
- List subscriptions: call the MCP tool `stripe_api_read` with `GET /v1/subscriptions`

#### CLI (official)

Install the command and sign in with it, then confirm it runs.

```sh
npm install -g @stripe/cli
stripe --version
```

- List customers: run `stripe customers list`
- List subscriptions: run `stripe subscriptions list`

### Brew (tool:brew/generate-email, tool:brew/send-email)

Use the first option your agent supports.

Notes:

- Generate an email: Costs credits and requires a ready brand. If generating, poll get_email. Keep emailId and emailVersionId; pass both to a send or automation to pin the design.
- Send an email: Supply subject and existing subscribed recipients. Use idempotency_key (MCP) or Idempotency-Key (HTTP), reusing it for retries. On confirmation_required, obtain approval and repeat with confirmed:true and the returned confirmation_id. Queued is not delivered.

#### MCP (official, remote)

Add this server to your agent's MCP settings, then sign in when asked.

```json
{ "mcpServers": { "brew": { "url": "https://brew.new/api/mcp" } } }
```

- Generate an email: call the MCP tool `create_email`
- Send an email: call the MCP tool `send_email`

#### CLI (official)

Install the command, then confirm it runs.

```sh
brew install getbrew/tap/brew-cli
brew-cli --version
```

- Generate an email: run `brew-cli emails generate`
- Send an email: run `brew-cli emails send`

Set `$BREW_API_KEY` in your environment first (get a key: https://brew.new/settings/api).

Before step 1, confirm access to each service with its cheapest read-only call, like a list or a search. Never send or change anything to test access.

## Steps

1. **Find activated users** with Run a SQL query (PostHog). List people whose `consent_property` is true and who fired `activation_event` at least `min_events` times in the last `lookback_days`. Keep each person's email and event count.
2. **Find their customers** with List customers (Stripe). Look up each email, as stored and lowercased. Keep every customer ID it returns; people with no customer stay on the list.
3. **Skip paying customers** with List subscriptions (Stripe). Remove anyone whose customer has a subscription on a paid price that is not canceled. Keep the emails that remain.
4. **Write the email** with Generate an email (Brew). Generate one email that offers `trial_plan` around what these users already did, linking to `trial_url`. Show it to the user. Keep its `emailId`, `emailVersionId` and subject.
5. **Send** with Send an email (Brew). Match the consent-qualified addresses to existing subscribed Brew contacts first; stop for the user to prepare any missing contacts. After the user approves, send it to the remaining emails, 50 inline recipients per send, each send with its own idempotency key.

## Rules

- Use only the services set up above. The read-only calls they need, like listing ids or polling for results, are fine.
- Ask the user before anything that sends messages, costs money, or changes data, and say how many records it touches. One approval covers a batch the user has seen.
- Never print API keys.
