Launched:self-serve migrations intoSuperhuman Docs (Coda)
Try it now
01Agent-first
Runs where you already work
Plug it into Claude, ChatGPT or Cursor. Describe the move in plain English; the agent runs it.
02Engineer-led
Our production engine, unlocked
The pipeline our engineers use on managed enterprise migrations — the same code, now something you can drive yourself.
03Pricing
Try 10 pages free, then $1 a page
Credit-based, pay-as-you-go. No scoping call, no quote — sample it on your own docs before you spend anything.
04Sources
NotionSlabConfluenceSoonGoogle DocsSoon
Skip to content

Slack Canvas to Guru Migration: A Verification-First Guide

Migrating Slack Canvas to Guru is mostly editorial: every canvas needs a verifier, interval, and trust state that don't exist in the source. Here's how.

Raajshekhar Rajan Raajshekhar Rajan · · 19 min read
Slack Canvas to Guru Migration: A Verification-First 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

Slack Canvas to Guru Migration: A Verification-First Guide

Migrating Slack Canvas to Guru is 80% editorial work and 20% scripting. The technical conversion — markdown to HTML, channels to collections, files to cards — is straightforward engineering. The hard part is that every Guru card requires a verifier, a verification interval, and carries a visible trust state (either TRUSTED or UNVERIFIED), and none of that metadata exists in Slack Canvas. Somebody has to decide who owns the accuracy of each piece of content and how often it gets reviewed. That decision is human, not technical, and at volume it is the bottleneck that stalls the entire migration.

If your real goal is searchable Slack context rather than curated, durable knowledge, test Guru's Slack Source before committing to a full card migration. Guru can index selected Slack channels and keep them updated near real time, which is often a better fit for working notes than turning every canvas into a verified card. (help.getguru.com)

This guide covers how to triage which canvases deserve card status, assign verification ownership without derailing the project, extract canvases from the Slack API, convert content and handle edge cases, handle access permissions, avoid common rollback scenarios, and deal with what cannot be migrated.

Warning

If you skip the verifier and review-cadence decisions, you do not finish the migration faster. You just move the backlog into Guru, where it becomes a verification queue with no owner.

Why This Migration Is an Editorial Project

Slack Canvas is a lightweight document surface built into Slack. A canvas has a title, markdown content, and an author. There is no concept of content ownership beyond "who created it," no verification workflow, and no expiration signal.

Guru's entire architecture revolves around trust. Every card has a verification status — TRUSTED or UNVERIFIED — plus a timestamp and an assigned verifier, so anyone reading it knows whether it has been recently reviewed. Verification is a core part of how Guru keeps knowledge trustworthy. You can reduce the frequency by setting a custom verification date up to 10 years in the future, but you cannot turn it off entirely.

This asymmetry (which also makes the reverse migration from Guru to Slack Canvas a trust-model downgrade) means a script can convert markdown to HTML, but it cannot decide that the "Q3 OKRs" canvas should be verified quarterly by the VP of Product while the "Onboarding Checklist" needs monthly review by the People Ops team lead. If you bypass this by assigning every migrated canvas to a single "Migration Service Account" with a default 90-day verification interval, the migration will technically succeed. Within three months, that service account will receive thousands of verification requests, the requests will be ignored, and your Guru Trust Score will plummet — destroying user confidence in the platform.

Which Canvases Are Worth Migrating?

Not every canvas belongs in Guru. Slack canvases fall into two categories:

  • Channel canvases — each channel and direct message comes with its own canvas, providing a centralized hub for collecting resources. In practice, these are often meeting agendas, brainstorm dumps, and scratch-pad content. Slack began converting existing channel and DM canvases to canvases in tabs on April 9, 2025, so older inventories may mix legacy channel-canvas language with tabbed-canvas reality.
  • Standalone canvases — created independently, often more deliberate. Product specs, runbooks, process documentation.

