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

# Double Opt-In: How Two-Step Subscription Works

Double opt-in (DOI) is a two-step subscription confirmation flow for your email marketing program. With DOI turned on, new subscribers don't receive your campaigns until they click a confirmation link in a dedicated opt-in email. This guide explains how DOI works in Maestra, how to switch it on, how subscription statuses change once DOI is active, how to build a welcome flow around it, and how to turn DOI off again.

<Note>
  Double opt-in is widely considered a best practice for email deliverability and US anti-spam compliance (CAN-SPAM, CCPA-aligned consent records). It proves the subscriber actually owns the address they gave you and protects your sending reputation from typos, bots, and spam traps.
</Note>

## What double opt-in is

Double opt-in means a customer does not start receiving your campaigns until they explicitly confirm their subscription by clicking the link in the opt-in email you send them.

Until they click that link, their subscription stays in the **Requires confirmation** status. Once they click, the status flips to **Subscribed** and regular campaigns start flowing.

Two concepts are related but distinct in Maestra:

* **Subscription confirmation (DOI)** — the customer's consent to receive campaigns in a given channel. It's tied to the channel (and optionally topic).
* **Contact confirmation** — proof that a specific email address or phone number belongs to a specific customer. It's tied to the contact itself, not to a channel.

You can confirm both in a single click by attaching an email-confirmation ticket to your opt-in link (see step 4 below).

## Turn on double opt-in

<Steps>
  <Step title="Open email settings">
    Go to **Settings → Campaigns → Email settings**.
  </Step>

  <Step title="Enable subscription confirmation">
    Check the **Subscription confirmation** box and save.
  </Step>

  <Step title="Create the opt-in campaign">
    Create the campaign that the workflow will send.

    In the campaign settings, the **Subscription confirmation** profile must be selected. Then, in the template, mark the relevant link as the confirmation link for the channel or topic.

    <Tip>
      There's a second approach if you also want to confirm the contact (email address) at the same time. In the template, add an email-confirmation ticket to the link:

      ```
      ?direct-crm-ticket=${Ticket.EmailConfirmationLinkTicket}
      ```

      The ticket only subscribes customers whose subscription status is **Requires confirmation**. If the customer was already **Unsubscribed**, clicking the ticketed link does not change their subscription.
    </Tip>
  </Step>

  <Step title="Build the flow">
    Create a flow with the trigger **Subscription status changed to "Requires confirmation"** in the email channel.

    Specify a topic only if you want confirmation for a specific topic. For channel-level confirmation, leave the topic empty.

    In the **Steps** block, choose **Send email** and pick the opt-in campaign you built in the previous step.
  </Step>

  <Step title="Build a confirmation landing page">
    On your site, add a dedicated page with the main tracker code installed. This is the page customers land on after clicking the confirmation link — typically a short "Your email is confirmed" message and a button back to the store.
  </Step>
</Steps>

<Warning>
  Switching the project to double opt-in does **not** change the subscription status of customers who are already in your database. DOI applies to subscriptions created or changed after the switch.
</Warning>

## How email subscriptions change once DOI is on

With DOI active, a customer's email subscription can be in one of four statuses: **Subscribed**, **Unsubscribed**, **Requires confirmation**, or **No data**. How an incoming change is interpreted depends on which channel of data delivery it came through.

### API operations

**Register** — creates a new customer. You can't pass an unsubscribe here, only brand, channel, and topic.

* Any status → **Requires confirmation**

**Create and subscribe to campaigns** — always creates a new customer. If the customer already exists, a merge happens and the subscription follows the merge rules.

* Any status → **Requires confirmation**

**Import** — depends on what you pass in `/customer/subscriptions/subscription/isSubscribed`:

* `true` → **Subscribed**
* `false` → **Unsubscribed**
* No subscription block → **No data**

**Customer — Authorized — Edit** — only works on customers that already exist:

* `true` → **Subscribed**
* `false` → **Unsubscribed**

**Customer — Authorized — Append** and **Customer — Unauthorized — Register or Append** — you can't pass an unsubscribe here:

* Any status → **Requires confirmation**

### File import

**Customer import** — if the customer is new, you can add a subscription in any status, or skip subscription entirely (status will be **No data**). If the customer already exists, you can move them from any status to **Subscribed** (`true`), **Unsubscribed** (`false`), or **Requires confirmation** (`WaitingForConfirmation`). You can't move a customer back to **No data**.

**Data edit import** — you can move any customer from any status to **Subscribed**, **Unsubscribed**, or **Requires confirmation**. You can't move back to **No data**. For bulk subscribe/unsubscribe, follow the mass subscription guide.

### Flows

When a flow edits a customer, the system automatically logs an action *"Customer edit in flow block 'Flow name' — 'Step description'"*.

Subscribing to the email channel is not available inside flows. You can only unsubscribe a customer or move them to **Requires confirmation**.

