Migration Playbook

Slab Notion

Slab to Notion: The Complete Migration Playbook

A 35-step runbook across six phases — track your progress, and open the right tool at every step.

0 / 35 steps complete 0%
TL;DR

Slab's bulk export misses secret topics and drafts. Notion's importer caps at ~120 files/12 hours. For workspaces over 100 posts, use an API-based migration to preserve links and formatting.

There is no native migration path from Slab to Notion — Notion's import menu does not list Slab as a source, and manual imports are capped at ~120 files every 12 hours. Slab stores content using Quill's Delta format and exports as Markdown. Notion is block-based, where every element is a typed JSON object with a unique ID and specific nesting constraints. For workspaces over 100 posts, only an API-based migration preserves internal links, re-hosts images from Slab's CDN, and handles secret topics and drafts that the bulk export silently excludes.

Read this first

Pair-specific gotchas that catch teams out. Each one has cost somebody a weekend.

Admin does not mean full access

Slab admins can bulk-download published posts and topics, but they cannot export secret topics they are not part of or drafts. Admins also cannot use privilege to join secret topics, and Slab's API only returns content the Slab Bot can access. If you skip this access audit, your migration will be incomplete before it starts. (help.slab.com)

Critical gap

Slab's Help Center confirms that admins "cannot export secret topics they are not a part of or drafts." If your workspace uses secret topics for sensitive team documentation (HR policies, security runbooks, board materials), those posts will silently be missing from the export ZIP. There is no warning in the UI. (help.slab.com)

Audit before you export

Use Slab's advanced search filters to inventory what you actually have. The documented filters include in:, is:, by:, owner:, contributor:, and mention:. The is: filter is especially useful for identifying draft, published, public, verified, expired, and archived content before the move — the fastest way to produce a gap list rather than discovering missing content after cutover. (help.slab.com)

Created/updated dates

Notion's importer does not preserve original timestamps. All imported pages show the import date as their creation date. If audit trails or version history matter to your team, plan to store original dates in a database property after import.

Do not use PDF as your migration source

Notion can import PDFs, but headings, equations, quotes, toggles, to-dos, code, callouts, and dividers may lose structure. Paid-plan PDF imports cap at 20 MB per file. PDF is an archive format, not a migration format. (notion.com)

Minimize query complexity

Only request the fields you need. Fetching user details, reactions, and comments in the same query as post content will burn through your complexity budget fast. Split extraction into phases: content first, metadata second.

The runbook

Work top to bottom. Tick steps as you go — your progress is saved in this browser.

01 Discovery Decide what content deserves to move before you plan how to move it. 0/5

Objective A content inventory with a keep/rewrite/retire decision on every article and an agreed URL strategy.

  1. Inventory all content in Slab

    Content lead 2-3 days

    Count articles, categories, attachments, images and embedded media, and pull page views and last-updated dates for each article. Usage data is what makes the next decision defensible rather than political.

    Data Profiler Get real record counts instead of estimating from memory
  2. Make a keep, rewrite or retire call on every article

    Content lead 1-2 weeks

    Most knowledge bases are half stale. Migrating everything imports the staleness and doubles the work; use views and last-updated to triage, and get the owning team to confirm. This usually removes 30-50% of scope.

    Migrating stale content is the most common knowledge-base migration mistake — it costs effort and actively degrades the new site.

  3. Agree the URL and redirect strategy

    SEO / web 2-3 days

    Decide the Notion URL structure and whether you can serve 301 redirects from the old paths. Public help centres carry real search traffic and inbound links; losing it is a measurable commercial impact.

    Without 301 redirects from old article URLs you lose accumulated search ranking and every external link and bookmark breaks.

  4. Map the information architecture

    Content lead 3-5 days

    Document the current category tree and design the target one, checking whether Notion supports your nesting depth. Deeply nested hierarchies frequently have to be flattened, which changes navigation for everyone.

  5. Confirm permissions, audiences and localisation scope

    Content lead 2-3 days

    Establish which content is public, internal or restricted, and how Notion models that. Then confirm how many locales you have and whether translation relationships between articles survive the move.

Slab → Notion specifics

No relational databases
Slab is document-only. Notion's database-first architecture lets teams build project trackers, CRMs, and sprint boards alongside their docs.
Limited integrations
Slab connects to Slack, GitHub, and a handful of others. Notion's ecosystem is broader, with a public API, webhooks, and a growing marketplace.
Tool consolidation
Teams running Slab for docs, Trello for tasks, and Airtable for tracking can often collapse all three into Notion.
Lack of advanced views and permissions
Notion's filtered database views, granular permissions, and workspace-level controls give IT leads more flexibility.

