Easymail keeps three things deliberately separate: list membership, list unsubscribes, and account-level opt-outs. Once you keep them apart, every question about who gets added to a list - and who actually receives your emails - has a clear answer. This guide walks through the rules one by one, including the most common ones: “If I add contacts to a list, will people who unsubscribed come back?”, “What’s the difference between removing and unsubscribing?”, “Who actually receives a campaign?”, “What happens if the contact already exists?”
TL;DR - will unsubscribed contacts come back?
“If I bulk-add to a list all contacts that match some filter (e.g. everyone who bought a product), will the contacts I previously removed jump back onto the list?”
No - people who genuinely unsubscribed from that list are NOT re-added. Bulk-add checks the list’s unsubscribe records and skips those contacts. Contacts already on the list are silently ignored (no duplicate), and everyone else is added.
But read the next section carefully, because “unsubscribed” and “removed” are two different things, and the answer depends on which one happened.
The mental model: three independent concepts
Almost every confusion comes from mixing up three things that Easymail keeps deliberately separate. Keep them apart and the rest of this guide is obvious.
| Concept | Question it answers | Reversible? |
|---|---|---|
| 1. List membership | Is this contact on this list right now? | Yes - add / remove freely |
| 2. List unsubscribe (consent) | Did this contact opt out of this list? | Permanent - never cleared automatically |
| 3. Account-level opt-out / suppression | Should this address receive any email? | Partly (see Rule 8) |
The critical insight:
- Removing a contact from a list only touches #1 (membership). It’s churn, not consent - the contact can be freely re-added later.
- Unsubscribing from a list creates #2 (a permanent unsubscribe record) and removes membership. That record is a permanent “do not put me back” marker that every bulk, import, and API add-path respects.
- Whether a campaign is actually delivered is decided only by #3 plus current membership - not by the list unsubscribe record (see Rule 3).
Rule 1 - Adding contacts to a list: does a past unsubscribe come back?
Short version: every mass or automated way of adding contacts skips people who unsubscribed from that list. They will not “jump back in.”
| How contacts get added | Skips list-unsubscribers? | Existing member? | Notes |
|---|---|---|---|
| Bulk-add by filter / segment (“add everyone who matches…”) | ✅ Yes, skipped | Ignored (no duplicate) | The path from the question above |
| Bulk-add a selected set of contacts | ✅ Yes, skipped | Ignored | Works the same way |
| CSV / file import (with target lists) | ✅ Yes, skipped | Ignored | Import still updates the contact’s fields - see Rule 5 |
| Public API - add contact to list | ✅ Yes, skipped | Ignored | External integrations can’t resurrect an unsubscriber |
| Easycart - “customers who bought product X” | ✅ Yes, skipped | Ignored | |
| Easycart - checkout / opt-in subscribe | ✅ Yes, skipped | Ignored | |
| Ticking a list checkbox on the contact card | ⚠️ No - NOT skipped | Not applicable (contact is added) | The single exception - see below |
⚠️ The one exception: ticking a list checkbox on the contact card
Opening a contact’s details and checking the checkbox next to a mailing list adds that contact to the list. This is the only add-path that does not check the unsubscribe record - it will re-add a contact who previously unsubscribed from that list.
Treat ticking that checkbox as a deliberate manual override, not a bug in your data. Use it only when the contact has explicitly asked you to put them back on the list.
Why “already a member” is always a no-op
All the bulk paths check whether the contact is already on the list before adding. Re-running a bulk-add is therefore safe to repeat as many times as you like: existing members aren’t duplicated, aren’t re-dated, and don’t get a second welcome - they’re simply skipped.
Rule 2 - “Remove from list” ≠ “Unsubscribe”
This is the distinction behind most of the confusion.
| Action | Who does it | Membership | Permanent unsubscribe record? | Can they be re-added? |
|---|---|---|---|---|
| Remove from list (in the app or via the Public API) | You / your integration | Removed | ❌ No | ✅ Yes - freely (it’s just churn) |
| Unsubscribe from list (email footer / preference center / Easycart) | The recipient | Removed | ✅ Yes (permanent) | ❌ No - bulk, import and API paths will keep skipping them |
Key rule: you taking someone off a list is not consent, so it never creates an unsubscribe record - a later import legitimately re-adds them. Only a genuine recipient-initiated unsubscribe creates that record. This is why the “clean up the list, then re-import” workflow works without wiping your real opt-outs.
Two nuances worth knowing:
- The unsubscribe record is never cleared. Even if a contact later re-subscribes through the preference center, the record stays. Consequence: they can be an active member and still carry an old unsubscribe record - they’ll get email (see Rule 3), but bulk-add and import will keep skipping them. This is intentional: the per-list opt-out history stays clean for reporting.
- The preference-center “Unsubscribe” button (and Gmail’s one-click unsubscribe on a private list) is treated as an account-level opt-out, not just a single-list one - see Rule 8.
Rule 3 - Who actually receives a campaign
When a campaign sends, the recipient list is built from current list membership, minus these four gates. A contact is excluded if any of them matches:
- Deleted contacts.
- Account-level unsubscribe - the contact opted out of everything from your account.
- Email-address opt-out - this email address is opted out for your account (survives contact deletion - see Rule 8).
- Suppression list - this address hard-bounced or was flagged by the email provider (this one is platform-wide - see Rule 8).
Important - the list unsubscribe record does NOT block sends. Sends are driven purely by membership plus the four gates above. So:
- If a contact is a member of the targeted list and passes the four gates, they get the email - even if they carry an old list unsubscribe record (e.g. they re-subscribed via the preference center).
- Removing a list unsubscribe record would not stop a send; removing membership (or an account-level opt-out) is what stops it.
This is deliberate: membership is the source of truth for sends. Don’t try to “also exclude the unsubscribe records” when reasoning about audience size - membership already reflects who’s really on the list.
Note for automations: automation (workflow) sends use a similar but separate suppression set - they additionally honor automation-specific opt-outs. Campaign audience rules are the ones described here.
Rule 4 - One person = one email per campaign
A contact can be on several lists, but a campaign targets a single list, and the recipient snapshot is keyed by contact. Even when a segment filter references several lists, each contact resolves to exactly one recipient.
Bottom line: nobody gets two copies of the same campaign because they’re on two lists.
Segments, by the way, are evaluated live at send time - the campaign re-runs the segment’s filter against the current contact set when it sends, and applies the same four mailability gates. So a contact who left the segment (or got suppressed) after the campaign was set up but before it sent is correctly excluded.
Rule 5 - Adding a contact that already exists (matched by email)
Contacts are unique per account, by email, case-insensitively
- A contact is unique within your account by email. The same address cannot exist twice in one account.
- Email is lowercased and trimmed before it’s stored or matched, so
John@X.comandjohn@x.comare the same contact. - A deleted contact’s email doesn’t block reuse - you can re-create a contact with an address that a deleted contact used.
What happens when the email already exists depends on the path
| Path | If the email already exists |
|---|---|
| CSV / file import | Updates the existing contact (overwrites standard fields - see the gotcha below) |
| Easycart sync | Updates the existing contact |
| Public API - create contact | Rejected with an “email already exists” error (create-only; use the update endpoint to change it) |
⚠️ Import gotcha: blank standard fields overwrite; blank custom fields don’t
When an import updates an existing contact:
- Standard fields (first name, last name, phone, language, country, timezone) are overwritten - including with blanks. If your import file has an empty “first name” column, it will erase the existing first name. The “paste a list of emails” import carries no names at all, so re-importing that way wipes existing names. (Contacts that originated from Easycart are protected - import won’t overwrite their name or phone.)
- Custom fields are only ever set to non-empty values - a blank cell is skipped, never blanks out an existing value.
Practical guidance: when you re-import to update a subset of fields, only include the columns you actually want to change, or you’ll blank out the rest.
Note: within a single CSV, duplicate rows for the same email aren’t handled deterministically. Don’t rely on “last row wins” inside one file - de-duplicate your file first.
Rule 6 - Double opt-in (subscription confirmation)
- Double opt-in applies only to the public sign-up form flow. API-created and CSV-imported contacts are added directly, with no confirmation step.
- Before someone clicks the confirmation link, there is no contact record and no list membership - nothing “pending” is stored.
- The contact is created and added to the list only when they click confirm.
- It’s driven per sign-up request against a specific list - there is no per-list or account-wide “double opt-in” toggle.
So: an unconfirmed sign-up can’t receive anything because it doesn’t exist yet - double opt-in gates creation, not sending.
Rule 7 - Custom fields
- Custom fields are defined per account (field keys are unique within your account).
- A CSV import or Public API call that references a custom field which doesn’t exist is rejected with an error - it does not silently create the field or ignore it. Create the field first, then import.
- The Easycart sync is the exception: it auto-creates custom fields on the fly (it’s the trusted internal e-commerce sync, not user-driven import).
Rule 8 - Account-level opt-out & suppression, in detail
Three mechanisms, three different scopes. All three block campaign delivery (Rule 3); they differ in how far they reach and how they’re set.
| Mechanism | Scope | Keyed by | Set by | Cleared by |
|---|---|---|---|---|
| Account unsubscribe | Your account | Contact | Unsubscribing in the app, preference-center “Unsubscribe”, private-list one-click unsubscribe, Public API | Resubscribe |
| Email-address opt-out | Your account | Email address | Mirrored automatically whenever an account unsubscribe happens | Resubscribe |
| Suppression list | Platform-wide | Email address | Hard (permanent) bounces and complaints flagged by the email provider | Not clearable in the app - contact us if you believe an address was suppressed by mistake |
Key points worth internalizing:
- Account unsubscribe vs. email-address opt-out: the first is tied to a contact record; the second is tied to the address. If a contact is deleted and later re-imported (brand-new record, same email), the contact-level record is gone but the address-level opt-out still blocks them for your account. This is intentional - deleting and re-adding a contact does not wash away their opt-out.
- The suppression list is platform-wide and append-only. One hard bounce or provider-level complaint blocks that address everywhere, and there’s no in-app way to un-suppress. This protects sending reputation for everyone.
- Ordinary spam complaints do not auto-suppress or auto-unsubscribe - they’re recorded as events for statistics only. Only hard (permanent) bounces and provider-level suppression complaints suppress an address.
- Resubscribe (in the app or via the Public API) clears the account unsubscribe and the email-address opt-out for your account. It does not touch the suppression list, does not delete any list unsubscribe record, and does not re-add the contact to any list - it only lifts the account-level opt-out.
Quick FAQ
Q: I removed some contacts from a list, then bulk-added everyone matching a filter. Will the removed ones come back? Depends on how they left. If you removed them (churn) - yes, they come back. If they unsubscribed themselves - no, they’re permanently skipped. See Rules 1 & 2.
Q: Someone unsubscribed from a list but is still getting my campaigns. Why? They must be a current member again (e.g. they re-subscribed via the preference center, or were re-added by ticking the list checkbox on their contact card - the exception in Rule 1) and not account-level opted-out. Sends follow membership, not the list unsubscribe record. See Rule 3.
Q: If a contact is on three lists, do they get three copies of a campaign? No - a campaign targets one list and counts each contact only once. One email. See Rule 4.
Q: I re-imported my customers to update phone numbers, and now everyone’s first name is blank. What happened? The import overwrote standard fields with the blank cells in your file. Only include columns you intend to change. See Rule 5.
Q: I deleted a contact who had complained, re-added them, and they still don’t get email. Why? Their address is likely still opted out at the email-address level (which survives deletion) or on the suppression list (from the bounce or complaint). Re-adding a contact doesn’t clear either. See Rule 8.
Q: Does adding a contact via the API go through double opt-in? No - only the public sign-up form does. API and CSV add directly. See Rule 6.