# Updating the contact

How a flow adds or removes tags and lists and changes a contact's subscription, and why those changes win over your data sources.

**Language:** en
**Audience:** platform
**TLDR:** Update tags and Update lists add or remove values on the contact; Manage subscription opts the contact in or out of SMS marketing (which also covers RCS), suppresses or reactivates the channel. A flow writes like a manual change, so it wins over your data sources: a value it removes stays removed even if a connector sends it again.
**Translation key:** platform.automations.flows.contact-updates
**Search keywords:** add tag, remove tag, tag contact, untag, add to list, remove from list, opt in, opt out, unsubscribe contact, suppress, block channel, reactivate, subscription, consent from a reply, data source precedence, connector overwrite, manual edit priority
**Related pages:** /platform/es/automations/flows/contact-updates, /platform/en/automations/flows, /platform/en/automations/flows/branches, /platform/en/automations/flows/triggers-and-entry, /platform/en/automations/flows/sending-messages, /platform/en/consent/marketing-preference-vs-suppression, /platform/en/data-sources
**Docs index (every page):** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/llms.txt
**This zone's index:** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/llms.txt
**This page:** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/automations/flows/contact-updates/ (HTML) · https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/en/automations/flows/contact-updates.md (Markdown)
**Other language (es):** https://staging-instasent-docs-nextjs.oscar-284.workers.dev/platform/es/automations/flows/contact-updates.md

A flow doesn't only send messages: it can also write on the contact it is carrying. The
steps in the **Update the contact** group of the step palette tag a contact, add them to a
list or take them out of one, and record a change in their SMS subscription. That is how a
flow marks everyone who received the welcome message, gathers the contacts who clicked an
offer into a list you can target later, or records the "yes" of a customer who replied to
accept promotions. What a flow writes stays on the contact after the run ends, and the rest
of Instasent sees it like any other change: the contact's profile, segments, campaigns and
other flows.

There are three steps:

| Step                    | What it does                                     | Summary on the canvas card |
| ----------------------- | ------------------------------------------------ | -------------------------- |
| **Update tags**         | Adds or removes tags on the contact.             | **Add · welcome-sent**     |
| **Update lists**        | Adds the contact to lists or removes them.       | **Remove · 3 lists**       |
| **Manage subscription** | Changes the contact's subscription on a channel. | **SMS · Opt in**           |

The three behave the same way inside the flow. They act straight away and the contact
moves on to the next step; they have a single exit, with no branches; and they never stop
the run — whatever happens, the contact continues. A write that changes nothing, such as
adding a tag the contact already carries, leaves the contact as it was.

## Update tags and lists

**Update tags** and **Update lists** work identically: one writes on the contact's tags,
the other on their lists. Each step has two settings:

- `Action` — default: `Add`
  **Add** puts the values on the contact; **Remove** takes them off. A step does one or
  the other: to add some values and remove others, use two steps.