Don't move on until

  • Full content inventory with page views and last-updated dates
  • Keep / rewrite / retire decision recorded per article
  • URL and redirect strategy agreed with whoever owns SEO
02 Data Audit Audit the markup, the links and the assets — that is where KB migrations break. 0/6

Objective A content export with markup, internal links and every embedded asset accounted for.

  1. Export content and assess markup fidelity

    Content engineer 2-3 days

    Export articles in the richest format available and inspect what survived: tables, code blocks, callouts, nested lists, anchors and embedded video. Rich formatting is where fidelity is lost, and it is lost quietly.

    HTML-to-Markdown conversion routinely mangles nested lists, tables and code blocks. Inspect the output rather than trusting the converter.

    Data Profiler Profile the Slab export for nulls, outliers and type drift
  2. Inventory every internal link and cross-reference

    Content engineer 2-3 days

    Extract all internal links, anchor links and article cross-references. These break by default: the target URL structure differs, so every internal link needs rewriting as part of the load, not afterwards.

    Internal links left pointing at old URLs turn the new knowledge base into a maze of 404s on day one.

  3. Inventory images, attachments and embedded media

    Content engineer 2 days

    List every asset with its URL, size and type, and confirm each still resolves. Assets hosted on the old platform's CDN will 404 the moment you decommission it, so they must be rehosted, not referenced.

    Images referenced from the source platform's CDN break when the old account closes. Download and rehost every asset.

  4. Find and fix broken links and orphans

    Content lead 2-3 days

    Crawl for existing broken internal and external links, and find articles no category links to. Fix them before migrating — a migration is a bad time to discover pre-existing rot.

  5. Check for PII and internal information in public content

    Compliance 1-2 days

    Scan for customer names, internal hostnames, credentials in code samples and screenshots containing real data. Republishing these on a public help centre is a disclosure, and screenshots are the usual culprit.

    PII & Compliance Scanner Find regulated fields before they land in a new system
  6. Normalise metadata

    Content engineer 1-2 days

    Standardise authors, tags, timestamps to UTC, and locale codes. Author mapping needs a decision for people who have left — attribution to a deleted user usually fails the import.

Slab → Notion specifics

Internal links
become relative paths that point nowhere once you leave Slab
Embedded third-party content
(Figma, Loom, Google Docs, custom iframes) exports as raw URLs, not embeds
Code blocks
survive but language annotations may vary
Image references
point to Slab's CDN — those URLs may expire or become inaccessible after your Slab subscription ends
Metadata
document IDs, precise creation timestamps, user attributions, and verification status are stripped

Don't move on until

  • Content exported with markup fidelity assessed
  • Every internal link and asset reference inventoried
  • Broken links and missing assets fixed or logged
03 Field Mapping Map structure, metadata, permissions and — above all — URLs. 0/6

Objective A mapping covering article fields, taxonomy, permissions and a complete old-to-new URL map.

  1. Map the article schema

    Content engineer 2 days

    Map title, body, excerpt, author, dates, status, tags, SEO metadata and any custom properties. Confirm which fields Notion lets you set on import versus which it computes — computed dates are a common surprise.

    Schema Mapper Opens pre-loaded with the Slab → Notion field pair
  2. Map the taxonomy and hierarchy

    Content lead 2-3 days

    Map categories, sections and tags to the target structure, resolving any nesting-depth limit explicitly. If you must flatten, decide how the lost level is preserved — usually as a tag or a title prefix.

    JSON to CSV Converter Flatten nested API responses into a reviewable sheet
  3. Map permissions and audience segmentation

    Content lead 2 days

    Map public, logged-in, and role-restricted visibility to Notion's model. Verify the mapping deliberately: internal content accidentally published publicly is the highest-severity failure in this whole category.

    Permission mapping errors publish internal documentation to the open web. Verify visibility on every restricted article after load.

  4. Build the complete old-to-new URL map

    SEO / web 2-3 days

    Produce a row per article mapping the old URL to the new one, then confirm exactly where the 301s will be served — Notion, a CDN, or your own web layer. Without this artifact the redirect step cannot be executed at all.

  5. Define the markup conversion and link-rewrite rules

    Content engineer 3-5 days

    Specify how each markup construct converts and how internal links are rewritten using the URL map. Write it as a repeatable transform, not manual edits — you will run it more than once.

    Data Format Converter Reshape the export into the format Notion's importer expects
  6. Plan localisation and freeze the spec

    Content lead 1-2 days

    Confirm how translated articles link to their source language in Notion, then version and sign off the mapping spec.

