Get the FREE Ultimate OpenClaw Setup Guide →

slack-mrkdwn

Scanned
npx machina-cli add skill ccheney/robust-skills/slack-mrkdwn --openclaw
Files (1)
SKILL.md
11.4 KB

Slack mrkdwn

Slack's custom text formatting syntax for messages and text objects. Not standard Markdown.

CRITICAL: Two Markup Systems

Slack has two completely different markup syntaxes. Using the wrong one is the most common formatting mistake.

SystemUsed InBoldLinkHeading
Slack mrkdwntext field, text objects (type: "mrkdwn"), section fields*bold*<url|text>Not supported
Standard Markdownmarkdown block only**bold**[text](url)# Heading

Standard Markdown syntax (**bold**, [text](url), # Heading) renders as literal text in mrkdwn contexts. Slack mrkdwn syntax (*bold*, <url|text>) renders as literal text in markdown blocks. Never mix them.

The markdown block (type: "markdown") accepts standard Markdown and translates it for Slack rendering. Supports: headings, bold, italic, strikethrough, lists, links, blockquotes, code blocks, images (rendered as link text). Does not support: syntax-highlighted code blocks, horizontal rules, tables, task lists. A single input block may produce multiple output blocks. Cumulative limit across all markdown blocks in one payload: 12,000 characters.

mrkdwn Syntax

FormatSyntaxNotes
Bold*bold*Not **bold**
Italic_italic_Not *italic*
Strikethrough~strikethrough~Not ~~strikethrough~~
Inline code`code`Same as standard Markdown
Code block```code```No syntax highlighting
Blockquote> quoted textPrefix each line
Link<https://example.com|display text>Not [text](url)
Emoji:emoji_name:Standard or custom. Direct Unicode also works
Newline\nLiteral newline in string
Ordered list1. itemPlain text, no special rendering
Bullet list- itemRendered properly in rich_text blocks only

Inline code disables all other formatting within it — use it to display literal text like *not bold*.

Nested Formatting

Combining adjacent format markers without spaces (e.g., *bold*_italic_) is unreliable and may not render correctly. Always add a space between differently-formatted segments:

*bold* _italic_              ← works reliably
*bold*_italic_               ← may fail to render

For reliable combined formatting on a single word, use rich_text blocks with explicit style objects ({"bold": true, "italic": true}).

Links

<https://example.com>                            Auto-detected URL
<https://example.com|Display Text>               URL with custom text
<mailto:user@example.com|Email Link>             Email link

URLs posted in text are auto-linked by Slack. Use <url|text> for custom display text. Spaces in URLs will break parsing — remove them. mrkdwn formatting inside link labels (e.g., <url|*bold*>) works for basic styles.

Link Unfurling

Slack previews ("unfurls") linked content. Control this per message:

ParameterControlsDefault (API)
unfurl_linksText-based content previewsfalse
unfurl_mediaMedia (images, video, audio) previewstrue

Set both to false to suppress all previews. These are chat.postMessage parameters, not mrkdwn syntax.

Mentions and References

User Mentions

<@U0123ABC456>

Triggers a notification for the mentioned user. Auto-converts to display name.

Channel References

<#C0123ABC456>

Auto-converts to channel name. Users without access see "private channel".

User Group Mentions

<!subteam^SAZ94GDB8>

Notifies all members of the user group.

Special Mentions

SyntaxScopeCaution
<!here>Active members in channelUse sparingly
<!channel>All channel membersTriggers push notifications for everyone
<!everyone>All non-guest workspace membersVery disruptive

Best Practice

Always use IDs, not names. IDs are stable; names change:

  <@U0123ABC456>       (user ID)
  @chris                (name — may not resolve)

  <#C0123ABC456>       (channel ID)
  #general              (name — may not resolve)

To enable name-based parsing, set link_names: 1 in the API call. This is fragile and discouraged.

Date Formatting

Displays dates/times localized to the reader's device timezone (not their Slack preference timezone).

Syntax

<!date^{unix_timestamp}^{token_string}^{optional_link}|{fallback_text}>

Tokens

TokenExample Output
{date_num}2014-02-18
{date}February 18th, 2014 (omits year if within ~6 months)
{date_short}Feb 18, 2014
{date_long}Tuesday, February 18th, 2014
{date_pretty}Yesterday / February 18th, 2014
{date_short_pretty}Yesterday / Feb 18, 2014
{date_long_pretty}Yesterday / Tuesday, February 18th, 2014
{time}6:39 AM (12h) or 06:39 (24h)
{time_secs}6:39:42 AM
{ago}3 minutes ago / 4 hours ago

_pretty variants use relative terms ("yesterday", "today", "tomorrow") when applicable.

Examples

<!date^1392734382^{date} at {time}|February 18th, 2014 at 6:39 AM PST>
<!date^1392734382^{date_short_pretty} {time}|Feb 18, 2014 6:39 AM>
<!date^1392734382^{ago}|February 18th, 2014>

Tokens can be mixed with literal text in the token string. The optional link (third ^-separated parameter) makes the date a clickable hyperlink. Fallback text (after |) displays for clients that cannot render date formatting.

Escaping

Only three characters require escaping in mrkdwn:

CharacterEscape Sequence
&&amp;
<&lt;
>&gt;

Do NOT encode other characters as HTML entities. Only these three are control characters in Slack's markup system.

When displaying user-generated content that may contain these characters, always escape them to prevent unintended formatting or link injection.

Text Object

The text object is the most common composition object in Block Kit. It determines how text is rendered.

{ "type": "mrkdwn", "text": "*bold* and _italic_", "verbatim": false }
{ "type": "plain_text", "text": "No formatting", "emoji": true }

mrkdwn supports Slack mrkdwn syntax. plain_text renders literally. emoji: true converts :emoji: to rendered emoji (plain_text only). Min 1 char, max 3000 chars (section fields max 2000 chars each, max 10 fields).

Where Each Type Is Allowed

ContextAllowed Types
Header block textplain_text only
Section text / fieldsmrkdwn or plain_text
Context elementsmrkdwn or plain_text
Button textplain_text only
Placeholderplain_text only
Input label / hintplain_text only
Modal title / submit / closeplain_text only
Option textplain_text only
Option descriptionmrkdwn or plain_text

Verbatim Behavior

When verbatim: false (default):

  • URLs auto-convert to clickable links
  • Channel names auto-convert to channel links
  • Mentions auto-parse

When verbatim: true:

  • Markdown formatting still processes
  • No auto-linking or mention parsing
  • Useful for displaying raw URLs or text containing @ or # that aren't mentions
{ "type": "mrkdwn", "text": "Check the log at http://example.com/debug", "verbatim": true }

Auto-Parsing Behavior

The parse Parameter (chat.postMessage)

ValueEffect
"none" (default)mrkdwn formatting enabled; minimal auto-parsing of names/URLs
"full"Disables mrkdwn formatting; auto-parses URLs, channel names, user mentions

Disabling Auto-Parsing

In text objects: Set verbatim: true (see above).

In message payloads:

  • Omit link_names argument (or set to 0)
  • Set parse: "none" to disable all auto-parsing

Disabling Formatting Entirely

ContextMethod
Text objectsSet type to "plain_text"
Top-level message textSet mrkdwn: false
AttachmentsExclude field from mrkdwn_in array

Anti-Patterns

Anti-PatternProblemFix
**bold** in mrkdwnRenders literallyUse *bold*
[text](url) in mrkdwnRenders literallyUse <url|text>
# Heading in mrkdwnRenders as plain textUse header block or markdown block
*bold* in markdown blockRenders as italicUse **bold**
link_names: 1 for mentionsFragile — names change, IDs don'tUse <@USERID> directly
HTML-encoding beyond &<>Renders literallyOnly escape &, <, >
Spaces in URLsBreaks link parsingURL-encode spaces as %20
Combining *bold*_italic_ without spaceRendering unreliableAdd space: *bold* _italic_

Secondary Attachments (Legacy)

The attachments array adds secondary content below the main message. One of fallback or text is required (unless using blocks).

FieldDescription
fallbackPlain-text summary for limited clients (always plain text)
colorHex color or "good" / "warning" / "danger"
pretextText above the attachment block
author_name, author_link, author_iconSmall author line (16px icon)
title, title_linkLarge heading with optional hyperlink
textMain body (auto-collapses at 700+ chars)
fieldsArray of { title, value, short } objects
image_urlFull-width image (GIF, JPEG, PNG, BMP)
thumb_urlThumbnail (75px max)
footer, footer_icon, tsFooter metadata (footer max 300 chars)
mrkdwn_inArray of fields to format with mrkdwn: "text", "pretext", "fields"

Only "text", "pretext", and "fields" are accepted values in mrkdwn_in. Fields not listed render as plain text. fallback is always plain text.

Prefer Block Kit blocks over attachments for new development.

Reference Documentation

FilePurpose
references/CHEATSHEET.mdQuick reference: mrkdwn syntax, mentions, dates, escaping at a glance

Sources

Source

git clone https://github.com/ccheney/robust-skills/blob/main/skills/slack-mrkdwn/SKILL.mdView on GitHub

Overview

Slack uses two markup systems: Slack mrkdwn for text fields and text objects, and standard Markdown for markdown blocks. This skill guides generating correctly formatted Slack messages, escaping dynamic content, and adding mentions, date formats, and links without breaking rendering. It covers bold, italic, links, emojis, code blocks, and common pitfalls when mixing systems.

How This Skill Works

The skill activates when generating Slack text content in text fields or text objects with type "mrkdwn". It enforces Slack mrkdwn syntax (*bold*, _italic_, ~strikethrough~, <url|text>), emoji, inline code, code blocks, blockquotes, and proper link labels, while warning against mixing with standard Markdown in the same context. It also addresses escaping user content, mentions, and simple date formatting to ensure predictable rendering across clients.

When to Use It

  • When formatting Slack chat messages sent via chat.postMessage or text objects with type "mrkdwn"
  • When embedding bold, italic, links, or emojis to improve readability in Slack messages
  • When adding user (<@UID>) or channel (<#CID|name>) mentions and date formatting in messages
  • When escaping user-provided content to prevent unintended formatting or injection
  • When debugging rendering issues between Slack mrkdwn and standard Markdown in different blocks or views

Quick Start

  1. Step 1: Identify context (text field or text object) and ensure you’re using Slack mrkdwn syntax
  2. Step 2: Apply formatting for bold, italic, links, mentions, and code with proper Slack mrkdwn markers
  3. Step 3: Escape and test dynamic content, then verify rendering in the target Slack context

Best Practices

  • Use the correct Slack mrkdwn syntax for bold (*bold*), italic (_italic_), and strikethrough (~strikethrough~)
  • Always keep Slack mrkdwn in text fields or text objects; do not mix with standard Markdown in the same context
  • Use <url|text> for links to control display text; avoid spaces in URLs to prevent parsing issues
  • Wrap literal or code-like content in inline code (`code`) or code blocks (```code```) to prevent unintended formatting
  • Test messages in both text fields/text objects and the markdown block if you’re unsure which system will render to users

Example Use Cases

  • Send a concise announcement: *Team Sync* at <https://company.example/sync|Today’s Sync> — see details in the link
  • Mention a teammate: 'Please review this, <@U12345>, and respond by EOD'
  • Channel-wide update: 'Design feedback requested from <#C67890|design-team>'
  • Show code without formatting: use ```function(){ return true; }``` to render as literal code
  • Escape user input: 'User submission: `*not bold*`' to display literal formatting inside inline code

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers