> ## Documentation Index
> Fetch the complete documentation index at: https://loops.so/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Recipe: Onboarding completion workflow

> Send a congratulatory email the moment a user finishes your onboarding checklist, plus a next-step nudge if they don't.

A common SaaS lifecycle pattern: celebrate when a user completes onboarding, and re-engage the users who stall. This recipe sets up both with two [workflows](https://loops.so/docs/workflows.md).

The core idea: fire an [event](https://loops.so/docs/events.md) from your app when the user completes onboarding and update an `onboardingCompletedAt` contact property in the same request. The celebration workflow triggers from the event, and the stalled-user workflow filters out contacts with a completion timestamp.

## What you need

* A timestamp [contact property](https://loops.so/docs/contacts/properties.md) like `onboardingCompletedAt`
* A named [event](https://loops.so/docs/events.md) for "onboarding completed"
* The [Loops API](https://loops.so/docs/api-reference/intro.md) or an [integration](https://loops.so/docs/integrations.md) writing into Loops

## Set up the trigger

Use the **Event received** [workflow trigger](https://loops.so/docs/workflows/triggers.md) with an event name like `onboardingCompleted`.

Update the contact's `onboardingCompletedAt` property at the same time so your stalled-user workflow can exclude users who already finished.

If you prefer using contact property changes as the trigger, see the **Contact updated** approach used in [the lifecycle emails guide](https://loops.so/docs/guides/lifecycle-emails.md).

**1. Send the event from your app**

Call the [Send event endpoint](https://loops.so/docs/api-reference/send-event.md) when the user finishes the last onboarding step. The API accepts contact properties as top-level fields in the same request:

```json API request theme={"dark"}
{
  "email": "user@example.com",
  "onboardingCompletedAt": "2026-04-27T17:00:00Z",
  "eventName": "onboardingCompleted",
  "eventProperties": {
    "daysToComplete": 2
  }
}
```

```ts SDK theme={"dark"}
await loops.sendEvent({
  email: "user@example.com",
  eventName: "onboardingCompleted",
  contactProperties: {
    onboardingCompletedAt: new Date().toISOString(),
  },
  eventProperties: { daysToComplete: 2 },
});
```

**2. Create the workflow**

In the [Workflow builder](https://loops.so/docs/workflows.md), pick **Event received** and select `onboardingCompleted`.

**3. Send the celebration email**

Add a **Send email** node. Congratulate them, surface the next high-value feature, and offer a next action.

## Catching users who stall

The other half of this recipe is a separate workflow that fires when a contact is added but does not complete onboarding within a timer window.

**1. Trigger on Contact added**

Pick **Contact added** as the [trigger](https://loops.so/docs/workflows/triggers.md).

**2. Add a timer**

Wait 3 days.

**3. Filter on onboarding state**

Use an [audience filter](https://loops.so/docs/workflows.md#audience-filters) to only send if `onboardingCompletedAt` is empty.

**4. Send the nudge**

Keep it short. Link to the specific step they missed if you track that.

## Measuring success

* Open rate on the celebration email: should be >50% because it is expected
* Click-through on the stall nudge: track with the `email.clicked` [webhook](https://loops.so/docs/webhooks.md)
* Completion lift: compare `daysToComplete` distributions before and after this workflow ships

## Read more

> [card] [Lifecycle emails overview](https://loops.so/docs/guides/lifecycle-emails.md)

> [card] [Workflows](https://loops.so/docs/workflows.md)

> [card] [Events](https://loops.so/docs/events.md)

> [card] [Filters and segments](https://loops.so/docs/contacts/filters-segments.md)


## Related topics

- [Recipe: SaaS customer lifecycle emails](https://loops.so/docs/guides/lifecycle-emails.md)
- [Recipe: Upgrade upsell workflow](https://loops.so/docs/guides/upgrade-upsell.md)
- [Recipe: Churn risk segment and re-engagement workflow](https://loops.so/docs/guides/churn-risk-segment.md)
- [Triggering workflows](https://loops.so/docs/workflows/triggers.md)
- [Recipe: Scheduled digest email](https://loops.so/docs/guides/scheduled-digest-email.md)
