Importing a list
Upload a file or sync from WinRed or Anedot. A list has one of four sources:
A list is
processing while the import runs and ready when it is done. You
cannot send to a list that is not ready; the API returns
409 EMAIL_LIST_NOT_READY.
Where the uploader lives
Every file you upload to the platform now goes through one page: Assets > File Uploads. Pick Email recipients as the kind and drop the file: the file you upload is the list, named after the file unless you rename it, so there is no list to create first. Name it, choose whether it is available to every campaign or only to one sending domain, then map the columns and record consent. Texting contacts, opt-out numbers, email unsubscribes, texting media, and email images are the other kinds on the same page. A campaign combines lists by attaching several of them, exactly as a texting project attaches contact lists, so there is no reason to import two files into one list. The old Email > Lists > Import link still works and redirects to the uploader with the kind already selected, so existing bookmarks are fine.Importing over the API
POST /v1/email/lists/import does the whole thing in one call: give it an
HTTPS URL to a CSV you host, and it fetches, stages, and commits it as a new
list. name defaults to the file name; email_domain_id scopes the list to one
sending domain, and omitting it leaves the list available to every campaign.
consent.source is one of donation_form, petition, signup_form, event,
purchased, rented, or other. It is the same attestation the wizard asks
for, and the same reasons to answer honestly apply.
mapping is optional. Leave it out and the platform uses the mapping it
recognizes from the export’s own headers, which is what you want when the file
came from a common ESP. If neither your mapping nor the recognizer finds an
email column, the call returns 400 VALIDATION_ERROR and details.headers
lists the headers it read, so the retry can name the right column instead of
guessing.
The response is 202 with an import id; the import runs in the background and
its progress and row counts are shown on the list in the dashboard, and in the
import summary over the API. The request takes no options: sending that
field returns 400 VALIDATION_ERROR.
What import removes and holds back
Every import, from the uploader or the API, applies the same checks:- Malformed addresses are rejected and reported.
- Likely typos in the domain are skipped, not corrected. A row whose domain
is a known misspelling of a major mailbox provider, such as
gmial.com, is counted in the import summary as “Likely typo in the domain”. Fix the address in your file and import it again. - Role addresses such as
info@,admin@, andsales@are always removed. They reach a shared inbox rather than a person and complain at a far higher rate than personal addresses, so there is no option to keep them. - Disposable addresses from throwaway-mailbox services are removed. The list we check covers several thousand such domains.
- Addresses that cannot receive mail, such as a domain with no mail server, and addresses that already bounced or complained on this platform, are removed, as are duplicate rows in the same file.
- Addresses currently held by screening are imported but held back, and the
import summary reports them as
screened. See Address screening at send time.
Donor syncs and segments
Two of the four sources are worth calling out because they are not files: WinRed and Anedot syncs build an email list from your donor records automatically, so people who give keep arriving on the list without anyone exporting a CSV. Consent comes from the donation form itself, which is the cleanest provenance an email list can have. Create one from Email > Lists > New dynamic list (or from Contact Management); one connection feeds both a text list and an email list, and the email list’s page shows the connection details and settings. The same picker offers Recent openers and Recent clickers: lists of everyone who opened or clicked a campaign in a window you choose, refreshed nightly. A refund can park a donor off the list, and a later gift brings them back; retention works the same way. These lists are managed through the connection rather than deleted, so the Delete action is not offered on them. Segments are lists built from contacts already in the platform, using rules rather than a file. Engagement rules are the useful ones: everyone who opened in the last 30 days, everyone who clicked a particular campaign, everyone who has not engaged in 90 days. Giving rules read your synced donations: total given, recurring, gave recently, number of gifts, any single gift above an amount, and the donation source (refcode, source code, UTM parameters, page name). Giving is counted net of refunds: a refunded or charged-back gift does not count toward a total or a gift count, and a gift that arrives through both a webhook and a scheduled report is counted once. A random split rule takes a stable slice of a list, so two segments with 0-50 and 50-100 never overlap; that is how you run two campaigns against halves of one list. Because a segment is defined by its rules, it reflects the current state of your contacts each time you use it rather than a snapshot from the day you built it, and it can refresh nightly.Consent attestation
Every list requires a consent attestation when you create it: a short statement of how the people on it agreed to hear from you, plus an optional note. This is not a checkbox to click past. It is the record you will want if a complaint is ever escalated, and the honest answer determines what happens next. A list from your own donate-page opt-in behaves differently from a list you bought.Acquired lists
If a list came from anywhere other than your own sign-up flow, set itsacquired field. Doing so is in your interest, not against it: an acquired list
that is not declared is far more likely to trip a deliverability breaker
mid-send and pause your campaign.
An acquired list is not blocked from sending. Declaring it has one consequence:
warm-up runs on half steps. The daily ceiling is halved at every stage of
the warm-up ramp, so a
list with less certain provenance reaches mailbox providers more slowly.
Address screening at send time
There is no separate cleaning step and no charge for one. Every campaign email is screened as it is sent, using the strictest setting of the mail provider’s automatic validation. An address it rates as likely undeliverable is not sent to. What happens to a screened address:- The message is recorded with status
suppressedand reasonauto_validation. - It is not counted as a bounce, so it does not count toward your bounce
rate or the deliverability breakers,
and it does not fire the
email.bouncedwebhook. - The address is held out of all sends on the platform for 90 days, for every organization. After 90 days it is checked again on its next send.
- The campaign report shows the total as Screened as invalid.
- You are billed the normal per-recipient email rate for it, the same as a bounce, because the message was handed to the mail provider.
Exporting a list
Export on the list page downloads a plain contact export: the columns from the file you uploaded, in the order they arrived, followed byemail, status,
and status_reason. There are no verdict columns and no state filters.
Contact statuses
Only
subscribed contacts are mailed. The rest are excluded automatically, and
none of them can be restored by re-importing the same file.
Removing contacts
Removing an address unsubscribes it rather than deleting the row, because the row carries the bounce and complaint history that makes suppression survive your next import. To erase an address entirely, use forget this address.Suppressions and the sunset policy
Suppressions, bounces, complaints, unsubscribes, and the 90-day hold and 180-day sunset all work the same way regardless of which list an address is on, so they have their own page: Bounces, complaints, and suppressions. The short version: an address that bounces permanently or complains is suppressed for you automatically, unsubscribes are honored immediately, and contacts who have not engaged in 90 days stop being mailed before they can damage your reputation. Opening or clicking one of your emails counts as engagement and starts that clock over.Bulk contact upsert over the API
POST /v1/email/lists/{id}/contacts takes up to 1,000 contacts per call and
returns a per-row outcome, so one bad address does not cost you the batch:
rejected.