# Tag Conversation

Add one or more tags to this conversation — read by saved views as a fallback when a contact tag doesn't match, and gone once the thread is.

## Getting here

**Automate → Workflows**, open a workflow, click **+** on the canvas, then pick **Tag Conversation** 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).
- Nothing outside Inchat has to be connected.

## Set up

1. Open the workflow and click **+** where the tag belongs.
2. Pick **Tag Conversation**.
3. Leave **Action** on **Add Tag** and **On** on **Conversation** — switching either turns this into Untag Conversation, Tag Contact or Untag Contact instead, since all four share one editor.
4. Pick one or more tags from the chips already used in this workspace, or type a new one and press Enter.
5. Save the step, then publish the workflow. A saved but unpublished workflow tags nothing.

## Fields

| Field | What it means | Default | Limits |
| --- | --- | --- | --- |
| Action | Add Tag or Remove Tag. | Add Tag | Choosing **Remove Tag** saves this as the Untag Conversation step instead. |
| On | Whether the tag goes on the conversation or on the contact behind it. | Conversation | Choosing **Contact** saves this as the Tag Contact step instead. |
| Tags | Chips for every tag already used somewhere in the workspace, plus a box to type a new one. Several may be picked on one step. | — | A step keeps at most 20 tags: any past the 20th are dropped when you save, with no warning. A name typed here that is not already in the workspace's tag list is added to it automatically; a name over 64 characters is refused when you save. |

## How it works

- The step writes the tag onto `conversations.tags` — what a saved view's tag filter checks first is the contact's own tags; a conversation tag only matches as a fallback, so a saved view built around conversation tags still finds them.
- Adding a tag the conversation already carries, or removing one it does not have, is a no-op success: nothing is written and the step still counts as ok.
- Naming several tags on one step tries every one of them, even if an earlier one in the list failed to write, and the step is recorded failed if any of them did.
- Every tag name is normalised before it is stored — trimmed, capped at 64 characters, and matched to the workspace's existing tag list without regard to case. Writing “sale” onto a conversation that already carries “Sale” does not create a second tag: the write is folded onto the catalogue's existing spelling — though the step still counts it as an add and logs “sale” on the Activity tab, so the conversation still shows one tag, “Sale”.
- A name nobody in the workspace has used before is added to the tag catalogue at the same time it is first written onto a conversation.
- When the conversation has a linked contact, the same tag is also logged to that contact's Activity tab, marked as added by a workflow (or by the AI agent, when the step runs inside an AI turn) — so a tag applied by automation is not invisible there.

## When it fails

- The only realistic failure is a database error reading or writing the conversation — rare and transient. This action does not report a specific reason, so the run's **Activity** tab shows the fixed line **failed without a reported reason** rather than anything naming the tag.
- A failed tag write does not stop the run: the step is recorded failed and the flow moves straight to the next one, so a message or close placed after it still happens on the untagged conversation.

## Limits

- It never touches the contact's own tags — a workflow that wants the tag to follow the person into segments and broadcasts needs **Tag Contact** instead.
- It never removes a tag that a saved view or another workflow relies on — clearing state a flow moved a contact out of is the author's job, with the matching **Untag Conversation** step in the same branch.
- The tag disappears with the conversation; it is not carried onto whatever new conversation the same contact starts later.

## Best practices

- Pair this with **Untag Conversation** on the branch that reverses it — a tag set is only useful while it says something true about the thread right now.

## Use cases

- Tag every conversation that starts from a paid ad campaign `ad-lead`, so the Inbox's saved view for that campaign is one filter away.
- Tag a thread `needs-quote` when a customer asks about pricing, then remove it once **Quote / confirm order** has sent one.

## Related

- [Untag Conversation](https://inchat.inseller.my/help/workflows/untag-conversation)
- [Tag Contact](https://inchat.inseller.my/help/workflows/tag-contact)
- [Untag Contact](https://inchat.inseller.my/help/workflows/untag-contact)
- [Conditions and variables](https://inchat.inseller.my/help/workflows/conditions-and-variables)
- [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/engine.ts`, `src/lib/workflows/form-payload.ts`, `src/lib/workflows/workflow-input-schema.ts`, `src/lib/activity/record.ts`, `src/lib/inbox/custom-inbox-filter.ts`, `supabase/migrations/20260911210000_tags_catalog.sql`, `supabase/migrations/20260913200000_review_0913_p1s.sql`