Don't move on until

  • Article schema and taxonomy mapped
  • Permission and audience model mapped to target equivalents
  • Complete URL map produced and redirect method confirmed
04 Test Migration Pilot the hardest articles, then read them. 0/6

Objective A pilot load whose formatting, links, assets and search all hold up under human review.

  1. Configure Notion with the agreed structure

    Content engineer 3-5 days

    Create the category tree, permission groups, locales and branding before loading. Articles loaded before their categories exist land uncategorised and have to be moved by hand.

  2. Pick the most difficult articles as the pilot

    Content lead 0.5 day

    Choose 20-50 articles for difficulty: the longest, the most heavily formatted, ones with tables and code blocks, deep internal linking, many images, embedded video, restricted visibility, and non-Latin scripts. Easy articles prove nothing.

  3. Run the conversion and load with link rewriting

    Content engineer 2-3 days

    Apply the markup conversion, rewrite internal links from the URL map, upload and re-reference assets, then load. Log every conversion warning rather than suppressing it.

  4. Read every pilot article side by side

    Content lead 2-3 days

    Open source and target together and compare rendering. This step is manual on purpose: no automated check catches a table that collapsed into a paragraph or a code block that lost its indentation.

  5. Click every link and load every asset

    Content engineer 1-2 days

    Verify each internal link resolves, each image loads from the new host, each attachment downloads and each embed plays. Assets still served from the old CDN are the defect that surfaces only after decommissioning.

    Migration Validation Tool Diff the pilot batch against source before scaling up
  6. Test search and permissions

    Content lead 1-2 days

    Search for known terms and confirm the right articles rank, then verify every restricted pilot article is invisible to an anonymous browser. Test permissions from a logged-out session, not an admin one.

Don't move on until

  • Complex articles render correctly with formatting intact
  • Every internal link and asset in the pilot resolves
  • Search returns sensible results for the pilot content
05 Cutover Publish, redirect, and keep the search traffic. 0/6

Objective All in-scope content live in Notion with redirects serving and search engines informed.

  1. Load the full content set ahead of the switch

    Content engineer 1-2 weeks

    Run the full conversion and load into Notion, unpublished or on a staging domain. Content migration differs from data migration here: you can stage the whole thing before anyone sees it.

  2. Publish the runbook with the redirect step first-class

    Project manager 1 day

    Sequence the freeze, final delta, publish, redirect activation, sitemap submission and link updates, with owners for each. Redirect activation is the step with lasting commercial consequences, so it gets explicit ownership.

  3. Freeze editing and migrate the delta

    Content lead 2-4 hours

    Stop editing in Slab, then convert and load anything changed since the full load. Announce the freeze to every team that publishes — content teams are used to editing whenever they like.

  4. Publish and verify permissions live

    Content lead 2-4 hours

    Publish the content set, then immediately verify restricted articles are not publicly reachable using an anonymous session. Do this before announcing the new site, not after.

    Verify restricted content from a logged-out browser. An admin session will show you everything and tell you nothing.

    Migration Validation Tool Confirm the final delta landed before you reopen
  5. Activate 301 redirects and submit the sitemap

    SEO / web 2-4 hours

    Turn on the redirects from the URL map, then spot-check a sample of high-traffic old URLs and confirm each returns 301 to the right article. Submit the new sitemap and keep the old one reachable until search engines have recrawled.

    Redirect chains and redirect loops both leak ranking. Verify each redirect resolves in a single hop.

  6. Repoint in-product and support links

    Content lead 1-2 days

    Update help links embedded in your product, in support macros, in email templates and in onboarding material. These are the links your existing customers actually use, and they are easy to forget.

Don't move on until

  • All content loaded, categorised and correctly permissioned
  • 301 redirects live and verified from a sample of old URLs
  • Sitemap submitted and support links repointed
06 Validation Watch traffic, links and search rankings for weeks, not hours. 0/6

