Skip to content

Read a Slack Canvas as Markdown

Edit on GitHub

slackcli canvas lists Slack canvases and reads them as Markdown, which makes them usable in a terminal, a diff, or an AI agent’s context.

Terminal window
slackcli canvas list
slackcli canvas list --limit=50
slackcli canvas list --channel=C1234567890 # canvases shared in one channel
slackcli canvas list --json
Option Default Purpose
--limit <number> 20 How many to return (1–1000)
--channel <id> — Channel ID, URL or name ("#general") whose shared canvases to list
--workspace <id|name> — Workspace to use
--json off JSON output
--fields <list> all With --json, only these comma-separated fields (dot paths allowed)

With --json, an empty result writes nothing to stdout and exits 0.

Terminal window
# By canvas file ID
slackcli canvas read F1234567890
# From its Slack URL
slackcli canvas read https://myteam.slack.com/docs/T012AB/F1234567890
# The canvas attached to a channel or DM
slackcli canvas read --channel=C1234567890
# Raw HTML, no conversion
slackcli canvas read F1234567890 --raw
# JSON, with the Markdown in a `markdown` field
slackcli canvas read F1234567890 --json
Option Purpose
--channel <id> Read the canvas attached to this channel or DM
--raw Print the source HTML instead of Markdown
--workspace <id|name> Workspace to use
--json JSON output including metadata and the Markdown
--fields <list> With --json, only these comma-separated fields (dot paths allowed)

--raw takes precedence over --json: with both, stdout carries the HTML, not JSON. --fields then has nothing to select from and is ignored (it is still validated).

Canvas IDs are file IDs: F followed by alphanumerics. Either give one or use --channel (the canvas ID wins when both are given). A channel with no canvas is reported on stderr with exit code 0 and nothing on stdout. An unknown canvas ID exits 1 with Slack’s error.

Slack canvas exports are Quip-based HTML with custom elements. The converter is dependency-free and covers headings, bold/italic/strike/code, links, ordered and unordered and nested lists, task lists, blockquotes, fenced code blocks (preserved verbatim, so inline tags inside them are not mangled), tables as GFM, embedded files and links, and emoji.

<@U…> and <#C…> mentions are resolved to display names and channel names after conversion, so you get @Rafael and #engineering rather than raw IDs.

  • Downloads are capped at 10 MB; a larger canvas is refused rather than buffered.
  • If the download comes back as a Slack sign-in page — which is what an expired token produces — SlackCLI detects it and tells you to re-authenticate instead of printing HTML at you.
  • Reading a canvas needs file-read permission: files:read for standard tokens.

Cookies