# Update Lifecycle

Move the contact to another lifecycle stage, or clear the stage entirely — what the dashboard's lifecycle counts read, and what a pipeline stage can watch for to move a deal forward.

## Getting here

**Automate → Workflows**, open a workflow, click **+** on the canvas, then pick **Update Lifecycle** under **Add Steps**.

## Before you start

- An **owner**, **admin** or **agent** can add this step and save the workflow. Publishing that workflow — the thing that makes it run on live conversations — is an **owner** or **admin** action.
- Building and running workflows depends on your plan; see [pricing](/pricing).
- The lifecycle stage must already exist under **Settings → Lifecycle**. This step picks a stage; it cannot create one.

## Set up

1. Open the workflow and click **+** where the move belongs.
2. Pick **Update Lifecycle**.
3. Choose **Update stage** and pick one from the list, or choose **Remove stage** to clear it.
4. Save the step, then publish the workflow. A saved but unpublished workflow moves nobody.

## Fields

| Field | What it means | Default | Limits |
| --- | --- | --- | --- |
| Lifecycle action | Update stage — move the contact to a named stage — or Remove stage — clear it entirely. | Update stage | — |
| Stage | Which lifecycle stage to move the contact to. | — | Only shown for Update stage; hidden when Remove stage is chosen. |

## How it works

- The step resolves the contact behind this conversation and writes the chosen stage id onto `contacts.lifecycle_stage_id`, replacing whatever stage was there before.
- **Remove stage** writes null, clearing it — the contact still exists, it simply has no lifecycle stage until something sets one again.
- The move is exact: the step goes straight to the stage you named. It does not advance the contact to “the next stage” relative to wherever they were, so skipping or moving backward needs no special handling — you just pick the stage.
- A pipeline stage can be configured, under **Pipelines → Manage pipelines**, with **“Moving a contact to these lifecycle stages moves its deal here (forward only)”**. Moving the contact to a lifecycle stage on that list moves their already-open deal in that pipeline forward to the matching stage — never backward, and never opens a new deal (unlike the equivalent tag rule) — and that move fires **Deal Stage Changed** for any workflow listening on it, writer **system**. A lifecycle stage not configured on any pipeline stage does none of this.

## When it fails

- This conversation has no linked contact: the step fails with **this conversation has no contact whose stage could be set**.
- The chosen stage no longer exists (deleted since the workflow was built): the step fails with **could not move the contact to stage <id> — it may have been deleted**.
- A database error reading the conversation's contact fails the step with **could not load the conversation's contact**.
- A failed move does not stop the run: the step is recorded failed and the flow moves straight to the next one, with the contact's stage left exactly as it was.

## Limits

- It cannot create a lifecycle stage — only move a contact to one that already exists under Settings → Lifecycle.
- It does not fire this workspace's **Lifecycle Updated** trigger for other workflows — only a change made in (Contacts, the inbox thread header, the app, or the public API) does; use **Trigger Another Workflow** to hand off on purpose instead. This is narrower than "cannot start a chain": a lifecycle stage that a pipeline stage watches for (see How it works) can still move an already-open deal forward and fire **Deal Stage Changed** for other workflows, even though this specific trigger never fires.
- Directly, it only changes the stage column itself — it does not touch tags or the assignee. It can still move a deal, as a side effect, per the pipeline rule above.

## Use cases

- Move a contact to **Customer** once **Move Deal to Stage** records their deal as won, so the dashboard's lifecycle counts reflect the sale immediately.
- Clear the stage when a contact's record needs to leave every named stage's count — the dashboard's lifecycle funnel keeps a separate **No stage** bucket for them, it does not drop them from the report.

## Related

- [Move Deal to Stage](https://inchat.inseller.my/help/workflows/move-deal-to-stage)
- [Save to Contact Field](https://inchat.inseller.my/help/workflows/save-to-contact-field)
- [Tag Contact](https://inchat.inseller.my/help/workflows/tag-contact)
- [Workflows: how a flow runs](https://inchat.inseller.my/help/workflows/workflows-overview)

---

Source files: `src/lib/workflows/ai-builder/spec.ts`, `src/lib/workflows/canvas-model.ts`, `src/components/workflows/WorkflowStepConfigDrawer.tsx`, `src/lib/workflows/engine-record-actions.ts`, `src/lib/workflows/types.ts`, `src/lib/workflows/workflow-input-schema.ts`, `src/lib/workflows/contact-triggers.ts`, `supabase/migrations/20260917230100_pipeline_stage_auto_lifecycle.sql`, `supabase/migrations/20260920150000_opportunity_stage_events.sql`, `src/lib/pipelines/stage-events.ts`, `src/lib/i18n/messages/pipelines.ts`, `src/components/dashboard/LifecycleFunnel.tsx`
