Skip to content

How to Migrate from SharePoint to Guru: The Complete Technical Guide

How to migrate from SharePoint to Guru: API constraints, object mapping, permission translation, and step-by-step process for a clean knowledge base migration.

Raaj Raaj · · 29 min read
How to Migrate from SharePoint to Guru: The Complete Technical Guide
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

How to Migrate from SharePoint to Guru: The Complete Technical Guide

Info

Quick Answer: The Reality of Migrating SharePoint to Guru Migrating from SharePoint to Guru is a medium-to-high complexity knowledge base migration, not a file copy. It typically takes 2–3 weeks for organizations with 500–2,000 pages, and 3–5 weeks for 5,000+ pages with complex permissions. The single biggest risk is permission misalignment: SharePoint's item-level broken inheritance has no 1:1 equivalent in Guru's Collection-and-Group access model. Version history, SharePoint web parts, and folder nesting beyond three levels cannot be migrated directly. Guru's native SharePoint integration is a sync, not a structural migration — it does not create native Guru Cards. Teams under 200 pages with flat permissions can handle this in-house with scripting; above that, or with complex permissions, a managed migration service significantly reduces re-work.

What Is a SharePoint to Guru Migration?

A SharePoint to Guru migration is the process of extracting pages, documents, and metadata from SharePoint Sites and Document Libraries, transforming that content into HTML-formatted Guru Cards, and loading them into Guru's Collection → Folder → Card hierarchy. It is a content-architecture translation, not a file copy.

Guru's own guidance explicitly separates "connect a Source" from "migrate into Guru." Connected sources stay outside Guru and are not editable there. Migrated content becomes editable, governed Guru knowledge. Understanding this distinction is the first step in planning correctly.

Why Teams Move from SharePoint to Guru

  • AI-powered knowledge delivery. Guru's search surfaces verified answers inside Slack, Teams, and browser extensions. SharePoint search requires users to navigate to a separate portal, adding context-switching overhead in support and sales workflows where response time matters.
  • Verification workflows. Guru's built-in Verifier system assigns subject-matter experts to Cards on a configurable recurring interval (e.g., 30, 60, 90, or 180 days). SharePoint has no native equivalent — content review depends on manual processes, SharePoint Designer workflows, or Power Automate flows that must be built and maintained separately.
  • Lower information architecture overhead. SharePoint requires ongoing admin effort to maintain sites, content types, metadata columns, term stores, and permission inheritance. Guru's flatter hierarchy (Collection → up to 3 Folder levels → Card) reduces structural maintenance for teams under 10,000 articles.
  • In-context access. Guru operates where support agents and engineers work (Slack, browser extensions, Chrome/Edge), reducing the portal-switching that SharePoint requires for non-admin users.

For a deeper look at SharePoint's information architecture challenges, see our guide on SharePoint metadata, content types, and lists.

Three Architectural Differences That Make This Non-Trivial

  1. Permission model. SharePoint permissions can be broken at the item level, creating thousands of unique access control entries per library. Microsoft supports up to 50,000 unique permissions per list or library but recommends staying under 5,000. Guru controls access at the Collection and Group level — individual Card-level permissions do not exist.
  2. Content format. SharePoint modern pages use a web-part-based canvas layout (serialized as JSON via the Microsoft Graph API). Guru Cards accept HTML or Markdown content. Every page requires format conversion, including re-hosting of inline images and stripping of unsupported web part types.
  3. Hierarchy depth. SharePoint allows unlimited site and folder nesting. Guru supports a maximum of three levels of Folder nesting within a Collection. Deep SharePoint structures must be flattened or restructured before loading.

Data Mapping: SharePoint Objects to Guru Cards

The fundamental data models of SharePoint and Guru do not align cleanly. You must design the correct mapping before writing a single line of extraction code.

SharePoint Object Guru Object Notes / Caveats
Site Collection One Collection per SharePoint Site is the cleanest mapping. Hub Sites may need multiple Collections.
Document Library / Folder Folder Guru supports max 3 levels of Folder nesting. Deeper SharePoint structures must be flattened.
Modern Page / Wiki Page Card Page content must be converted from canvas layout JSON or legacy HTML to Guru-compatible HTML.
Document (PDF, DOCX, XLSX) Card with Attachment Binary files are uploaded via POST /api/v1/attachments/upload and referenced in Card HTML. Guru does not extract searchable text from PDFs.
List Card (or external link) SharePoint Lists have no native Guru equivalent. Convert to tabular Card content or link externally.
Metadata Columns Tags SharePoint columns (choice, managed metadata) map to Guru Tags. Free-text columns have no clean mapping.
Page Author / Modified By Card Owner / Verifier Map SharePoint createdBy or lastModifiedBy to Guru Verifier to preserve accountability.
Item-level Permissions Group-level access on Collection No 1:1 mapping. Items with broken inheritance must be regrouped into separate Collections or accepted as broader access.
Version History Not migrated Guru tracks Card revision history natively, but SharePoint's file version history (timestamps, authors, diffs) cannot be imported.
Web Parts (Hero, Quick Links, Embed, Power BI) Not supported Web part functionality has no Guru equivalent. Content must be manually simplified to static HTML or linked externally.
SharePoint Workflows / Power Automate Not migrated Guru has no workflow engine. Rebuild in external tools if needed.
Warning

Do not design a new migration around legacy Boards documentation. With the recent updates to hierarchy within Guru, they have switched from Boards to Folders. Older API docs or scripts referencing boardId will fail — use folderIds instead.