Objective Verified content completeness, healthy redirects, and search traffic recovered to baseline.

  1. Reconcile content counts and assets

    Content engineer 1-2 days

    Compare article counts by category and status, plus asset counts, against source. Confirm every article in the keep list is present and every retired one genuinely is not.

    Migration Validation Tool Reconcile Slab and Notion record-for-record
  2. Crawl the new site for broken links and assets

    Content engineer 1-2 days

    Run a full crawl for 404s, broken images and missing attachments, and fix everything it finds. Repeat the crawl after the fixes rather than assuming they worked.

  3. Verify the redirects at scale

    SEO / web 1-2 days

    Test every mapped old URL for a single-hop 301 to the right destination. Chains and loops both leak ranking and are invisible unless you check the whole map, not a sample.

  4. Monitor organic traffic and rankings for four to eight weeks

    SEO / web 4-8 weeks

    Track organic sessions, impressions and rankings for your top articles against baseline. A dip in the first two weeks is normal; one that has not recovered by week six is a redirect or indexing problem to investigate.

    Do not decommission the old platform until search traffic has recovered — you may still need the old URLs to diagnose a ranking loss.

  5. Verify search, permissions and feedback loops

    Content lead 1-2 days

    Confirm on-site search returns good results for real queries, re-verify restricted content from a logged-out session, and check article feedback and analytics are collecting.

  6. Sign off and decommission on a delay

    Project sponsor 1 day

    Get acceptance against the Discovery criteria, keep Slab available read-only until traffic has recovered, take a final export, and only then close the account.

Slab → Notion specifics

Page counts
Slab total vs. Notion total (published, drafts, secret topics)
Formatting spot-check
10–15% of posts, prioritizing pages with the worst tables and richest formatting
Missing content
Check for gaps from secret topics or drafts
Recent edits
Verify changes that landed after the initial export

Don't move on until

  • Article counts reconciled and no broken links remain
  • Redirects returning 301 with no chains or loops
  • Organic traffic recovered to within tolerance of baseline

Field mapping reference

The field-by-field mapping for each object. Use this as the starting point for your mapping spec.

Limit Value 7 fields
Slab fieldNotion fieldNotes
Request rate 3 requests/second per integration Token bucket; bursts up to ~10 allowed
Rate limit response HTTP 429 with Retry-After header Back off for the duration specified in the header (typically around 2 seconds)
Blocks per request 1,000 max Total across all nested levels
Payload size 500 KB max Per request
Children array 100 elements max Per individual children array
Nesting depth 2 levels per request Deeper nesting requires follow-up append calls
Rich text per object 2,000 characters Text exceeding this must be split across objects
Object Equivalent 24 fields
Slab fieldNotion fieldNotes
Post Page 1:1. Each Slab post becomes a Notion page. Store the original Slab post ID as a text property for QA and link rewriting.
Topic Page (as parent) or database property Create a Notion page per topic; nest post pages inside. Use properties for reporting.
Subtopic Nested page Maintain hierarchy by nesting under topic pages.
Bold / Italic / Strikethrough Rich text annotations Maps directly to Notion's annotations object.
Heading (H1, H2, H3) heading_1, heading_2, heading_3 blocks Direct mapping. Both platforms support H1–H3. Slab does not use H4–H6.
Bullet list bulleted_list_item block Direct mapping, but nesting depth requires recursive API calls beyond 2 levels.
Numbered list numbered_list_item block Same nesting constraints as bullets.
Checkbox / Task list to_do block Maps cleanly including checked state.
Code block code block Language annotation may need normalization (e.g., js → javascript). Must match Notion's supported enum values or the request fails/defaults to plain text.
Blockquote quote block Direct mapping.
Horizontal rule divider block Direct mapping.
Callout / Hint callout block Requires extracting text and explicitly assigning a default emoji or icon URL in the API payload.
Image image block Requires re-hosting: download from Slab CDN and re-upload via Notion's File Upload API.
Embedded content (Figma, Loom, YouTube) embed block URL-based embeds map to Notion's embed block, but Notion's allowlist may reject some sources.
Table table + table_row blocks Notion tables have a 100-column limit. Slab tables are simpler, so this usually maps fine.
Internal link (post-to-post) Page mention or inline link Requires two-pass link rewriting. Build a lookup table mapping Slab post IDs/URLs to new Notion page IDs.
Post owner People property or text Use people property if the user exists in the Notion workspace, otherwise store as text. Do not block the migration on user matching.
Published / updated dates Date properties Notion's native timestamps reflect import date. Store originals as custom properties for audit and delta logic.
Post verification status Select or checkbox property No native Notion equivalent. Store if your team still needs review state after migration.
Post series Index page or relation property No native series object in Notion.
Comments / Annotations Notion comments API (partial) Slab inline comments don't map natively. Notion's API supports page-level and block-level comments, but not inline text annotations positioned at specific text ranges. Inline positioning is lost.
Reactions ❌ No equivalent Cannot be migrated.
Version history ❌ No equivalent Does not transfer. Notion creates its own history from import forward.
Analytics / read receipts ❌ No equivalent Slab analytics data is not exportable.
Data Type Migrateable? 11 fields
Slab fieldNotion fieldNotes
Published posts (text + formatting) ✅ Yes Full fidelity with API approach
Topic hierarchy ✅ Yes Maps to Notion page nesting
Inline images ✅ Yes (with re-hosting) Must download and re-upload
Internal links ✅ Yes (with rewriting) Requires two-pass link mapping
Post metadata (created/updated dates) ⚠️ Partial Stored as custom properties; Notion's native timestamps reflect import date
Comments & annotations ⚠️ Partial Can migrate as page-level comments; inline annotation positioning is lost
User attribution ⚠️ Partial Author names stored as text; Notion won't link them to workspace members automatically
Version history ❌ No Does not transfer
Reactions (emoji) ❌ No No Notion equivalent
Verification status ❌ No (native) Can store as a custom database property
Analytics / read receipts ❌ No Slab analytics data is not exportable

