Import and Export
A site that can bring its audience in can take it out again. This page covers importing a CSV from another tool, in the admin or on the command line, and exporting the subscriber list. Both need mailroom.manage.
Import a contact list
Open Subscribers and press Import ("Import a contact list").
- Choose a CSV file: a comma or semicolon separated file with a header row. Exports from EmailOctopus arrive as a ZIP; unzip it first.
- Which column is which. Pick a field above each column: Email address, Full name, First name, Last name, Tags, Status, Subscribed date or Language, or Ignore this column. A file Mailroom recognizes (an EmailOctopus export) arrives with the columns already matched, and headings that plainly name a field (
email,E-mail,Email address,Name,First name,Surname,Tags,Status,Languageand the like) are picked for you. One column must be the email address, and each field can come from one column only. - What the first rows become. The first twenty rows, read exactly as the import would read them. A row it would refuse says why.
- Where it goes:
- Add them to: a list, or No list, subscribers only.
- Ask everybody to confirm: leave this off for an export from another tool, since those people confirmed there. Turn it on only for a list you are not sure about; everybody is then imported waiting to confirm and emailed a confirmation.
- Tag everybody in this file: optional, and worth doing, since it is how you find this batch again.
- Where did these people agree?: optional, such as "Signed up on the old site, 2019 to 2024". Kept in each person's consent history as how they came to be on the list. Left empty, the file's name is kept instead.
- Read the dry run above the button: "Running it now would add N new, find N already here, skip N and leave N suppressed", with the reasons. It counts again when you change the list.
- Press Start the import.
The import is queued and runs on the worker, so a big file does not need the browser left open. The screen shows its progress ("N of N rows"), and Past imports keeps every run with its file, list and counts. The uploaded file is deleted as soon as its import finishes; a file whose import never ran is swept after Keep Uploaded Files For (import.keep_days, 30 days, on the Signup tab).
Note
Imports need the worker. A site with no job queue running says "This site has no job queue running, so an import cannot be started." See Jobs and cron.
What happens to each row
| Row | What happens | Counted as |
|---|---|---|
| No address, or one that is not an address | Skipped | Skipped |
| The same address earlier in the file | Skipped | Skipped |
Status pending (never confirmed at the old tool) |
Skipped, whatever Ask everybody to confirm says | Skipped |
Status unsubscribed |
The address is suppressed (reason Added by hand, note import: {file}), and a known subscriber is taken off every list |
Suppressed |
| An address that bounced or complained here before, or is suppressed | Nothing is written | Suppressed |
| Somebody who left the list, or every list, themselves | Nothing is written | Skipped |
| Anybody else | A subscriber, joined to the list, with source Imported and the file name | New, or Already here |
Status words are read loosely: unsubscribed, unsub, opted out, cleaned and removed all mean unsubscribed; pending, unconfirmed and awaiting confirmation mean pending; anything else is subscribed.
An import never downgrades anybody: somebody already subscribed stays subscribed, and a membership they already hold keeps how they joined. Each row is written on its own, so an import that stops partway leaves the rows it reached; running the same file again changes nothing the first run already did.
Import on the command line
For a file already on the server, import:csv runs the same importer in the foreground and prints what it did:
bin/plugin mailroom import:csv contacts.csv --dry-run
bin/plugin mailroom import:csv contacts.csv --list=newsletter --tag=october-import --basis="Signed up on the old site"
bin/plugin mailroom import:csv export.csv --preset=emailoctopus
bin/plugin mailroom import:csv contacts.csv --map email="Email address" --map name="Full name"
| Option | What it does |
|---|---|
--list |
The code of the list everybody joins. Default: the default list. |
--preset |
Read the file as another tool's export: emailoctopus. |
--map field=column |
A column mapping, repeatable. Fields: email, name, first_name, last_name, tags, status, subscribed_at, language. |
--tag |
A tag put on everybody in the file. |
--basis |
Where these people agreed, kept in each consent history. Default: the file name. |
--as-confirmed |
Treat everybody as already confirmed. This is the default. |
--ask-to-confirm |
Import everybody as waiting to confirm and email each a confirmation. |
--dry-run |
Read the file and report, writing nothing at all. |
It prints the file, preset, list, consent and basis first, then the counts (rows read, new, already here, skipped, suppressed) and the reasons. The run is kept under Past imports like one from the admin.
Export
Export CSV above the Subscribers table downloads the people the current filters match. The same file from the command line:
bin/plugin mailroom export:csv --file=subscribers.csv
bin/plugin mailroom export:csv --status=subscribed --list=newsletter > newsletter.csv
bin/plugin mailroom export:csv --status=subscribed | wc -l
| Option | What it does |
|---|---|
--file |
Where to write. Standard output when not given. |
--status |
pending, subscribed, unsubscribed, bounced or complained |
--source |
form, import, api, admin or automation |
--list |
Only people on this list, by code |
--tag |
Only people carrying this tag, by code |
--search |
Only addresses or names containing this |
The file has ten columns: email, name, status, lists, tags, source, consent_at, confirmed_at, unsubscribed_at, language. It starts with a byte order mark so spreadsheets read it as UTF-8, and it is streamed a line at a time, so a large list exports on the same server that serves the site.
For everything held about one person, including their consent history, use Export their data on their page instead (see Privacy).