What Has No Clean Equivalent in Guru

SharePoint Lists are structured tabular data with typed columns, calculated fields, filtering, and views. Guru has no database or list object. Your options:

  1. Convert each row to an individual Card (produces high Card counts — a 500-row list becomes 500 Cards).
  2. Embed the list as an HTML table inside a single Card (limited to static display, no filtering or sorting).
  3. Maintain the List in SharePoint and link from a Guru Card (preserves interactivity but requires cross-platform navigation).

Item-level permissions with broken inheritance are the hardest translation problem. A Document Library with 200 unique permission entries cannot be expressed in Guru's model. The practical solution: audit which permission groups actually exist and which users they contain, then restructure content into separate Guru Collections with appropriate Group assignments. In practice, most libraries have 3–8 distinct access patterns, not 200 — many "unique" permission entries are near-duplicates.

Field-level mapping is where most DIY projects slow down. Rich text usually maps cleanly after HTML cleanup (stripping SharePoint-specific CSS classes and data- attributes). Choice and managed metadata columns become Guru Tags via POST /api/v1/tagcategories and POST /api/v1/tagcategories/{id}/tags. People fields are best mapped to Verifier assignments or rendered as a visible metadata line in the Card body. If your SharePoint information architecture is folder-heavy and metadata-light, restructure before migration — otherwise you recreate opaque storage in a different UI.

Migration Approaches: Native Sync vs. Custom ETL vs. Managed Service

There are three primary viable approaches. Generic SharePoint file-migration tools (SPMT, Migration Manager, ShareGate) move content into Microsoft 365 destinations, not into Guru Cards — they do not solve the Card-conversion problem.

Guru's Native SharePoint Integration Is a Sync, Not a Migration

Guru lets you connect SharePoint as a Source to improve knowledge visibility, discoverability, and governance across your organization. By syncing SharePoint content into Guru, teams can easily search, access, and trust internal documentation. But this is an ongoing sync — content remains in SharePoint and is surfaced through Guru's search. It does not create native Guru Cards that your team can edit, verify, or restructure within Guru.

The upside is speed (minutes to configure) and zero coding. The downside: synced content is read-only in Guru, and it carries a hard limitation. Due to a limitation in the Microsoft Graph API, SharePoint Group memberships cannot be retrieved — so while Guru can see the groups, they appear empty, and Access Control Lists (ACLs) won't sync automatically for SharePoint group-only sites. Guru also enforces a 50 MB file-size limit across connected sources. Files exceeding this limit are silently excluded from the sync.

When to use native sync: You want to keep SharePoint as the system of record but make content discoverable in Guru's search and browser extension. You are not moving off SharePoint.

Custom Microsoft Graph → Guru API ETL

This is the right path for a true structural migration into native, editable Guru Cards. You extract with the Microsoft Graph API, transform modern pages and file content into clean HTML, create Collections and Folders via the Guru API, then create Cards and assign Verifiers.

The upside is full control: you can rewrite internal links, flatten bad hierarchies, normalize metadata, deduplicate content, and preserve accountability. The downside is significant engineering work — retry logic, pagination handling, attachment re-hosting, permission modeling, link rewriting, and QA all become your team's responsibility.

Typical engineering effort: 40–80 hours for a developer experienced with both APIs, for a 500–2,000 page environment. This does not include content audit, stakeholder alignment, or UAT time.

Guru Manual Sync / SDK-Based Import

Guru supports both imports (one-time, content becomes editable in Guru) and syncs (content is read-only, refreshable from the source bundle). The Manual Sync path loads a structured ZIP file into an EXTERNAL collection. The ZIP must follow Guru's expected bundle format: a manifest JSON file mapping content files to Cards, with HTML content files referenced by path.

This works well for archive-like or externally mastered content. It is weaker when you need rich per-Card governance inside Guru after launch, because synced content stays read-only. Complexity is medium if your source is already normalized and you can generate the expected bundle format programmatically.

Note on Guru SDKs: As of 2024, Guru does not publish an official Python or Node SDK. Migrations use the REST API directly via requests (Python), axios/fetch (Node), or community wrappers. The API is straightforward enough that a dedicated SDK is not strictly necessary.

Managed Migration Service

A specialized team handles the end-to-end extraction, transformation, loading, and validation. Best for 500+ pages, complex permissions, compliance requirements (SOC 2, HIPAA content handling), or when your engineering team cannot absorb a multi-week project without delaying product work.

Approach How It Works Best For Complexity Key Risks
Guru Native SharePoint Sync Connects SharePoint as a read-only Source via delegated Graph permissions Teams keeping SharePoint as source-of-truth while enabling Guru search Low Not a migration; no native Cards; SharePoint Group ACLs don't sync; 50 MB file limit
Custom API ETL (Python/Node) Extract via Graph API, transform HTML, load via Guru REST API Engineering teams with 200–2,000 pages and 40–80 dev hours available High Throttling on both sides; attachment re-hosting; broken internal links; undocumented Guru rate limits
Guru Manual Sync / SDK Upload structured ZIP bundle into Guru Controlled one-way sync or archive import Medium Read-only if synced; must match Guru's expected bundle format exactly
Managed Migration Service Dedicated team handles end-to-end ETL, permission mapping, and validation 500+ pages, complex permissions, compliance requirements Low (for your team) Cost; requires vendor evaluation and data-handling agreements