Guru cards are short, searchable knowledge units organized within folders and collections, with built-in collaboration and version tracking. A canvas that is meeting notes from March does not need to become a verified card that someone reviews quarterly. (If you simply need to preserve historical canvases for compliance, consider an archival migration to Box instead.)

Good card candidates:

  • Onboarding checklists that still matter after the week they were written
  • SOPs, runbooks, and escalation paths
  • Policy summaries and internal FAQ material
  • Channel canvases that mostly answer "how do we do X?"

Poor card candidates:

  • Meeting notes, standup notes, retros, and brainstorms
  • One-off incident scratchpads once the incident is closed
  • Weekly planning docs with date-stamped content
  • Canvases whose value is the conversation around them, not the document itself

Mixed candidates — project canvases with one durable section and five temporary sections, channel home canvases that combine evergreen links with rotating updates, or incident canvases whose postmortem section should become a card but whose live log should not. Split these during editorial review rather than migrating them wholesale.

Triage framework:

Signal Card-worthy? Typical action
Referenced in multiple channels Yes Migrate as standalone card
Has >5 unique viewers Likely Migrate, assign topic SME as verifier
Last edited >6 months ago Investigate Archive or migrate with long interval
Channel canvas, <500 chars Rarely Skip or consolidate
Contains process/policy language Yes Migrate with short verification interval
Contains temporal data (dates, names) Maybe Migrate only if someone will maintain it

Triage spreadsheet schema: Export your canvas inventory (covered below) and add these columns before writing any code:

Column Values
canvas_id Slack file ID
canvas_title From file object name field
channel_id From linked_channel_id
is_channel_space Boolean from file object
last_edited Unix timestamp, converted to date
char_count Approximate from content length
migrate Y / N / Split
proposed_verifier_email Individual or group email
proposed_interval_days 30 / 90 / 180 / 365
proposed_collection Target Guru collection name
proposed_folder Target folder within collection
notes Free text for edge cases

Distribute this spreadsheet to team leads for review. Give them 5 business days to complete their rows; apply defaults and move forward if they do not respond. Migrations that wait for perfect metadata never finish.

Tip

At volume, do not ask reviewers to read every canvas from scratch. Pre-label likely keep, migrate, and archive candidates using signals like channel linkage, title patterns, last edit date, and whether the canvas reads like instructions rather than a log.

How Do You Assign Verifiers at Volume Without Stalling?

Verification assignment is the single biggest risk of the project stalling. If you ask individual contributors to claim ownership of migrated content, you will get crickets. Nobody volunteers for ongoing review obligations.

What works in practice:

  1. Default to the team lead. For each Slack channel that produced canvases, assign the channel's purpose owner (usually the team lead) as the default verifier. This is a starting point, not a final answer.

  2. Use Guru groups, not individuals. If a group is a verifier, the verification task appears in every group member's queue until someone in the group verifies the card. This distributes load and avoids single-point-of-failure when someone leaves the company.

  3. Pick the interval in bulk by collection, not per card. Rather than deciding card A needs 30-day review and card B needs 90, set a collection-level default: engineering runbooks get 90-day intervals, sales playbooks get 30-day, company policies get 180-day. Refine later. The verificationInterval field takes a number of days; passing null defaults to 30 days.

  4. Set verification during card creation. The POST /api/v1/cards/extended endpoint accepts verificationInterval and verifiers in the same request body, so you do not need a separate call after card creation.

  5. Route only ambiguous items to humans. If ownership is clear and the content class is obvious, do not stop the pipeline. Send only disputed or low-confidence canvases into an editorial review queue.

  6. Plan for verifier turnover before go-live. Confirm with your Guru admin: when a verifier leaves the company, their assigned cards do not automatically reassign. Cards they owned will accumulate in the UNVERIFIED state until someone manually reassigns them. The mitigation is to make groups — not individuals — the primary verifier for every collection. Individual verifiers are acceptable only for cards with a single unambiguous expert owner and a long interval (180+ days).