Risk matrix

Per-object risk for this pair. Plan extra validation around anything marked high.

ObjectRiskNotes
Internal Links high All Slab URLs break immediately — require two-pass ID mapping and rewriting
Secret Topics high Silently excluded from export and API if admin or Bot lacks access
Draft Posts high Excluded from bulk export by default — new posts are draft-only until published
Inline Images medium Slab CDN URLs may become inaccessible after subscription ends
Comments & Annotations medium Inline comment positions are lost — only page-level comments can be partially migrated
Deeply Nested Lists medium Notion API limits to 2 nesting levels per request — deeper lists need extra calls
Rich Text Length medium Paragraphs over 2,000 characters must be split across multiple rich text objects
Callouts & Hints medium Export as plain text — must be programmatically converted to Notion callout blocks
Version History low Does not transfer — Notion creates fresh history from the import date forward
Published Post Content low Text and formatting migrate with full fidelity via the API approach

The hard parts

What makes this specific migration difficult, beyond the mechanics.

Import Throttling

Notion limits native imports to ~120 files per 12 hours. A 500-post workspace takes 60+ hours of staggered batching.

Internal Link Rewriting

Slab URLs become broken relative paths after migration. Requires a two-pass ID mapping and link replacement pipeline.

Image Re-hosting

Slab CDN image URLs may become inaccessible after subscription ends. Every image must be downloaded and re-uploaded via Notion's File Upload API.

Block Nesting Limits

Notion's API limits nesting to 2 levels per request. Deeply nested Slab lists require multiple sequential API calls.

Secret Topic Extraction

Slab admins cannot export secret topics they haven't joined. The API is also scoped to Slab Bot user access only.

What breaks

Known failure modes. Have a recovery plan for each before you cut over.

Pass 1:

Migrate all posts, recording a mapping of slab_post_id → notion_page_id

Pass 2:

Walk every migrated page, find blocks containing Slab URLs, and replace them with Notion page links using your mapping table. Handle orphaned links for posts that referenced content that wasn't migrated.

Tools used in this playbook

All free, all run entirely in your browser — nothing is uploaded.

FAQ

Can I import Slab directly into Notion?

No. Notion does not have a native Slab importer. You must export from Slab as Markdown or DOCX files, then import those into Notion manually — or use both platforms' APIs to build a custom migration pipeline.

What data is lost when exporting from Slab?

Slab's bulk export excludes secret topics the admin hasn't joined and all draft posts. Version history, reactions, analytics, and inline comment positions are also lost. Internal links between posts become broken relative paths, and image URLs point to Slab's CDN which may become inaccessible after cancellation.

What is Notion's native import file limit?

Notion limits native file imports to approximately 120 files every 12 hours. File size is capped at 5 MB per file on the Free plan and 50 MB on paid plans. There is no progress bar or status tracking during import.

How do I preserve internal links when migrating from Slab to Notion?

You need a two-pass approach: first migrate all posts and record a mapping of Slab post IDs to new Notion page IDs, then walk every migrated page and replace Slab URLs with Notion page links using that mapping table. Handle orphaned links for any content that wasn't migrated.

What are the Notion API rate limits for migration scripts?

Notion's API allows an average of 3 requests per second per integration with bursts up to 10. Each request can contain a maximum of 1,000 block elements and 500 KB. Individual children arrays are capped at 100 elements with only 2 levels of nesting per request. Rich text objects are limited to 2,000 characters each.

Or skip all of this and let us handle it

Book a 30-minute call and we'll scope your migration in a single session.