Telegram rich messages

Send headings, lists, tables, media, code blocks, and quotes over Telegram by sending an HTML body.

Your agent can send Telegram messages that look designed, not dumped — a headed status report, a table of results, a highlighted code block, an inline image. You do it the same way you'd send HTML email: put the content in the html field of a send. Telegram renders it as a rich message.

This builds on connecting a Telegram bot. If you've done that, you're ready.

Send formatted content

Point a send at your Telegram inbox and pass html instead of text. Every other field is the same send you already use — inboxId and a recipient in to.

curl -X POST https://api.dairo.app/v1/messages \
  -H "Authorization: Bearer $DAIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inboxId": "inbox_9f2b...",
    "to": ["telegram:5031234567"],
    "html": "<b>Deploy finished</b>\n<i>3 services</i>, <s>0</s> errors.\nDetails: <a href=\"https://status.acme.dev\">status page</a>"
  }'

Send text instead of html for a plain message — nothing to escape, nothing to render. Use html only when you want formatting.

What you can format

Telegram renders a rich set of tags. The everyday ones:

TagRenders as
<b> / <strong>bold
<i> / <em>italic
<u>underline
<s>strikethrough
<code>inline code
<pre>code block
<pre><code class="language-python">code block with syntax highlighting
<blockquote>quoted block
<a href="…">link
<a href="tg://user?id=123">mention a user
<tg-spoiler>hidden until tapped

Rich messages also render headings (<h1>–<h6>), lists (<ul>, <ol>), tables (<table>), media (<img>), and formulas — all in the same html body.

A status report

<h3>Nightly run — Q1 pipeline</h3>
<ul>
  <li><b>Ingested</b> 1.2M rows</li>
  <li><b>Failed</b> <tg-spoiler>3</tg-spoiler> (retrying)</li>
</ul>
<blockquote>Next run at 02:00 UTC.</blockquote>

A table of results

<table>
  <tr><th>Metric</th><th>Value</th></tr>
  <tr><td>Latency p50</td><td><b>42 ms</b></td></tr>
  <tr><td>Errors</td><td>0</td></tr>
</table>

An inline image

<img src="https://cdn.acme.dev/signups.png"/>
<b>Signups this week</b>

Patterns for agents

  • Lead with a heading. A <h3> title makes a status update scannable in the chat list.
  • Tables for numbers, lists for steps. Reserve prose for the one line that matters.
  • Spoilers for noise. Wrap long stack traces or optional detail in <tg-spoiler> so the summary stays clean.
  • Split long reports. A very long report reads better as a few sends — one heading per send keeps each scannable in the chat list.
  • Always have a plain fallback. When you don't need formatting, send text — it's faster to compose and impossible to mis-escape.

Next steps

On this page