How to Inventory Slack Canvases via the API

There is no dedicated canvases.list endpoint. To programmatically list canvases, use files.list with the types=canvas filter:

curl -s "https://slack.com/api/files.list?types=canvas&count=100" \
  -H "Authorization: Bearer $SLACK_BOT_TOKEN" | jq '.files[] | {id, name, created, channels, is_channel_space, linked_channel_id}'

Key technical details:

  • Pagination: files.list defaults to 100 results per page. Use count and page parameters to iterate. For a workspace with 2,000 canvases, this is roughly 20 calls.
  • Rate tier: files.list is Tier 3 (50+ requests per minute minimum), so a full inventory of 2,000 canvases is well within limits. (api.slack.com)
  • Channel association: Each file object includes a channels array showing where the canvas was shared, plus linked_channel_id and is_channel_space for channel canvases. Capture all three for triage and collection mapping.
  • Canvas content: To retrieve the actual markdown content of a canvas, use files.info with the file ID. The response includes the document_content object with type: "markdown" and the full markdown body. (api.slack.com)
  • Version history: Slack stores canvas revision history internally, but the API does not expose individual historical revisions through files.list or files.info. You receive only the current version. If you need a record of prior states, export the workspace before migration — workspace exports include the current canvas version as HTML, but revision history is not included in standard exports either. Treat version history as data that will not survive this migration and communicate that to stakeholders.
Info

If you have Slack export rights, workspace exports include the current version of a canvas as HTML, plus references to anchored comments and embedded files. Exports are useful for QA and historical capture even if your primary inventory path is the API. (slack.com)

Data Model: Slack Canvas → Guru Card

Slack Canvas concept Guru equivalent Notes
Canvas title Card preferredPhrase 1:1 mapping
Canvas body (markdown) Card content (HTML or Markdown) Conversion required; see below
Channel Collection or Folder Decision: flat or nested?
Canvas creator Card owner Closest equivalent
(does not exist) verifiers Must be decided by humans
(does not exist) verificationInterval Must be decided by humans; null defaults to 30 days
(does not exist) verificationState All cards start as TRUSTED on creation
Canvas comments (see below) Cannot map to inline comments via API
Embedded images Card images Must be re-hosted; Slack URLs return 403 without auth
Tables (≤300 cells) HTML tables No formulas in source
Version history (not preserved) API returns current version only
// Example Guru API Payload (POST /api/v1/cards/extended)
{
  "preferredPhrase": "Q3 Engineering Roadmap",
  "content": "<h1>Q3 Engineering Roadmap</h1><p>Migrated from Slack Canvas.</p>",
  "boardId": "string",
  "collectionId": "string",
  "verifiers": [{"type": "group", "id": "group-uuid"}],
  "verificationInterval": 90
}

HTML vs. Markdown: Which Content Format to Send Guru

Guru's POST /api/v1/cards/extended endpoint accepts both HTML and Markdown in the content field. The choice has practical consequences:

Send HTML when:

  • Your canvases contain tables. Guru's Markdown parser can mishandle complex table syntax at the edges of the 300-cell cap.
  • Your canvases contain images that have been re-hosted. HTML lets you specify exact src attributes and alt text without ambiguity.
  • You need precise heading levels. HTML <h1>, <h2>, <h3> are unambiguous; Markdown heading interpretation can vary.
  • You want to sanitize and validate content before submission. HTML parsers (e.g., Python's html.parser or lxml) give you fine-grained control over malformed markup before it reaches the API.

Send Markdown when:

  • Canvases are text-only with minimal formatting. The Markdown path is faster to implement and produces cleaner diffs if you need to audit content later.
  • You want to preserve the source format for potential round-tripping back to Slack-compatible tools.

What happens when you send Markdown with edge cases: Guru's Markdown parser handles standard CommonMark reasonably well but has documented inconsistencies with nested lists inside tables, raw HTML blocks embedded in Markdown, and non-standard link syntax. If you are converting at scale and cannot manually inspect every card, convert to HTML and sanitize before submission. Unclosed tags, unsupported inline styles (e.g., style="color:red"), and <script> blocks will cause the endpoint to return 400 Bad Request with a generic error body — see the error handling section below.

How to Convert Canvas Markdown to Guru HTML

Canvas markdown supports H1, H2, and H3 headings — nothing deeper. If a canvas feels dense, split it into multiple cards rather than expecting deep heading hierarchy to organize it.

Specific conversion rules:

  • Headings: #, ##, ### → <h1>, <h2>, <h3>
  • Bold/italic: **text** / _text_ → <strong>, <em>
  • Unordered lists: - item → <ul><li>item</li></ul>
  • Ordered lists: 1. item → <ol><li>item</li></ol>
  • Code blocks: ``` fences → <pre><code>...</code></pre>
  • Inline code: `code` → <code>code</code>
  • Links: [text](url) → <a href="url">text</a>
  • Tables: standard Markdown pipe syntax → <table><tr><td>...</td></tr></table> (max 300 cells; verify count before conversion)
  • Checkboxes: - [ ] / - [x] → <ul><li>...</li></ul> (Guru has no native checkbox element; convert to bullets)
  • Slack user mentions: <@U12345678> → strip entirely or replace with plain-text display name if available from your Slack user directory
  • Slack channel links: <#C12345678> → plain text channel name, optionally with a Slack deep link if the channel will still exist
  • Canvas size cap: Slack caps each document_content object at 1 MiB (as detailed in our Canvas API limits guide). Canvases near that limit almost certainly need to be split into multiple Guru cards.

Guru API Error Taxonomy for Card Creation

The POST /api/v1/cards/extended endpoint returns these common error responses. Plan for each in your pipeline:

HTTP status Common cause Remediation
400 Bad Request Malformed HTML in content field (unclosed tags, unsupported inline styles, <script> blocks) Run HTML through a sanitizer (e.g., bleach in Python, DOMPurify in JS) before submission
400 Bad Request Missing required fields (preferredPhrase, collectionId, or boardId) Validate payload schema before each request
401 Unauthorized Invalid or expired API token Rotate credentials; Guru tokens do not expire but can be revoked
403 Forbidden Token does not have write access to the target collection Confirm the API user is a collection admin, not read-only
404 Not Found collectionId, boardId, or verifiers [].id does not exist Validate IDs against the Guru collections and groups endpoints before batch import
409 Conflict Duplicate preferredPhrase within the same collection Append a disambiguator (e.g., channel name, date) to the card title
429 Too Many Requests Rate limit exceeded Back off and retry; Guru returns no Retry-After header — use exponential backoff starting at 1 second

Log every non-201 response with the full request payload. Do not silently discard failures — a failed card at import time is harder to detect than a failed card during the pre-publish review pass.

Channels → Collections and Folders

The most natural mapping is one Slack channel → one Guru Collection, with canvases becoming cards inside it. For large workspaces this creates too many collections and makes navigation worse.

The alternative: group related channels into a single collection with folders per channel. Guru supports up to three levels of folder nesting inside a collection. If your Slack workspace has #engineering, #eng-backend, and #eng-frontend, one "Engineering" collection with folders per sub-team works well.

A sane default:

  • Collection = team or department. Use when permissions and ownership line up at the team level.
  • Folder = channel or topic cluster. Use when many canvases share the same audience.
  • Card = one answerable unit. Do not force an entire sprawling canvas into one card if the real destination is five separate procedures.

Use a collection-per-channel model only when the Slack channel boundary is also a hard access boundary in Guru.

Access Permissions: Private Channels and Sensitive Content

Guru collections have three permission levels: Public (visible to all workspace members), Private (visible to invited members only), and Shared (visible to specific groups). If a Slack canvas lived in a private channel, migrating it to a public Guru collection exposes it to the entire organization — a compliance and access control failure.

Mapping private channels to Guru permissions via API:

  1. Check is_private on the Slack channel object when building your inventory.
  2. For canvases from private channels, create a Private Guru collection with access restricted to the equivalent Guru group.
  3. Create or verify the Guru group exists before card creation: GET /api/v1/groups to list, POST /api/v1/groups to create.
  4. When creating the collection, set collectionType to PRIVATE and specify memberIds (Guru user IDs of authorized users).
  5. Confirm the API token used for card creation has admin rights to the private collection — a token with only public collection access will return 403 on private collection writes.

For canvases from shared channels (channels that span multiple Slack workspaces), treat the content as sensitive by default and route it through editorial review before assigning a collection.

(help.getguru.com)

For another example of how Guru hierarchy translation works from a different source system, see our Slab to Guru migration guide.

How to Handle Images and Attachments

Images embedded in Slack Canvases use Slack-hosted permalink URLs that require Slack authentication to access. If those URLs are referenced in Guru cards, they will return 403 errors — Guru users do not have Slack tokens when viewing a card. The images will break permanently once the Slack workspace or canvas is deleted.

To migrate attachments correctly:

  1. Parse the content for media. Identify all image and file links within the canvas markdown using the url_private and url_private_download fields in the Slack file object.
  2. Download the asset. Make a GET request to the url_private_download URL using your Slack bot token in the Authorization: Bearer header.
  3. Upload 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 link field with the Guru-hosted URL.
  4. Rewrite the HTML. Replace every old Slack URL in your parsed HTML with the new Guru URL before card creation.
  5. Publish the card. Send the final HTML payload to /api/v1/cards/extended.

This is a per-attachment operation — there is no batch upload endpoint. A canvas with 20 images requires 21 API calls to Guru (20 for images, 1 for the card). Budget for this in your rate limit planning.

Attachment types that do not migrate cleanly:

  • Slack-native video recordings (huddle recordings, clips): These are Slack-proprietary formats with no download path via the standard API. Note their existence during triage; manually download via the Slack UI if preservation is required.
  • Google Drive, Notion, or other third-party embeds: These appear as link previews in canvases, not embedded files. The link transfers; the preview does not. Verify that destination links remain accessible from Guru.
  • Slack workflow buttons and interactive elements: These are not supported in Guru and cannot be migrated. Strip them from the content during conversion.

For a deeper treatment of the re-hosting pattern, see our guide on migrating images, attachments, and embeds without broken links.

Can Slack Canvas Comments Migrate to Guru?

Slack Canvas comments cannot be faithfully migrated to Guru inline comments.

Comments on a canvas behave like messages in threads and appear in both the Threads view and the Activity tab. In the UI, comments are section-anchored — you highlight text and add a comment to a specific passage. But the Slack API does not expose comments with their positional anchors. Comments surface as flat channel thread messages tied to the canvas file via conversations.replies, with no API field indicating which paragraph a comment belongs to.

Guru does have inline commenting similar to Google Docs, but the public API does not support creating inline comments programmatically. Even if it did, the positional anchor data does not exist in the Slack API response to place them correctly.

Practical options:

  • Drop comments entirely (recommended for most migrations). Most Canvas comments are ephemeral discussion ("Looks good," "Updated this section"). Dropping them results in the cleanest Guru instance.
  • Append comments as a section at the bottom of the migrated card, labeled "Migrated Comments," preserving text but not position. Extract the thread using conversations.replies with the canvas file's latest_reply timestamp as a cursor.
  • Merge meaningful comments into the card body. Comments that change the meaning of the knowledge should be folded into the content during editorial review.
  • Archive the original canvas URL as a link in the card so people can reference old discussion threads in Slack.

Do not attempt to reverse-engineer positional anchors. The data does not exist in the Slack API response.

Rate Limits on Both Sides

Slack API Rate Limits

Slack's Web API rate limits apply per method, per workspace, per app. Each method belongs to a tier:

Tier Rate limit Typical methods
Tier 1 ~1 req/min Infrequent admin operations
Tier 2 ~20 req/min Some user and channel lookups
Tier 3 50+ req/min files.list, files.info, paginating collections
Tier 4 100+ req/min Common read operations
Special Per-method conversations.history, chat.postMessage

files.list and files.info are both Tier 3. Exceeding limits returns HTTP 429 with a Retry-After header stating how many seconds to wait. Honor it exactly — continued requests during a backoff window can trigger longer lockouts.

For a workspace with 2,000 canvases, full inventory via files.list requires ~20 paginated calls. Content retrieval via files.info requires 2,000 calls. At Tier 3 minimums, content retrieval alone takes ~40 minutes if run sequentially — parallelize across multiple app tokens if timeline is a constraint.

Guru API Rate Limits

Guru does not publish official rate limit tiers. Empirically observed safe ceiling: 200 requests per minute per API token. The API returns HTTP 429 when throttled with no Retry-After header — implement exponential backoff starting at 1 second, doubling up to a 60-second ceiling.

Practical throughput math for a 500-canvas migration:

Operation Calls Time at 200 req/min
Card creation (500 cards) 500 2.5 min
Image uploads (avg 3 per canvas, 300 canvases with images) 900 4.5 min
Group/collection validation (pre-flight) ~50 <1 min
Total Guru API time ~1,450 ~8 min

The API work takes under 10 minutes. The editorial triage spreadsheet will have taken two weeks.

Rollback Strategy: What to Do When a Batch Goes Wrong

If you publish 200 cards with wrong verifiers, broken HTML, or incorrect collection assignments, you need a remediation path. Guru does not have a native "undo import" feature, but the API supports bulk updates.

Before publishing any batch: Tag all migrated cards with a migration-specific tag during creation (e.g., migration-2025-q2). This makes them discoverable via the List Cards endpoint for audit or rollback.

To update verifiers in bulk:

# 1. List all cards with the migration tag
GET /api/v1/cards?q=tag:"migration-2025-q2"
 
# 2. For each card, update the verifier
PUT /api/v1/cards/{cardId}
{
  "verifiers": [{"type": "group", "id": "correct-group-uuid"}]
}

To delete a bad batch:

DELETE /api/v1/cards/{cardId}

There is no batch delete endpoint. For 200 cards, deletion is 200 sequential API calls. At 200 req/min, that is about 1 minute of API time.

Dry-run strategy before full migration: Publish a pilot batch of 10–20 cards covering your most complex content types (image-heavy, table-heavy, long content, private channel source). Validate rendering, verifier assignment, permission inheritance, and search visibility before scaling to the full set. Flag these pilot cards with a separate tag (e.g., migration-pilot) so they are easy to identify and clean up.

Post-Migration: Validation and the Ongoing Verification Burden

Validating the migration

Guru Query Language lets you audit cards through the List Cards endpoint using filters on verification state, interval, verifier, attachments, and folder membership. (developer.getguru.com)

verificationState != trusted
hasFileAttachment
verInterval = 90
tag = "migration-2025-q2"

A practical validation pass checks:

  • Card count against the number of canvases that passed triage
  • Every card has an assigned verifier and an intentional interval
  • No image or file URLs still point to Slack private assets (search for slack.com in card content via the API)
  • Table-heavy cards render cleanly and did not silently lose cells
  • Channel-to-folder or channel-to-collection mapping matches your permission design
  • Private channel content landed in private collections, not public ones
  • Pilot batch cards are identified and either promoted or deleted before announcing go-live

For a full validation checklist, see our zero-downtime migration plan.

Bulk Import Alternatives to the API

The API is the only path for migrations over ~50 canvases that require programmatic verifier assignment, custom metadata, and image re-hosting. For completeness, two alternatives exist:

  • Guru's CSV import: Supports bulk card creation with title, content, collection, and folder fields. Does not support setting verifiers or verification intervals per card — all imported cards receive the importing user as verifier and the workspace default interval. Not suitable for large migrations where ownership mapping matters.
  • Guru browser extension: Allows manual capture of web content one card at a time. Not suitable for batch migration.

For Slack Canvas migration at any meaningful scale, the API is the correct path.

The Verification Burden Is Ongoing

This is the part most migration plans underestimate. Assigning verifiers and intervals during migration is step one. Guru's verification system runs continuously after migration — that is by design.

When a card becomes unverified, it is flagged in the verifier's task queue. The card remains searchable and visible, but users can see that it has not been recently reviewed. If your migration created 400 cards with 30-day verification intervals, someone is reviewing roughly 13 cards per day, every day, indefinitely.

This is a feature, not a bug — it is exactly why organizations choose Guru. But if the team is not briefed on the incoming verification workload, trust scores will crater within a month of go-live.

To mitigate this, stagger the verification intervals during the data mapping phase:

Content type Recommended interval
Critical architecture docs, security policies 30 days
Onboarding checklists, active SOPs 90 days
Standard operating procedures, playbooks 90–180 days
Historical reference, archived project docs 365 days
Legal/compliance content (rarely changes) Up to 3,650 days (10 years)
Warning

Before migrating, confirm: Who handles verification when a verifier leaves the company? Are the intervals realistic for the team's capacity? Has leadership signed off on the ongoing review commitment? Are private channel canvases mapped to appropriately restricted collections? Do team leads understand that verification requests will start arriving within 30 days of go-live? If the answers are not clear, the migration may technically succeed while operationally failing.

When to DIY and When to Bring In Help

If your workspace has fewer than 50 canvases and a clear owner for each one, you can handle this with a weekend of scripting and a shared spreadsheet. The editorial decisions fit in a single meeting.

For larger workspaces — hundreds of canvases, multiple teams, ambiguous ownership, private channel content with compliance implications — the editorial coordination becomes a project in itself. The scripting is the easy part. If you need a team that has handled this work across 1,500+ knowledge base migrations and can run both the technical pipeline and the editorial triage without stalling your timeline, that is what we do.

Frequently Asked Questions

Is there a native Slack Canvas to Guru migration tool?
No. There is no built-in import path from Slack Canvas to Guru. You need a custom API-driven pipeline using Slack's files.list (filtered to type canvas) on the extract side and Guru's POST /api/v1/cards/extended on the load side, plus manual editorial decisions for verifier assignments.
How do I list all Slack Canvases via the API?
Use the files.list method with types=canvas. There is no dedicated canvases.list endpoint. Paginate at 100–200 results per page. The method is rate-limited at Tier 3 (50+ requests per minute per workspace per app).
Can Slack Canvas comments migrate to Guru inline comments?
Not faithfully. Canvas comments are section-anchored in the UI, but the Slack API exposes them as flat channel thread messages with no positional data. Guru supports inline comments but has no public API for creating them programmatically. Append important comments as a text section at the bottom of the card, or drop them.
What is Guru's verification interval and can you disable it?
Every Guru card has a verification interval — the frequency in days at which it must be re-reviewed. The default is 30 days. Verification cannot be turned off. The longest workaround is setting a custom verification date up to 10 years in the future.
Does Guru accept Markdown or only HTML via the card creation API?
Guru's POST /api/v1/cards/extended endpoint accepts both HTML and Markdown for the content field. Card bodies are stored as HTML. Converting to clean HTML before import gives you tighter control over tables, images, and link rewrites than relying on Guru's markdown parser.

More from our Blog

Slack Canvas to Box: The Complete Archival Guide
Slack Canvas/Box/Migration Guide

Slack Canvas to Box: The Complete Archival Guide

Moving Slack canvases to Box is archival, not migration. This guide covers inventory, export formats, folder mapping, permissions, rate limits, and metadata for compliance-driven teams.

Nachi Raman Nachi Raman · · 24 min read