What should you check before importing subscribers?
Preserve the export as evidence, map the destination fields and inspect exceptions before changing any account. Buttondown's import guide describes source detection and manual mapping for subscriber data. Its API import documentation distinguishes new, existing and rejected subscribers in the result. Upload acceptance and a successful migration are therefore different checkpoints.
This article supplies a local inspection step, not a destination-specific import format. The fixture's status and consent columns are our teaching schema. They must be mapped and verified against the actual service rather than uploaded unchanged.
Reproduce the 16-row inspection
The synthetic file includes one duplicate, a quoted comma, a UTF-8 name, pending and unsubscribed states, a future join date, malformed email shapes, an unknown status, a formula-like field and an invalid date. Addresses use the reserved .invalid namespace. They are not a live audience.
The executed inspector found 16 rows, 13 unique shape-valid addresses and one exact duplicate. Seven rows received issue flags. It prints aggregates and row numbers, avoiding contact values in the report. It reads local files only and creates no transformed import file.
python3 inspect-newsletter-csv.py subscribers.synthetic.csv- Synthetic inspection input · CSV
- Read-only local inspector · Python
- Actual local inspection output · JSON
- Definitions and limitations · Markdown
Map meaning, not just column names
- Identity: establish which field is the address and how duplicates should be reviewed. The supplied script uses exact-address keys; it does not merge aliases or change address case.
- Status: keep active, pending, unsubscribed and suppressed states distinct. A name resembling “subscribed” is insufficient without its source definition.
- Dates: distinguish join date, confirmation date and import time. The script pins its comparison date to 10 October 2026 for reproducibility.
- Metadata: confirm how tags, commas and empty fields map. Python's CSV reader handles quoted fields; splitting every line on commas does not preserve the fixture's structure.
- Review exceptions: decide how a real destination should treat each flagged row before preparing a small authorized test.
What this validator cannot establish
The email check tests shape only. It does not prove that an address exists, belongs to a person, can receive mail or has given permission. The local “confirmed” labels are invented. The script does not assess all possible cross-row state conflicts, provider-specific field limits or every spreadsheet hazard. Formula-prefix flags are review prompts; no spreadsheet was opened or formula executed.
Do not interpret its “local review ready” count as subscribers you may contact. That count merely satisfies the fixture's stated local rules. The separate subscriber-count worksheet explains why an export count is also not automatically a billing count.
Close the migration loop
After an explicitly authorized small native import, inspect the resulting records, rejected rows, original statuses and required fields. Keep the original export and a reconciliation summary. Subscriber records, published archives, paid access and recurring payments are separate migration tasks. None of these provider actions was executed for this guide.
Use the newsletter trial pack for the wider workflow brief and the platform comparison for dated plan scopes. The local CSV checks add a preparation step rather than claim a completed migration.
Sources and scope
- Buttondown: importing your newsletter data · Read 10 October 2026.
- Buttondown: import API semantics · Read 10 October 2026.
- Python CSV documentation · Read 10 October 2026.
- RFC 2606: reserved names · Read 10 October 2026.
Factual explanation and local teaching examples. Source reads and local executions have separate scopes. No native provider workflow, send, payment, deliverability result or comparative winner is claimed. Send a correction.