CollabOps

Message Format Reference

Every Markdown construct, token, block, mark, and color you can use in an incoming webhook body

This page lists everything you can put in an incoming webhook body. The text form uses Markdown and tokens; the blocks form uses block JSON. Request format and limits are on the Incoming Webhooks page.

What each form can express

Constructtextblocks
Bold · italic · strikethrough · underline · inline code · linkYesYes
List · task · quote · code block · tableYesYes
Text color · background colorNoYes
Toggle (collapsible)NoYes
Issue · change request · document · project · repository · goal · doc folder · pipeline run · channel referenceYesYes
Sprint referenceNoYes
DateYesYes
Heading · dividerShown unformattedShown unformatted
ImageNoNo

Chat messages show headings as plain text without heading size, and do not draw dividers. Use bold instead of a heading when you want emphasis. Images are blocks that point to an image uploaded to CollabOps, so a webhook cannot send them. Link to external images instead.

The text form — Markdown

CommonMark is supported, plus tables and strikethrough.

WriteResult
**bold**Bold
*italic*Italic
~~strike~~Strikethrough
<u>underline</u>Underline. This is the only HTML tag interpreted; other tags show as plain text.
Text wrapped in a pair of backticksInline code
[label](https://collabops.ai)Link
A line starting with # to ######Heading, levels 1 to 6. Shown as plain text in chat.
A line starting with - Bulleted list. Each two-space indent goes one level deeper (up to 5 levels).
A line starting with 1. Numbered list
A line starting with - [ ] or - [x] Task list (unchecked or checked)
A line starting with > Quote
A line containing only ---Divider. Not drawn in chat.
A block fenced by three backticksCode block. You can name the language after the opening backticks.
GFM table syntaxTable. : in the separator row sets column alignment.
A single line breakA new line within the same paragraph.
A blank lineA new paragraph.
![alt text](URL)Images are not shown.

Text color, background color, and toggles have no Markdown syntax, so they are available only in the blocks form.

Tokens

Tokens inside text become issue chips and date chips. They all share one shape.

{{kind:key=value|key=value}}

Key order does not matter. A token with an unknown kind or a missing required key shows up as the literal text you wrote, with no error. When you start using a new token, check once in the channel that it turned into a chip.

Reference chips — issues, change requests, docs, folders, runs, channels and more

{{issue:slug=acme|key=42|label=Login error}}
{{cr:slug=acme|key=318|label=Fix session expiry}}
{{repo:slug=acme|key=7|label=web}}
{{run:slug=acme|key=128|label=nightly}}
KindRefers to
issueIssue
crChange request
docDocument
projectProject
repoRepository (not repository)
goalGoal
folderDoc folder
runPipeline run
channelChat channel
KeyRequiredDescription
slugYesWorkspace slug, the value in https://collabops.ai/<slug>/….
keyYesThe number. For issue #42 it is 42. Only channel takes the channel ID (a UUID) instead of a number.
labelRecommendedTitle shown on the chip. The chip does not look up the real title; it shows this value as is, so include it.

Sprint references cannot be made with text tokens. {{sprint:…}} and {{repository:…}} stay as literal text. Write repositories as repo, and use the blocks form when you need a sprint.

Date

{{date:iso=2026-09-23|hasTime=0}}
{{date:iso=2026-09-23T15:30:00+09:00|hasTime=1}}
KeyRequiredDescription
isoYesYYYY-MM-DD or an ISO 8601 timestamp. Include the time zone offset for timestamps. An unparseable value stays as literal text.
hasTimeNo1 shows the time as well; omitted or 0 shows the date only.

Things to watch with tokens

Do not put tokens inside a code block. They do not become chips, and an internal placeholder string is shown instead.

A token inside bold or inline code still becomes a chip, and the surrounding formatting is dropped.

To show token-shaped text literally, escape the opening braces with backslashes. \{\{issue:…}} is shown as {{issue:…}} instead of a chip.

The blocks form

blocks is a flat array of block objects, rendered in array order. Blocks are never nested; toggles use parentId and tables use tableId to express relationships.

FieldRequiredDescription
idYesA string unique within this message
typeYesBlock type (see below)
attrsDepends on typeBlock attributes
childrenYesArray of inline pieces. Use an empty array [] for blocks without text
parentIdNoFor a block inside a toggle, that toggle's id

Block types

typeattrsDescription
paragraphNoneParagraph
headinglevel 1–6 (required)Heading. Shown as plain text in chat.
listItemkind bullet · ordered · task (required), indent 0–5 (required), checked (task), start (first item of a numbered list)List item. A following item with a larger indent becomes its child.
blockquoteNoneQuote
codeBlocklanguage (optional)Code block. Put one unformatted text piece in children and separate lines with \n.
thematicBreakNoneDivider. children is []. Not drawn in chat.
toggleNoneCollapsible. children is the title shown while collapsed; blocks shown when expanded point to this toggle with parentId. It starts collapsed and expands on click.
tableCelltableId · rowIdx · colIdx (required), colCount · columnAlign (first cell of the table only)Table cell. Consecutive cells with the same tableId form one table. The first row is the header.
table · image · columnList · columnBlocks for the document editor. Build tables with tableCell; images cannot be sent by webhook.

Inline pieces (children)

children mixes text pieces and chip pieces. Text pieces take formatting through marks.

[
  {"text": "Deployed ", "marks": [{"type": "bold"}]},
  {"type": "embed", "embedType": "entityRef",
   "attrs": {"kind": "issue", "workspaceSlug": "acme", "entityKey": 42, "title": "Login error"}},
  {"type": "embed", "embedType": "date",
   "attrs": {"iso": "2026-09-23", "hasTime": false}}
]
embedTypeattrs
entityRefkind · workspaceSlug · entityKey (integer; a channel ID string for channel) · title (all required)
dateiso · hasTime (both required)

entityRef accepts 10 kind values: issue · cr · doc · project · repository · goal · sprint · folder · run · channel. Unlike tokens, repositories are written as repository, and sprints are allowed. For a sprint, entityKey is the sprint group number. The chip shows title as is.

Marks

typeattrsEffect
boldBold
italicItalic
strikethroughStrikethrough
underlineUnderline
codeInline code
linkurl (required)Link
textColorcolor (required)Text color
bgColorcolor (required)Background color

A piece can carry several marks. For example, [{"type": "bold"}, {"type": "link", "attrs": {"url": "https://collabops.ai"}}] is a bold link.

Colors

color accepts only seven names: gray · amber · green · blue · coblue · purple · red. The actual shade for light and dark themes is decided by the app. Any other value, including hex codes, returns 422. To have no color, leave the value out.

Block-level attrs.textColor · attrs.bgColor are accepted without error but are not painted in chat messages. To show color in chat, put a textColor · bgColor mark on the text piece. To color a table cell, put the mark on the text inside the cell, not on the cell's attrs.

Validation

blocks are validated in full before posting. If any block breaks the spec, the whole message is rejected with 422, and error.title names the block by index (from 0), as in blocks.3 rejected.

Table of Contents