| Flow type                   | Before → After                         |
| --------------------------- | -------------------------------------- |
| Flow requiring confirmation | Any status → **Requires confirmation** |
| Flow with unsubscribe       | Any status → **Unsubscribed**          |

### Polls

**Poll with subscription:**

| Before                | After                 |
| --------------------- | --------------------- |
| Subscribed            | Subscribed            |
| Unsubscribed          | Requires confirmation |
| Requires confirmation | Requires confirmation |
| No data               | Requires confirmation |

**Poll with unsubscribe:**

* Any status → **Unsubscribed**

### Branded unsubscribe page

When the customer ticks a topic checkbox and saves:

* Any status → **Subscribed**

When the customer unchecks a topic or unsubscribes from everything:

* Any status → **Unsubscribed**

### Manual change in the customer card

You can move a customer from any status to **Subscribed**, **Unsubscribed**, or **Requires confirmation**. You can't move back to **No data**.

## Welcome flow with subscription confirmation

A typical DOI welcome program has two trigger events — a new customer landing in your database, and a customer confirming their subscription. Build a separate flow for each.

Before you start, prepare your campaigns:

* An automated opt-in campaign for the confirmation request and the reminder (both must use the **opt-in** profile).
* An automated welcome campaign that goes out after confirmation (standard profile).
* Configure the confirmation link setting on the relevant links so a click confirms the subscription.

### Flow 1 — request subscription confirmation

<Steps>
  <Step title="Set the trigger">
    Trigger on a subscription change — specifically, when the customer enters the **Requires confirmation** status in the email channel.

    **What counts as entering this status:**

    * Status became "Requires confirmation," including implicitly.
    * Status went straight to "Requires confirmation."
    * Customer appeared already in this status.
    * Status returned to "Requires confirmation."

    **What does not count:**

    * An implicit "Requires confirmation" became explicit.
    * After a merge, the primary customer ended up in this status.

    Depending on your business case, other valid triggers include action issued with templates from specific operations, customer registered, or new customer.
  </Step>

  <Step title="Limit re-entry">
    In the start block, limit the flow to one trigger per customer.
  </Step>

  <Step title="Check the contact">
    Verify that the contact exists and is valid. You don't need to check the subscription status here — the trigger event already guarantees it. If you use a different trigger, add a filter for **Subscription — Requires confirmation in the Email channel**.
  </Step>

  <Step title="Send the confirmation email">
    Send the opt-in campaign you prepared.
  </Step>

  <Step title="Wait 24 hours">
    Add a one-day wait step.
  </Step>

  <Step title="Send a reminder if still unconfirmed">
    If the subscription is still in **Requires confirmation**, send the reminder campaign.
  </Step>
</Steps>

### Flow 2 — welcome email after confirmation

When the customer clicks the confirmation link, the system automatically issues an action *"Customer subscription to channel"* (or *"Customer subscription to topic"* if the link is topic-scoped). Trigger this flow on that action.

<Steps>
  <Step title="Trigger and limit">
    Trigger on the subscription action and limit to one run per customer.
  </Step>

  <Step title="Check the click and the contact">
    Verify there was a click in the campaign and that the customer is subscribed with a valid contact.

    If you only have one confirmation flow, you can skip the extra checks. But if you run multiple confirmation campaigns — for example, separate flows for different topics — these checks matter, because the same action template is issued in every case.
  </Step>

  <Step title="Send the welcome email">
    A few ideas for the welcome email:

    * Recommend popular products, or browsed products if you have them.
    * Offer a promo code or loyalty points as a thank-you for subscribing.

    Useful campaign parameters:

    * Recommendations — `Recipient.Recommendations.{algorithm name}`.
    * Promo code — `Recipient.LastReceivedPromoCode.WithType{pool name}.Value`.
    * Point expiration date — use `AddDays` to add the relevant number of days to `Message.SendingDateTime`.

    Use A/B testing to compare variants and pick the best performer.
  </Step>
</Steps>

## Turn off double opt-in

If you need to disable subscription confirmation, do this in order:

<Steps>
  <Step title="Remove opt-in campaigns">
    DOI can't be turned off while opt-in campaigns are still active. Find and remove or reconfigure them.

    Use the event log filter to find campaigns with the opt-in profile. Switch the profile to anything that does not include **Send only to customers awaiting subscription confirmation** — for example, the **Standard** profile. If a campaign can't be edited, delete it.

    <Note>
      For multi-brand projects: only remove opt-in campaigns in the brand where you're turning DOI off.
    </Note>
  </Step>

  <Step title="Disable confirmation">
    Go to **Settings → Campaigns → Email settings** and uncheck **Subscription confirmation**.

    <Warning>
      Customers who used to land in your database with **Requires confirmation** status will now arrive as **Subscribed** and start receiving campaigns immediately.
    </Warning>
  </Step>

  <Step title="Subscribe existing customers if needed">
    Turning DOI off does **not** automatically subscribe customers who are already sitting in **Requires confirmation**. To move them to **Subscribed**, edit them using a data edit import.
  </Step>
</Steps>