- `Tags / Lists` — required
  One or more values. Pick them from the ones your project already has, or type a new one
  (the field says "Pick tags or type a new one"): a value doesn't need to exist before a
  flow writes it. With no value, the step shows "Pick at least one tag." (or "Pick at
  least one list.") and the flow can't be published until you add one (see
  [Building a flow](/platform/en/automations/flows/building-a-flow#fix-what-blocks-publishing)).

Typical uses:

- **Mark who received something.** After a message, **Update tags** with **Add**
  `welcome-sent`. You can then exclude those contacts from a campaign, or build a segment
  of everyone who was welcomed.
- **Build a follow-up audience.** In a **Wait for activity**, the branch of contacts who
  tapped the offer link goes to **Update lists** with **Add** `spring-interested`; a later
  campaign targets that list.
- **Keep a decision on record.** The **No consent** branch of a **Check consent** step
  adds the tag `no-marketing-consent`, so you can see how many contacts the flow couldn't
  offer anything to.
- **Clean up after the flow.** A tag the flow added at the start (`in-onboarding`) is
  removed in the last step, so it only marks contacts who are still going through it.

When every branch of a split needs the same write, put one update step below the split
instead of one per branch: all branches continue there (see
[Building a flow](/platform/en/automations/flows/building-a-flow#splits-branches-and-where-a-step-lands)).

## Changes from a flow win over your data sources

A contact's data usually comes from several places at once — a store connector, a CSV
import, your API — and Instasent combines them into a single profile (see
[Integrations & data sources](/platform/en/data-sources)). When those sources disagree about a
contact's tags, lists or subscription, some carry more weight than others. A change made
by hand in the panel carries the most: it wins over every connector. The three update steps write **exactly like that manual change** — as if
someone on your team had edited the contact on their
[profile](/platform/en/audience/contacts-profiles).

> **Warning**: **A tag or list removed by a flow stays removed, even if a connector keeps sending it.**
> As the panel puts it: "The flow writes like a manual change in the panel, so it wins over
> your data sources: a removed value stays removed even if a connector keeps sending it.
> Use tags and lists that belong to your flows."

In practice:

- **Adding doesn't conflict with your sources.** A tag or list a flow adds sits next to whatever your sources send,
  and doesn't stop them from updating anything else.
- **Removing overrides your sources for that contact.** The removal is recorded as your
  decision, not as a one-off cleanup. Suppose your store connector marks its best
  customers with the tag `vip` on every sync, and a flow removes `vip` from customers who
  stop buying. From then on, the connector can send `vip` for that customer as often as it
  likes: the contact won't carry it again. The flow has broken the value the store was
  maintaining.
- **So use tags and lists that belong to your flows** — values no data source fills in,
  for example with a prefix you reserve for flows (`flow-inactive`, `flow-welcome-sent`).
  In the example above, the flow would add `flow-inactive` and your segments would exclude
  it, leaving `vip` to the store. Be especially careful with lists: they are often
  populated by a data source (see [Lists and tags](/platform/en/audience/segments#lists-and-tags)).

For how data from your sources and manual changes combine, see
[How unification works](/platform/en/data-sources/managing#how-unification-works) and
[Data composition](/platform/en/audience/contacts-profiles#data-composition).

**Manage subscription** follows the same rule: it writes the subscription with the same
priority as the panel, so a connector can't undo what the flow recorded.

## Manage subscription

**Manage subscription** records a change in the contact's subscription on a channel, the
same change someone on your team can make from the contact's profile. It has two
settings: the channel and the operation.

### Channel

**SMS** is the channel you can choose. SMS and RCS share one subscription, so the step
covers both, as the hint under the field says ("SMS and RCS share one subscription, so
this covers both."). **WhatsApp** is shown but can't be selected. How the shared
subscription works is explained in
[Shared consent (RCS & SMS)](/platform/en/consent/rcs-sms-shared-consent).

### Operation

A contact's consent on a channel is made of two separate settings: their **marketing
preference** (accepted, declined, or no preference) and **suppression** (subscribed, or
suppressed so that nothing reaches them on that channel). Both are explained in
[How consent works](/platform/en/consent/marketing-preference-vs-suppression). The four
operations come in two pairs: **Opt in** and **Opt out** set the marketing preference;
**Suppress** and **Reactivate** set the suppression. A new step starts on **Opt in**.

| Operation      | What the panel says                                                                                  | What changes                    | Which messages reach the contact afterwards                         |
| -------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------- |
| **Opt in**     | Records that the contact accepts marketing on this channel.                                          | Marketing preference → accepted | Messages under any consent policy, unless the contact is suppressed |
| **Opt out**    | Records that the contact refuses marketing. They still receive messages sent under the Basic policy. | Marketing preference → declined | Only messages sent under **Basic**                                  |
| **Suppress**   | Blocks every message on this channel, marketing or not. Only an admin or a flow can undo it.         | Suppression on                  | Nothing on SMS or RCS                                               |
| **Reactivate** | Lifts the suppression. Their marketing preference stays exactly as it was.                           | Suppression off                 | Whatever their marketing preference allows                          |

Which consent policy a flow message uses, and who each policy reaches, is explained in
[Sending messages](/platform/en/automations/flows/sending-messages#who-receives-it-the-consent-policy).

![Manage subscription settings with the four operations](/platform/en/automations/flows/images/contact-updates--1-manage-subscription.png)

### Each pair leaves the other alone

Because the two settings are independent, each operation changes only its own:

- **Opt in doesn't lift a suppression.** A suppressed contact still receives nothing on
  the channel after an **Opt in**. To bring back a suppressed contact who has now accepted
  marketing, use two steps: **Reactivate**, then **Opt in**.
- **Reactivate doesn't touch the marketing preference.** A contact who declined marketing
  and was later suppressed comes back still declined: only **Basic** messages reach them.
- **Opt out never turns into a suppression.** A STOP from the contact can end in
  suppression (see
  [Opt-outs & reactivation](/platform/en/consent/opt-outs-reactivation#from-opt-out-to-suppression)),
  but this step doesn't escalate: an **Opt out** applied to a contact who had already
  declined leaves them declined. Use **Suppress** when you want the hard block.

### What it doesn't do

The step changes the subscription and nothing else. In the panel's words: "It changes the
subscription and nothing else: it never replies to the contact and never triggers the STOP
keyword flow." No confirmation message is sent; if you want to confirm the change to the
contact, add a **Send message** step after it.

> **Warning**: Record an **Opt in** only when the contact has really accepted marketing — a reply, a
> form, an explicit request. A flow that opts in every customer who places an order makes
> your **Opt-in** messages reach people who never agreed to them, which defeats the purpose
> of the policy. The same goes for **Reactivate**: use it when there is a genuine reason to
> message the contact again.

## What else happens when a flow updates a contact

A flow's write is an ordinary change to the contact, so it has the same consequences as a
change coming from anywhere else:

- **It can start other flows.** Tag and list changes arrive as the **Customer created /
  updated** event, with the values in **Added tags**, **Added lists**, **Lost tags** or
  **Lost lists**; **Opt in** and **Reactivate** arrive as **Customer subscribed**, and
  **Opt out** and **Suppress** as **Customer unsubscribed**. A flow triggered on those
  events starts for this contact just as it would for a change from a connector (see
  [The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry#tags-lists-and-new-contacts)).
- **Waiting flows notice an opt-out.** If the contact is in another flow, sitting in a
  **Wait for activity** with an **Unsubscribed** branch, this step's **Opt out** and
  **Suppress** count there like any other unsubscribe: **Opt-out** catches **Opt out**,
  **Blocked** catches **Suppress**, and **Any**, the option the panel recommends, catches
  both (see [Waits](/platform/en/automations/flows/waits#wait-for-activity)).
- **A flow can trigger itself.** A flow that adds a tag and starts when a contact gains
  that same tag sends the contact back to the beginning. Its re-entry settings put a
  limit on how often that happens, but the simplest fix is not to trigger a flow on a
  value it writes itself (see
  [How often a contact can enter](/platform/en/automations/flows/triggers-and-entry#how-often-a-contact-can-enter)).
- **The next step can still see the old value.** The change takes a moment to reach the
  contact, so a step placed immediately after it, with no wait in between, can still read
  the value from before the update. That applies to a **Check tag**, **Check list**,
  **Check consent** or attribute split, and to a **Send message** right after **Manage
  subscription**: after an **Opt in** the message can be skipped because the contact
  still has no consent, and after an **Opt out** it can still go out. Put a **Fixed
  delay** of at least 1 minute between the update and any step that depends on it (see
  [Branches](/platform/en/automations/flows/branches#how-recent-the-information-is)).
- **The contact can leave the flow's own audience.** If who can enter the flow depends on
  a tag or list that the flow itself removes, and **Cancel the run if the contact leaves
  the audience** is on, the run is cancelled before one of the following steps (see
  [Goals and exits](/platform/en/automations/flows/goals-and-exits#other-ways-a-run-ends)).
- **Test runs write for real.** A test run is a real run of the draft for one contact, so
  these steps change that contact's tags, lists and subscription (see
  [Testing, publishing and versions](/platform/en/automations/flows/versions-and-publishing#what-a-test-run-checks-and-what-it-doesnt)).

## Example: an SMS that asks for marketing consent

A store wants to grow the list of customers who accept SMS offers, and asks them right
after a delivery. The flow *SMS offers opt-in*:

1. Starts on **Order delivered**.
2. **Send message**: "Your order has arrived. Would you like to receive our offers by SMS?
   Reply YES."
3. **Wait for activity**, with **How long to wait** set to 2 days and one specific branch,
   **Replied with text**, with the patterns `yes` and `y`.
4. In that branch: **Manage subscription** on **SMS** with **Opt in**, then **Update
   lists** with **Add** `sms-offers`.
5. **No interaction**: nothing — the contact simply reaches the end of the flow.

```mermaid
flowchart TD
    T["Trigger: Order delivered"] --> S["Send message: Would you like our offers? Reply YES"]
    S --> W{"Wait for activity (2 days)"}
    W -->|"Replied with text: yes / y"| M["Manage subscription: SMS · Opt in"]
    M --> L["Update lists: Add · sms-offers"]
    W -->|"No interaction"| E["Flow completed"]
    L --> E
```

What happens to three customers whose orders arrive the same day:

- **Anna** replies "Yes". The branch matches (matching ignores upper and lower case), her
  marketing preference on SMS becomes accepted — which also covers RCS — and she joins
  the `sms-offers` list. From now on, campaigns and flow messages with the **Opt-in**
  policy reach her (as long as she isn't suppressed), and you can target the list
  directly.
- **Leo** doesn't answer. After 2 days he takes **No interaction** and the run ends. His
  preference stays as it was: not answering is not a "no".
- **Martha** replies STOP. That isn't one of the patterns, so the branch doesn't match and,
  after the 2 days, she leaves through **No interaction**; her opt-out is recorded and respected by the
  usual STOP handling, independently of the flow. To give those contacts a path of their
  own, add an **Unsubscribed** branch to the wait.

Two things to check before publishing a flow like this. Replies are only possible where
contacts can answer an SMS, which depends on the market (see
[Opt-outs & reactivation](/platform/en/consent/opt-outs-reactivation#how-a-contact-opts-out)).
And the question itself is a message like any other, sent under the consent policy of its
own **Send message** step (see
[Sending messages](/platform/en/automations/flows/sending-messages#who-receives-it-the-consent-policy)).

## Related

- [How consent works](/platform/en/consent/marketing-preference-vs-suppression) - The marketing preference and suppression, and which messages reach each contact.
- [Branches](/platform/en/automations/flows/branches) - Route contacts by tag, list, segment, contact field, event, consent or an A/B split.
- [The trigger: who enters and when](/platform/en/automations/flows/triggers-and-entry) - Start a flow when a contact gains a tag, joins a list or changes their subscription.
- [Integrations & data sources](/platform/en/data-sources) - Where your contacts' data comes from and how sources are combined.

---

This is one page of the Instasent documentation. For the complete machine-readable index of every guide and API reference, fetch https://staging-instasent-docs-nextjs.oscar-284.workers.dev/llms.txt — start there for full context.
