Medium → Substack
Move Medium stories into Substack with the URL importer, then bring a consented email list separately. Medium followers are not a mailing list. Imported posts publish immediately and often keep Medium chrome at the bottom.
Should you make this move?
Both platforms have a case. Compare what you gain with what you give up before scheduling the cutover.
Medium
- Built-in distribution and a distraction-free editor remove nearly all publishing operations
- Editors get a purpose-built publishing workflow instead of raw files
- Brand, audience, monetization, and content control remain with the platform
- Themes, extensions, and content models add maintenance and portability constraints
Substack
- Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box
- Audience, campaigns, automations, and reporting live in one publishing system
- Brand control, automation, data depth, and platform independence are limited
- Automation logic, analytics history, and deliverability settings are not very portable
Substack: Publishing, email, recommendations, network discovery, and paid subscriptions work out of the box. This removes a major source-side concern: Brand, audience, monetization, and content control remain with the platform.
What you lose: Built-in distribution and a distraction-free editor remove nearly all publishing operations. What you inherit: Brand control, automation, data depth, and platform independence are limited.
Jump to a section
Know the shape of the move.
This timeline assumes
- One Medium profile or publication with up to 1,000 stories and a separate consented email list you can lawfully export
- You control the Medium account, the Substack publication, DNS if you use a custom domain, and any list you import.
- Medium remains public until you prove images no longer load from Medium.
- No full-audience Substack email goes out until content, consent, redirect, and seed-delivery checks pass.
- Claps, highlights, Medium followers, and Partner Program earnings stay out of scope.
What survives the move.
“Partial” and “manual” are not footnotes. They are work that must be scheduled and verified.
| Item | Outcome | Impact | What happens | Mitigation |
|---|---|---|---|---|
| Published stories | partial | critical | Substack lets you paste a Medium URL such as https://medium.com/@you. The importer finds the archive and publishes every imported post. You cannot pick which posts appear. You can delete individual posts later. | Import first. Review titles, dates, and paywall flags before you import any emails. |
| Story body and Medium chrome | partial | high | Substack says imported posts may keep a platform subscribe option or banner at the bottom. Embeds, paywalled sections, and footnotes often need a pass in the Substack editor. | Open a sample of public, member-only, and embed-heavy stories. Delete leftover Medium chrome before any send. |
| Images | partial | critical | The importer can leave image hosts on Medium. A Medium export zip of HTML files is the backup if the URL import is thin. | Keep Medium online. Re-upload any image that still points at Medium or miro.medium.com. |
| Medium followers | lost | critical | Followers are not a portable consented subscriber file. Substack only imports emails you upload and confirm opted in. | Import only addresses you can lawfully export with consent evidence. Do not invent a list from follower counts. |
| Email list and paid comps | manual | critical | If you have a real mailing list, Substack imports CSV, XLSX, or ODS. Duplicates and invalid domains are skipped. Paid readers from another platform are comps or trials unless you run a Stripe takeover path Substack documents for that source. | Pause the old sender first. Confirm opt-in. Skip the welcome email. Comp paid readers against recorded renewal dates. |
| Import review holds | manual | high | Substack can flag a list for Standards review, often within 72 hours, if it looks like it was not opted in. | Answer the origin questions. Do not send until the import is approved. |
| Publication dates and drafts | partial | high | Imported posts go live as published. If you paste by hand, Substack tells you to reset the publication date in post settings after you publish. | Compare dates against the Medium export. Unpublish anything that should stay draft. |
| Canonical URLs and redirects | manual | critical | Medium paths do not become Substack /p/ slugs. Substack has no in-app redirect table. | Map every public Medium URL. Add provider redirects if you own a custom domain. |
| Claps, highlights, responses, and stats | lost | medium | Medium engagement does not become Substack likes, comments, or analytics. | Export Medium stats if you still need them. Tell readers comments will not follow. |
| Publications, editors, and Partner Program | lost | medium | Medium publication roles and Partner Program earnings do not move. | Create Substack staff separately. Archive earnings reports before you leave. |
| Custom domain and From address | manual | high | A Substack custom domain is a separate setup. Newsletters still send from [email protected] unless Substack documents a change for your account. | Add the domain in Substack before you change DNS. Bookmark the *.substack.com settings URL. |
| Sending overlap | manual | critical | If you import emails while Medium or another sender still mails the same people, you send twice. | Pause the old sender. Import emails last. Keep one named send owner. |
Where each thing goes.
| Source | Destination | Method | Notes |
|---|---|---|---|
| Medium story title | Substack post title | automatic | Compare punctuation after import. |
| Medium story body | Substack post body | transform | Remove Medium subscribe leftovers and repair embeds. |
| Medium story URL | Substack /p/slug plus a provider redirect | transform | Substack cannot store the redirect itself. |
| Medium export HTML zip | Fallback archive if URL import is incomplete | manual | Keep the zip even when the URL importer works. |
| Consented email list | Substack subscribers via CSV upload | transform | Confirm opt-in. Skip welcome mail. |
| Medium followers | No destination | unsupported | Followers are not emails. |
| Member-only Medium stories | Substack paid posts if payments are on | transform | The importer can paywall the imported archive. |
| Medium canonical or custom domain | Substack custom domain | manual | Set redirects at the DNS or domain provider. |
| Claps and Medium stats | No destination | unsupported | Keep a dated Medium stats export. |
Make the move recoverable.
Create the source-of-truth backup
Keep an immutable Medium archive and a consented list snapshot before Substack publishes or sends anything.
- Request the Medium account export and store the zip with a checksum.
- Crawl public Medium URLs, titles, dates, and image hosts.
- Export any real mailing list with subscribed, unsubscribed, and bounce state.
- Record Medium publication membership, custom domains, and Partner Program reports.
- Work on copies. Do not edit the original zip.
Proof to capture: A dated manifest with the Medium zip hash, story count, list counts, and a named restore owner.
Import stories from the Medium URL
Bring the archive into Substack without sending it.
- Paste https://medium.com/@yourusername or the publication URL.
- Confirm you own the source. Decide whether imported posts are paid.
- Do not tick send-as-email for the imported archive.
- Delete leftover Medium banners on a sample of posts.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
Import only a consented email list
Move readers you can lawfully email, once.
- Pause every other sender first.
- Upload CSV, XLSX, or ODS. Confirm opt-in. Skip welcome email.
- Comp paid readers against recorded remaining term if you owe them access.
- Reconcile imported, skipped, and duplicate counts.
Proof to capture: Save the input, output, command or tool settings, warnings, and final item counts.
The things most likely to hurt.
These are operating limits. Treat every “Stop if” condition as a blocked migration, not a suggestion.
You import followers who never opted in
Someone treats Medium follower count as a mailing list.
- Consequence
- Substack holds or rejects the import. Complaints spike if you send.
- Mitigation
- Import only emails with consent evidence.
Stop if: The file includes scraped followers or purchased names.
Imported posts email the list
Substack asks whether to send each cleaned imported post.
- Consequence
- Readers get a dump of old Medium stories.
- Mitigation
- Choose not to send. Keep the list unscheduled until seed delivery passes.
Stop if: Any imported post is queued for the full audience.
Images still load from Medium
Imported posts request miro.medium.com or medium.com.
- Consequence
- The archive breaks when Medium hotlink or account access changes.
- Mitigation
- Re-upload stragglers while Medium is still up.
Stop if: A high-traffic post still depends on Medium media.
Historic Medium URLs 404
You move a custom domain without a URL map.
- Consequence
- Search and shared links miss the new posts.
- Mitigation
- Build the Medium-to-/p/ map first.
Stop if: Any high-value Medium URL fails after one redirect correction.
Do the work in this order.
- Days 1–2 · inventory
Export Medium and inventory the list
2–4 hours active1–2 days elapsedMedium export email waiting- Request the Medium export.
- Crawl public story URLs.
- Confirm whether you have a real opted-in list.
Stop / go checkpointCan we import posts?
Go when: The Medium zip, story inventory, and consent decision exist.
Stop when: You cannot export Medium or the only 'list' is followers.
- Day 2–3 · setup
Stand up Substack without sending
2–3 hours active1 day elapsedStripe and domain if you use them waiting- Create the publication and About page.
- Turn off welcome email on import.
- Start custom-domain setup if you own a host.
Depends on: inventory
Stop / go checkpointIs Substack safe to receive posts?
Go when: No production campaign is enabled.
Stop when: Payments or publication ownership is unclear.
- Days 3–5 · import
Import posts, then emails
3–6 hours active1–3 days elapsedImporter run and possible list review waiting- Import from the Medium URL and clean chrome.
- Pause other senders, then upload the consented CSV.
- Reconcile skipped and duplicate emails.
Depends on: setup
Stop / go checkpointDid the archive and list land?
Go when: Story and email counts match or have signed exceptions.
Stop when: Posts are missing, images stay on Medium, or the list is under review with no owner.
- Days 5–8 · verify
Verify content, redirects, and seed mail
2–4 hours active1–2 days elapsedAt least one seed delivery waiting- Compare titles, dates, and paywalls.
- Test redirects from Medium URLs.
- Send only to a seed list.
Depends on: import
Stop / go checkpointCan Substack own the next send?
Go when: Blocking content, consent, URL, and seed checks pass.
Stop when: A seed recipient gets the wrong access or a blast of old posts.
- Days 8–12 · cutover
Switch the public home and first send
1–3 hours active1–4 days elapsedDomain verification if used waiting- Point the custom domain if you have one.
- Leave a Medium pointer or redirect.
- Send the first Substack issue with a named operator.
Depends on: verify
Stop / go checkpointCan Medium sending stay off?
Go when: The first full send completes without a rollback trigger.
Stop when: Duplicate mail or broken images appear.
Cut over with a way back.
Cutover
Make Substack the public home and the only sender without dumping the Medium archive into inboxes.
- Confirm Medium or any other sender is paused.
- Import any final story delta and reconcile counts.
- Switch custom-domain DNS only after redirects are ready.
- Run blocking checks for posts, images, consent, and seed delivery.
- Keep the full audience unscheduled until those checks pass.
Proof to capture: Story and list reconciliation, image-host sample, seed headers, and named approval.
Rollback
Return readers to Medium or the previous sender without a second blast.
- Cancel any Substack campaign.
- Restore previous DNS if you moved a domain.
- Leave the Substack list in place for investigation. Do not send from both sides.
- Keep the Medium export zip.
Proof to capture: Exactly one platform owns the next send. Medium stories still resolve.
- Imported posts email the full list
- High-traffic images still depend on Medium
- Consent totals cannot be reconciled
- A list import is rejected after you already announced the move
- A blocking check cannot be fixed within two hours
Prove the migration worked.
Every blocking check must pass. Capture the evidence before cleanup begins.
| Pass | ID | Check | Method | Expected result | Evidence |
|---|---|---|---|---|---|
V-01Blocking | Story reconciliation | Compare Medium export titles, dates, and URLs with Substack posts. | Every expected story exists once or has a signed exception. | Story ledger. | |
V-02Blocking | Medium chrome and embeds | Open public, member-only, and embed-heavy samples. | No leftover Medium subscribe banner on accepted posts. | Paired screenshots. | |
V-03Blocking | Image hosts | Inspect image URLs on a stratified sample. | No required image depends on Medium. | Image-host report. | |
V-04Blocking | Consented list only | Compare import totals with the source CSV and skipped rows. | No follower scrape. Opt-outs stay out. | Import summary and source CSV counts. | |
V-05Blocking | Seed delivery | Send to controlled addresses only. | From, links, and unsubscribe work. No archive blast. | Seed headers. | |
V-06Blocking | Medium URLs | Request high-value Medium paths. | One hop to the matching Substack post if you own the domain, or a documented Medium pointer. | URL results. | |
V-07 | Comped paid readers | Sample readers who paid on the old stack. | Access matches the remaining term you recorded. | Comp ledger. | |
V-08Blocking | Single sender | Inspect Medium, Substack, and any ESP schedules. | Only Substack can send after cutover. | Schedule screenshots. |
Remove the scaffolding safely.
Safe after: One successful full-audience Substack send, 24 hours of acceptable delivery, seven stable days, and a signed report.
- Archive the Medium zip, list CSV, URL map, and verification evidence.
- Re-upload leftover Medium-hosted images.
- Leave a Medium pointer or redirect for 30 days if you still own those URLs.
- Cancel Medium Partner Program or custom domain only after images are independent.
- Revoke migration-only users.
- Schedule the next Substack backup and list-consent review.
When the plan met reality.
First-hand accounts are preferred. Vendor case studies are labeled, and every note below is an editorial paraphrase—follow the link for the full context.
Sharon Hurley Hall moved most of her Medium archive to Substack after algorithm changes, a username switch that broke old links, and falling Partner Program earnings. Substack had no clean Medium importer then, so she exported Medium HTML, imported it into a temporary WordPress.com blog, dropped posts she did not want to republish, and exported WordPress XML into Substack. The URL scrape of that temporary blog failed, so she uploaded the XML. She brought over about 500 posts with images. Embeds, decks, photo credits, and Medium internal links still needed cleanup.
- If the URL importer is thin, use a temporary WordPress.com blog as a bridge and clean the archive before the XML step.
- Review co-authored and publication-exclusive pieces before you republish them on Substack.
- A Medium username change can break every old link, and Medium may not restore them.
- The WordPress bridge let her choose which stories moved, which the Substack URL importer still does not.
Verify against the primary material.
Platform behavior changes. Check these sources and the review dates above before executing a production migration.
- Substack: import posts from Medium, WordPress, Ghost, and othersAccessed 2026-10-30
- Medium: export your account dataAccessed 2026-10-30
- Substack: import a mailing listAccessed 2026-10-30
- Substack: how email list imports are reviewedAccessed 2026-10-30