Decision criteria by scenario:

  • Under 50 pages, no complex formatting: Manual copy-paste or Guru's native sync.
  • 50–200 pages, flat permissions: Guru CSV import (for simple text content) or lightweight scripting.
  • 200–2,000 pages, dev team available: Custom API ETL with careful throttle management. Budget 40–80 engineering hours.
  • 2,000+ pages or complex permissions (broken inheritance in >10% of libraries): Managed migration service.
  • Ongoing sync, not a one-time move: Guru's native SharePoint integration. Middleware tools (Zapier, Make, n8n) can handle incremental Card creation via Guru's API triggers, but they are not designed for bulk backfill (Zapier's task limits and execution timeouts make them impractical for more than ~100 records per run).

Extracting SharePoint Data: API Limits and the 5,000-Item Threshold

SharePoint data extraction uses the Microsoft Graph API (preferred) or the older SharePoint REST API. The Graph API consumes fewer resource units for equivalent operations and provides consistent endpoint patterns across SharePoint, OneDrive, and Teams.

Key API Constraints

  • User-level throttling: SharePoint Online enforces a default limit of 3,000 requests per 5 minutes per user account, with additional per-second limits depending on the operation type. In practice, sustained throughput of ~8–10 requests/second per user is safe for read operations.
  • App and tenant throttling: Limits are also applied to applications in a tenant, based on the number of licenses purchased per organization. Costs are measured in resource units, and different API calls consume different amounts. A GET on a list item costs 1 resource unit; a search query costs 10.
  • The 5,000-item list view threshold: By default, the list view threshold is configured at 5,000 items. This is a query performance limit where views attempting to retrieve more than 5,000 items without proper indexing may experience throttling or timeouts — the threshold applies per view query, not to total library size. SharePoint can store 30 million items in a list or library, but unfiltered export queries will fail at 5,000. Partition queries using indexed column filters ($filter on an indexed field), folder-scoped requests, or time-window segmentation.
  • Throttle responses: SharePoint Online returns HTTP status code 429 ("Too many requests") or 503 ("Server Too Busy"), and the requests will fail. Always honor the Retry-After header. The header value is in seconds.
  • Bandwidth caps: 50 GB ingress per hour and 100 GB egress per hour per user account. For a typical migration (pages + documents under 10 GB total), this is not a binding constraint.
  • Search throttling: Microsoft documents 10 delegated search requests per second per user and 25 app-only search requests per second per tenant for the Search API. Use search sparingly during extraction — prefer direct list/library enumeration.

Extracting Pages via Graph API

Use the SharePoint Pages API to retrieve page content including the canvas layout:

GET /sites/{site-id}/pages/microsoft.graph.sitePage?$expand=canvasLayout

This returns the page's web part structure as JSON, including textWebPart inner HTML that can be extracted and cleaned for Guru. Image web parts return URLs that must be downloaded and re-hosted. Pagination follows standard OData @odata.nextLink patterns — continue fetching until @odata.nextLink is absent from the response.

For document libraries, use delta queries (/drives/{drive-id}/root/delta) — delta with a token is the most efficient way to scan content in SharePoint, and Microsoft lowers the resource unit cost of delta requests to 1 resource unit. Store the delta token between runs for incremental re-scans during pilot iterations or pre-cutover syncs.

A production-grade extractor typically hits these endpoints:

  • Site discovery: GET /sites or GET /sites?search={query} — returns all sites the authenticated user/app can access.
  • Lists and libraries: GET /sites/{site-id}/lists — filter by list.template to distinguish Document Libraries (documentLibrary) from generic lists.
  • Library folder/file traversal: GET /sites/{site-id}/drive/items/{item-id}/children with $select, $expand, and $skipToken for pagination.
  • File content download: GET /sites/{site-id}/drive/items/{item-id}/content — returns the raw binary stream.
  • Modern pages: GET /sites/{site-id}/pages/microsoft.graph.sitePage — requires Sites.Read.All permission scope.
  • Delta export: GET /drives/{drive-id}/items/{item-id}/delta for incremental re-scans during pilot or cutover phases.

Permissions Deserve a Separate Export Pass

SharePoint supports up to 50,000 unique permissions in a list or library, but Microsoft recommends 5,000 as a practical limit for performance. When a list, library, or folder exceeds 100,000 items, you cannot break or reinherit permissions at that container level.

To extract permissions, use GET /sites/{site-id}/drive/items/{item-id}/permissions for each item with broken inheritance. This is expensive — each item requires a separate API call. For large libraries, first identify which items have broken inheritance by checking the hasUniqueRoleAssignments property via the SharePoint REST API (/_api/web/lists('{list-id}')/items?$filter=...), then selectively extract only those permissions.

If your security model depends on item-level exceptions, normalize the permission structure before mapping it into Guru. In practice, this means creating a permission audit spreadsheet that maps each unique access pattern to a proposed Guru Collection + Group assignment.

For a full breakdown of SharePoint export methods, see our guide: How to Export Data from SharePoint: Methods, Limits & Migration Prep.

Loading Content into Guru: API Constraints and Formatting

Guru's REST API is at https://api.getguru.com/api/v1/. Authentication uses HTTP Basic Auth with your email and API token (Base64-encoded email:token in the Authorization header). For migrations, you need a User Token (read/write access), not a Collection Token (read-only, scoped to a single Collection).

Card Creation Endpoint

Create a Card with a single POST to /api/v1/cards/extended:

{
  "preferredPhrase": "Card Title",
  "content": "<p>HTML content here</p>",
  "shareStatus": "TEAM",
  "collection": { "id": "COLLECTION_UUID" },
  "folderIds": ["FOLDER_UUID_1"],
  "tags": [{ "value": "tag-name" }],
  "verificationInterval": 90,
  "verifiers": [
    {
      "type": "user",
      "user": { "email": "verifier@company.com" }
    }
  ]
}

Content and title are required. Card share status should be set to TEAM to make a card team-shared. Omitting the share status or setting it to PRIVATE will result in a card only accessible by the card owner. This endpoint allows the verifier to be set upon card creation, rather than requiring a separate call.

Key payload notes:

  • content accepts HTML. Guru strips JavaScript, iframes, and <script> tags. Allowed elements include <p>, <h1><h6>, <ul>, <ol>, <li>, <table>, <a>, <img>, <strong>, <em>, <code>, <pre>, and <blockquote>.
  • folderIds accepts an array, but in practice a Card should belong to one Folder for clarity.
  • tags must reference existing Tag values. Create Tag Categories and Tags first via POST /api/v1/tagcategories and POST /api/v1/tagcategories/{id}/tags.
  • verificationInterval is in days. Common values: 30, 60, 90, 180, 365.

Attachment Upload

To upload a file to Guru, make a POST call to https://api.getguru.com/api/v1/attachments/upload — include the file as a parameter called file and upload it as multipart/form-data. The response returns a JSON object containing an attachment URL (hosted on Guru's CDN) that you reference in the Card's HTML body via an <a> or <img> tag. Each attachment is a separate API call — there is no batch endpoint.

Maximum attachment file size is governed by your Guru plan. Files uploaded via the API must complete within the HTTP timeout window — for files over 20 MB, monitor for timeout errors and retry.

Guru's Rate Limits Are Not Publicly Documented

Rate limits are enforced but not publicly documented. Pagination uses a cursor-based nextPage token; standard offset/limit parameters are not supported. The API does not support bulk operations — each invite or role update is a discrete request. The same applies to Card creation: every Card is an individual POST.

Guru enforces a rate limit per account. If you receive this response, back off for a few seconds before retrying.

Based on empirical testing across multiple migrations, a safe sustained throughput is 2–3 Card creation requests per second. Bursting above 5 requests/second reliably triggers 429 responses within 30–60 seconds. Your migration script must implement exponential backoff with jitter. Without it, a script creating 2,000+ Cards will stall unpredictably.

Warning

Guru's API has no bulk Card creation endpoint. Every Card, attachment, and tag assignment is an individual HTTP request. At 2–3 Cards/second sustained throughput:

  • 500 Cards ≈ 3–4 minutes of API time
  • 2,000 Cards ≈ 11–17 minutes of API time
  • 10,000 Cards ≈ 55–85 minutes of API time
  • 50,000 Cards ≈ 5–7 hours of API time

These estimates exclude transformation, attachment upload, and link-rewriting passes. Attachment uploads (especially for PDFs and images) typically double the total elapsed time.

Step-by-Step Migration Process [For Engineering]

A production-grade migration requires a strict order of operations to prevent orphaned records and broken links.

Step 1: Audit and Inventory SharePoint Content

Enumerate all Sites, Document Libraries, and Pages using the Graph API. Record:

  • Item counts per library (flag any library exceeding 5,000 items for paginated extraction with indexed column filters)
  • Content types per item (modern page, wiki page, DOCX, PDF, XLSX, other)
  • Folder depth per library (flag anything deeper than 3 levels)
  • Permission structure: identify every library or folder with broken inheritance using hasUniqueRoleAssignments
  • Last modified dates (identify stale content for exclusion)
  • Total storage size (estimate attachment upload time)

Export a ledger keyed by SharePoint URL or item ID. This ledger becomes your source-to-target mapping table for the entire migration.

Recommended exclusions: SharePoint system pages (_layouts, _catalogs), auto-generated site pages (home.aspx with only web parts and no authored content), files not modified in >24 months (unless compliance requires retention).

Step 2: Design the Guru Information Architecture

Map SharePoint Sites to Guru Collections. Flatten folder structures deeper than three levels — common patterns:

  • SharePoint: Site > Library > Folder A > Folder B > Folder C > Folder DGuru: Collection > Folder A > Folder B with Folder C and D content merged or tagged
  • SharePoint Hub Site with 5 sub-sites:Guru: 5 Collections, or 1 Collection with top-level Folders per sub-site (depending on permission requirements)

Define your Tag taxonomy based on SharePoint metadata columns. Map Choice columns to Tag Categories; map Managed Metadata term sets to hierarchical Tags. Document which SharePoint authors become Guru Verifiers — use page owners or content stewards, not the migration service account.

Get stakeholder sign-off on the Collection structure before extraction begins. Restructuring Collections after migration requires moving Cards one at a time via the API.

Step 3: Extract Content from SharePoint

Use the Graph API Pages endpoint for modern pages (/sites/{id}/pages/microsoft.graph.sitePage?$expand=canvasLayout). For documents, use the DriveItem API (/drives/{id}/items/{id}/content). Pull modern pages separately from library files — they transform differently.

Implement retry logic that honors Retry-After headers. Run extraction during off-peak hours (evenings, weekends) to reduce throttling probability.

import requests
import time
 
def extract_with_retry(url, headers, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.get(url, headers=headers)
        if resp.status_code == 200:
            return resp.json()
        elif resp.status_code in (429, 503):
            wait = int(resp.headers.get("Retry-After", 2 ** attempt))
            print(f"Throttled. Waiting {wait}s (attempt {attempt + 1}/{max_retries})")
            time.sleep(wait)
        else:
            resp.raise_for_status()
    raise Exception(f"Failed after {max_retries} retries: {url}")

Store all extracted content locally (JSON for pages, binary for files) with the SharePoint item ID as the filename. This creates a local cache that decouples extraction from transformation — if the transform step fails, you don't need to re-extract.

Step 4: Transform Content to Guru-Compatible HTML

SharePoint modern pages return a canvasLayout JSON structure containing sections, columns, and web parts. The transformation pipeline:

  1. Extract text content: Pull innerHTML from textWebPart sections. This is already HTML but contains SharePoint-specific CSS classes and data-sp-* attributes that should be stripped.
  2. Handle images: imageWebPart sections contain serverRelativeUrl references. Download each image, upload to Guru's attachment endpoint, and replace the src URL in the HTML.
  3. Strip unsupported web parts: Remove heroWebPart, quickLinksWebPart, embedWebPart, powerBIWebPart, and any custom web parts. Log each removal for manual review.
  4. Flatten multi-column layouts: SharePoint sections can have 1, 2, or 3 columns. Guru Cards do not support multi-column layouts. Merge columns top-to-bottom in left-to-right order.
  5. Clean HTML: Remove empty <div> wrappers, normalize heading levels (SharePoint pages often start at <h2>), and ensure all <a> tags have valid href attributes.
  6. Handle binary files: Decide per file type:
    • PDF: Upload as attachment, create a Card with a download link and a brief description. Guru does not extract searchable text from PDF attachments.
    • DOCX: Convert to HTML using a library like python-docx + mammoth, then load as Card content. Alternatively, upload as attachment.
    • XLSX: Convert key data to an HTML table, or upload as attachment with a summary Card.
from bs4 import BeautifulSoup
 
def transform_sharepoint_html(raw_html: str) -> str:
    soup = BeautifulSoup(raw_html, "html.parser")
    # Remove SharePoint-specific attributes
    for tag in soup.find_all(True):
        attrs_to_remove = [a for a in tag.attrs if a.startswith("data-sp")]
        for attr in attrs_to_remove:
            del tag[attr]
    # Remove empty divs
    for div in soup.find_all("div"):
        if not div.get_text(strip=True) and not div.find("img"):
            div.decompose()
    return str(soup)

Step 5: Create the Guru Hierarchy First

Order of operations matters. Create objects in this sequence to prevent broken references:

  1. Tag Categories and Tags — create these first so Card creation can reference them. Store tag_category_id and tag_id mappings.
  2. CollectionsPOST /api/v1/collections. Store the returned Collection UUIDs.
  3. Folders within Collections — POST /api/v1/folders. Persist the mapping sharepoint_path → guru_folder_id. Create parent folders before child folders.
  4. Attachments — upload individually via POST /api/v1/attachments/upload. Store sharepoint_file_url → guru_attachment_url mapping.
  5. Cards — set collection ID, folder IDs, tags, verifier, and verification interval in a single call to POST /api/v1/cards/extended. Persist sharepoint_url → guru_card_id for the link-rewriting pass.

Assign Verifiers from your business owner map, not from the migration service account. If the migration script's user account becomes the default Verifier, every Card will show the migration engineer as the subject-matter expert.

Step 6: Load Cards with Exponential Backoff

Push the transformed HTML into Guru as Cards. Implement exponential backoff with jitter to handle undocumented rate limits:

import random, time
import requests
 
def create_guru_card(payload, auth, max_retries=5):
    delay = 2
    for attempt in range(max_retries):
        response = requests.post(
            "https://api.getguru.com/api/v1/cards/extended",
            json=payload,
            auth=auth
        )
        if response.status_code in (200, 201):
            return response.json()
        elif response.status_code == 429:
            wait = int(response.headers.get("Retry-After", delay))
            jitter = random.uniform(0, 0.5)
            print(f"Rate limited. Waiting {wait + jitter:.1f}s (attempt {attempt + 1})")
            time.sleep(wait + jitter)
            delay = min(delay * 2, 60)
        else:
            raise Exception(f"Failed to create card (HTTP {response.status_code}): {response.text}")
    raise Exception(f"Failed after {max_retries} retries")

Log every Card creation with its SharePoint source URL and Guru Card ID. This log is your audit trail and your input for Step 7.

This is the step most DIY scripts skip — and the step that causes the most post-launch complaints. Once all Cards exist, run a second pass over every Card body:

  1. Retrieve each Card's HTML via GET /api/v1/cards/{card-id}
  2. Scan for SharePoint URLs (https://tenant.sharepoint.com/sites/...)
  3. Replace each SharePoint URL with the corresponding Guru Card URL using the sharepoint_url → guru_card_id mapping from Step 5
  4. Update the Card via PUT /api/v1/cards/{card-id}
import re
 
def rewrite_links(html: str, url_map: dict) -> str:
    """Replace SharePoint URLs with Guru Card URLs."""
    for sp_url, guru_card_id in url_map.items():
        guru_url = f"https://app.getguru.com/card/{guru_card_id}"
        html = html.replace(sp_url, guru_url)
    return html

Track URLs that appear in Card bodies but have no mapping entry — these are links to SharePoint content that was excluded from migration (e.g., lists, workflows, external sites). Log them for manual resolution.

Step 8: Delta Sync Before Cutover

Use delta queries (GET /drives/{drive-id}/items/{item-id}/delta) and a last-modified window for pages changed during the pilot phase. The delta sync workflow:

  1. Store the delta token from your initial extraction
  2. Re-query with the stored token to get only changed items
  3. Re-transform and re-upload only changed Cards
  4. Lock SharePoint to read-only (set site to "No Access" for non-admin users, or use site lock via SharePoint admin PowerShell: Set-SPOSite -Identity <URL> -LockState ReadOnly) before the final extraction
  5. Run one final delta pass to capture any last-minute changes
  6. Perform the link-rewriting pass again for any new Cards

The freeze period between SharePoint read-only lockdown and Guru go-live should be 24–48 hours to allow for the final extraction, transformation, loading, link rewriting, and validation.

Timeline, Phases, and Resourcing [For PMs]

Do not attempt a "big bang" cutover for enterprise environments. Use a phased approach.

Phase Duration (500–2,000 pages) Dependencies
Content audit & inventory 2–3 days SharePoint admin access, Graph API app registration with Sites.Read.All scope
IA design & mapping 2–3 days Stakeholder sign-off on Collection structure
Script development & testing 3–5 days Developer with Graph API and REST API experience; Guru API token
Pilot migration (10% of content) 1–2 days Test Collection in Guru; 3–5 content owners for review
Full migration run 1–2 days Off-peak hours for SharePoint extraction
Link rewriting & attachment validation 1 day Completed source-to-target URL mapping
Validation & UAT 2–3 days Content owners review assigned Cards; permission spot-checks
Go-live & redirect setup 1 day DNS/link redirect plan; SharePoint read-only lock
Total 13–20 business days

For organizations under 200 pages, compress this to 5–7 days. For 5,000+ pages with complex permissions, expect 4–6 weeks including the permission audit and restructuring phase.

The timeline is driven less by raw volume than by permission cleanup, hierarchy flattening, and link rewriting. A 5,000-page environment with flat permissions and no broken inheritance moves faster than a 1,000-page environment with hundreds of unique permission entries.

Estimated Engineering Hours by Migration Size

Content Volume Estimated Engineering Hours Primary Time Sink
Under 200 pages 16–24 hours Script development and testing
200–500 pages 30–50 hours Transform logic for varied content types
500–2,000 pages 50–80 hours Permission mapping and link rewriting
2,000–5,000 pages 80–160 hours QA, edge cases, attachment volumes
5,000+ pages 160+ hours Permission restructuring, multi-phase rollout

Risk Register

Risk Likelihood Impact Mitigation
SharePoint API throttling stalls extraction High Medium Implement Retry-After handling; run during off-peak hours; use delta queries (1 resource unit each)
Guru rate limits block Card creation Medium Medium Exponential backoff with jitter; throttle to 2–3 requests/second; parallelize across multiple Guru user accounts if needed
Broken internal links between Cards High High Two-pass migration: create Cards first, then update links using URL → Card ID map; log unmapped URLs
Permission escalation (restricted content becomes broadly visible) Medium Critical Audit permissions pre-migration; map to separate Collections; test with least-privileged user accounts before go-live
Image/attachment rendering failures Medium Medium Validate attachment URLs post-upload; re-host all images via Guru attachment endpoint; check for expired SharePoint auth tokens in cached URLs
Deep hierarchy becomes unusable in Guru Medium Medium Flatten before import; split into multiple Collections; use Tags to preserve former hierarchy metadata
Content drift during migration window Medium Medium Lock SharePoint to read-only 24–48 hours before cutover; run delta sync before final load
Duplicate Cards from duplicate SharePoint pages Low Medium Deduplicate during transform phase using content hashing or URL normalization

Preserving Knowledge Trust: Verifiers and History [For Customer Success]

When your team moves from SharePoint to Guru, end-users lose the implicit trust signals they relied on: "I know this page is current because Sarah updated it last month." In Guru, that trust is rebuilt through the Verifier system.

Cards are Guru's core knowledge units — short, searchable, and organized within folders and Collections, with built-in collaboration and version tracking. Each Card can be assigned a Verifier (an individual user or a Group) and a Verification Interval. Guru comes with a feature to verify your knowledge so that users can trust that the content is the most up-to-date. Guru regularly prompts experts to verify the information so your knowledge base always remains accurate.

Map SharePoint page owners to Guru Verifiers during migration, not after. The /api/v1/cards/extended endpoint accepts a verifiers array and a verificationInterval (in days) at creation time. If you skip this, every Card launches as "Unverified," and your team inherits a backlog of hundreds of verification tasks on day one — which typically means nobody verifies anything.

Recommended verification intervals by content type:

  • Policy documents, compliance content: 90 days
  • Process documentation, how-to guides: 180 days
  • Product knowledge, feature docs: 90–120 days (aligned with release cycles)
  • Onboarding materials: 180–365 days
  • Troubleshooting guides: 90 days

SharePoint version history does not transfer to Guru. Guru tracks its own Card revision history (each edit creates a new version with timestamp and author), but importing SharePoint's historical revision trail with original timestamps and authors is not supported. Communicate this to stakeholders before migration. If historical audit trails matter for compliance (SOX, HIPAA, internal audit), archive the SharePoint site in read-only mode before decommissioning. Consider exporting version history to a separate archive (CSV or document) for records retention.

Post-Migration Governance Playbook

After go-live, establish these governance practices to prevent the knowledge decay that likely motivated the migration from SharePoint:

  1. Verification dashboard review: Guru admins should review the "Unverified Cards" dashboard weekly for the first 30 days, then monthly. Set a team OKR for verification compliance (target: >90% of Cards verified within their interval).
  2. New content creation process: Define where new knowledge is created (Guru, not SharePoint). Disable write access to the old SharePoint site after 30 days.
  3. Ongoing content ingestion: For content that continues to originate in SharePoint (e.g., from teams not yet migrated), use Guru's native sync for read-only visibility or build a lightweight scheduled script that checks for new/modified SharePoint pages and creates corresponding Guru Cards.
  4. Tag governance: Assign a Tag taxonomy owner. Review and consolidate Tags quarterly to prevent sprawl.
  5. Analytics review: Use Guru's analytics to identify Cards with zero views after 60 days — these are candidates for archival or consolidation.

What Users Will Notice After Go-Live

Users will notice faster retrieval and clearer ownership, but they will also notice that Guru is Card-first, not page-layout-first. Specific changes to communicate:

  • Some SharePoint pages become multiple Cards (one Card per discrete topic is a Guru best practice; Guru recommends Cards be "short and scannable")
  • Some files remain as attachment links rather than inline content
  • Permissions may be broader at the Collection level than they were item-by-item in SharePoint — communicate any access changes to affected teams before go-live
  • Multi-column layouts, embedded dashboards, and interactive elements are not available in Guru's editor
  • Search behavior is different: Guru's AI-powered search returns Card-level results with AI-generated answers, not page-level results with keyword highlights

A practical pattern: map each SharePoint site owner, library owner, or knowledge steward to a Guru Verifier Group. That gives customer-facing and support teams a visible answer to "who owns this article?" and keeps AI-grounded answers anchored to reviewed content rather than orphaned documents.

Communicate the freeze period clearly. SharePoint should become read-only at least 24–48 hours before the final cutover to prevent content drift during the transition.

Edge Cases and Known Limitations

  • The 5,000-item list view threshold. If you filter or sort a SharePoint document library containing over 5,000 items via the Graph API without indexed columns, the query will fail or return throttled responses. Partition by folder-scoped requests, indexed column $filter expressions, or $skipToken pagination.
  • Item-level broken inheritance. Guru does not support Card-level permissions. A Card inherits its Collection's access settings. If different SharePoint pages within the same library have different access requirements, they must be split across separate Guru Collections — each with its own Group assignments.
  • Unsupported web parts. SharePoint pages containing dynamic web parts (Power BI dashboards, Hero sections, Quick Links carousels, Embed/iframe, Yammer feeds, Stream video) will not migrate as functional elements. Content must be simplified to static HTML, screenshots with alt text, or external links.
  • Guru's editor is simpler than SharePoint's. Guru's Card editor allows you to format content for clarity and readability. The editor supports Markdown, and allows embedding of images, files, videos, and more. However, complex layouts, multi-column sections, collapsible sections, tabs, and interactive elements are not supported. Guru Cards are designed to be short, focused knowledge units — not long-form documents.
  • SharePoint Group ACLs in native sync. Guru's native SharePoint integration documents that the Graph API cannot retrieve SharePoint Group memberships, so ACLs won't sync for sites that rely exclusively on SharePoint groups (as opposed to Microsoft 365 groups or Azure AD security groups).
  • Large files in Source sync. Guru applies a 50 MB file-size limit across connected sources. Files exceeding this limit are silently excluded.
  • PDF text extraction. Guru does not extract searchable text from PDF attachments. PDFs are stored as downloadable files. If PDF content needs to be searchable, extract the text during transformation and include it in the Card body.
  • No built-in deduplication. If your SharePoint environment has duplicate pages across multiple sites (common with hub sites and content rollups), you will create duplicate Cards unless you deduplicate during the transform phase. Use content hashing (MD5/SHA256 of normalized HTML) or URL-based dedup rules.
  • Large attachment volumes. Guru's attachment upload is per-file with no batch endpoint. A library with 2,000 PDFs averaging 2 MB each takes approximately 45–90 minutes to upload at sustained throughput, depending on network and rate limits.
  • Deep folder trees. Guru supports up to 3 nested folder levels. Anything deeper must be flattened, merged, or split into multiple Collections before migration. Use Tags to preserve the former hierarchy path for searchability.
  • Card content size limits. Guru does not publicly document a maximum Card content size, but empirically, Cards exceeding ~100 KB of HTML content may experience editor performance issues. Long SharePoint pages should be split into multiple Cards.
  • Managed metadata term store. SharePoint's managed metadata (term store) supports hierarchical, multilingual term sets. Guru Tags are flat (no hierarchy). Multi-level term sets must be flattened to leaf-node Tags or concatenated (e.g., "Region > EMEA > UK" becomes the Tag "Region-EMEA-UK").

Rollback Procedure

If the migration produces unacceptable results (permission escalation, widespread formatting failures, missing content), execute this rollback:

  1. Revert SharePoint to read-write: Remove the site lock (Set-SPOSite -Identity <URL> -LockState Unlock).
  2. Communicate to users: Send a brief notification that Guru is temporarily unavailable and SharePoint is the active knowledge base.
  3. Archive or delete Guru Collections: Use DELETE /api/v1/collections/{id} to remove migrated Collections. This deletes all Cards and Folders within them. Alternatively, restrict Collection access to admins only while you investigate.
  4. Diagnose root cause: Use your source-to-target ledger to identify which Cards have issues. Common root causes: HTML transformation errors, missing attachment re-hosting, permission mapping errors.
  5. Fix and re-run: Correct the transformation or mapping logic and re-run from Step 4 onward (the extraction cache from Step 3 is still valid).
  6. Re-validate: Run the full validation checklist before attempting go-live again.

Keep the SharePoint site active in read-only mode for at least 30 days post-successful-migration. Retain your source-to-target ledger indefinitely — it's your only mapping between old URLs and new Card IDs for redirect rules and troubleshooting.

Validation and Testing

Validation determines whether the migration succeeded or shipped a broken knowledge base. Run these checks before granting go-live approval:

  1. Record-count reconciliation. Total Cards in Guru must equal total migrated pages from SharePoint, minus explicitly excluded items (archived pages, system pages, duplicates removed). Automate this check: GET /api/v1/collections/{id}/cards and compare counts by Collection against your extraction ledger.
  2. Field-level spot check. Sample 10–15% of Cards (minimum 20 Cards for small migrations). Verify: title accuracy, HTML rendering (no raw HTML tags visible), image display (no broken image icons), correct Collection/Folder placement, Tag assignment, and Verifier assignment.
  3. Link integrity scan. Crawl all Card HTML for URLs. Flag: (a) remaining SharePoint URLs that should have been rewritten, (b) broken <img> src URLs pointing to expired SharePoint auth tokens, (c) links to migrated pages that were excluded and have no Guru equivalent.
  4. Permission audit. Confirm that restricted SharePoint content landed in correctly permissioned Guru Collections. Test with a non-admin, least-privileged user account from each major access group. If restricted HR, legal, or executive documents are visible to unauthorized users, halt go-live and fix Collection permissions immediately.
  5. Search validation. Test 10–15 search queries that users actually use (gathered from SharePoint search logs or support ticket analysis). Confirm that relevant Cards surface in the top 3 results. Test both exact-title searches and natural-language queries.
  6. UAT with content owners. Have 3–5 subject-matter experts review their sections end-to-end before go-live. Provide a structured review template: "Is the content accurate? Are images rendering? Is the Verifier correct? Are any pages missing?"
  7. Attachment verification. Download 5–10 attachments from Guru Cards and confirm they match the original SharePoint files (file size comparison or hash check).
  8. Rollback readiness. Confirm SharePoint is still accessible in read-only mode. Verify your source-to-target ledger is complete and backed up. Test the DELETE /api/v1/collections/{id} endpoint on a test Collection to confirm rollback mechanics work.

For a comprehensive validation framework, see our knowledge base migration checklist.

Build In-House vs. Use a Managed Service

Build in-house when: your content volume is under 500 pages, your permissions model is straightforward (no broken inheritance or fewer than 5 unique access patterns), you have a developer experienced with REST APIs who can commit 40–80 hours over 2–3 weeks, and you don't need to preserve complex formatting (multi-column layouts, embedded dashboards).

Use a managed service when: you have 1,000+ pages, complex permission structures with broken inheritance across multiple libraries, attachment volumes exceeding 1,000 files, compliance requirements around data handling (SOC 2, HIPAA, data residency), or your engineering team cannot absorb a multi-week migration project without delaying product work.

The hidden cost of DIY is not the initial script — it's the re-work. Broken links, missing attachments, permission misalignment, and Guru API rate limit failures typically surface 1–2 weeks after go-live, when content owners start actually using the system. Based on our experience, fixing these issues retroactively takes 30–50% as many engineering hours as the original migration.

ClonePartner has completed knowledge base migrations involving complex permission models, large attachment volumes, and formatting transformations across platforms. For migrations where the SharePoint source involves broken inheritance and the target requires clean Guru Collection-level access, our team handles the permission audit and restructuring as part of the project — your engineers stay on product work. For a deeper look at our approach, see how we run migrations and our zero-downtime guarantee.

Frequently Asked Questions

Can I migrate SharePoint to Guru without losing data?
Page content, titles, tags, and author information can be fully migrated to Guru Cards. However, SharePoint version history, web part interactivity, item-level permissions, and Power Automate workflows cannot be replicated in Guru. Binary file attachments can be re-hosted but remain as Card attachments, not a document management system.
Does Guru have a native SharePoint import tool?
No. Guru offers a native SharePoint sync integration that surfaces SharePoint content in Guru's search, but it does not create editable native Guru Cards. For a structural migration where content lives natively in Guru, you need the Guru REST API, manual recreation, or a managed migration service.
How long does a SharePoint to Guru migration take?
For 500–2,000 pages with a dedicated engineer: 2–3 weeks including audit, script development, migration, and validation. Under 200 pages with simple formatting: 5–7 days. For 5,000+ pages with complex permissions: 3–5 weeks.
What data cannot be migrated from SharePoint to Guru?
SharePoint version history, Power Automate workflows, web part functionality (Hero, Quick Links, Embed, Power BI), item-level broken permission inheritance, list views, and calculated columns have no equivalent in Guru. These must be simplified, linked externally, or dropped.
Is there a downside to migrating SharePoint to Guru?
Yes. You lose SharePoint's document management capabilities (versioning, co-authoring, complex metadata views, Power Automate integration). Guru's editor is simpler — teams used to rich SharePoint page layouts may find it constraining. Item-level permission granularity is also lost since Guru flattens permissions to the Collection level.

More from our Blog