Messageboard started with plain text messages. That was intentional — simple to send, simple to display, nothing unexpected in the widget. But as teams started using it for release notes, deployment summaries, and status updates, the same request kept coming up: can the widget just render the Markdown?
Today it can.
How it works
When you send a message via the API, include a Content-Type header that declares the format of your payload. The widget reads that declaration and renders accordingly.
# Send a Markdown message
curl -X POST https://msgboard.tech/api/messages \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: text/markdown" \
-d '{
"id": "release-notes",
"content": "## v2.4.0\n\n- **New**: Rich content rendering\n- **Fix**: Widget scroll position on version change\n- **Docs**: Updated API reference"
}'
# Send an HTML message
curl -X POST https://msgboard.tech/api/messages \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: text/html" \
-d '{
"id": "status-update",
"content": "<p><strong>All systems operational.</strong> Last checked 14:03 UTC.</p>"
}'
The three supported content types are:
Content-Type header | Widget behavior |
|---|---|
text/plain | Displayed as-is, no formatting (default) |
text/markdown | Rendered as Markdown |
text/html | Rendered as sanitized HTML |
If no Content-Type header is provided, the widget falls back to text/plain — existing integrations are unaffected.
Viewing raw source
Sometimes you want to see exactly what was sent, not the rendered output. Every widget has a Raw toggle in the message toolbar. Clicking it switches the widget between the rendered view and the source text, regardless of content type.
This is useful for debugging API payloads, auditing what a webhook actually delivered, or just double-checking that your Markdown syntax came through as intended.
HTML sanitization
HTML messages are sanitized before rendering. Script tags, event handlers, and other executable content are stripped. The intent is to support formatting — headings, links, tables, emphasis — not arbitrary code execution. If your HTML contains elements that get stripped, the plain-text fallback is there.
What this unlocks
The content type header slots into the existing message model without changing anything else. The same message name, the same versioning behavior, the same dashboard layout. You can start sending Markdown today and the widget just works.
A few patterns that become easier now:
- Release notes: structure them with headings and bullet lists, post them once per deploy
- Incident summaries: use bold for status, plain paragraphs for timeline
- Job output: keep it as
text/plain, or wrap key lines in<pre>tags via HTML for monospace display - Internal docs: short-form HTML pages that update in place without a separate doc system
The API reference has the full header spec, and the quickstart has been updated with examples for all three content types.