Skip to content

Formatting Options

The Bot API supports formatted message text. Specify the parsing mode via the parse_mode parameter when sending; the server parses the markup into format entities and delivers them to clients.

  • Accepted values: MarkdownV2, Markdown, HTML (case-insensitive).
  • In SafeW, Markdown and MarkdownV2 are handled by the same parser and behave identically.
  • When parse_mode is provided, the entities / caption_entities parameters in the request are ignored; manually supplied entity lists are only used without parse_mode.

Where parse_mode applies:

MethodField
sendMessage, sendMessageDraft, editMessageTexttext
sendPhoto, sendVideo, sendVoice, sendAudio, sendDocument, sendMediaGroupcaption

MarkdownV2 Style

Syntax overview:

*bold* or **bold**
_italic_
__underline__
~strikethrough~
||spoiler||
[inline link](https://www.example.com)
[user mention](safew://user?id=123456789)
![😀](safew://emoji?id=5368324170671202286)
`inline code`
```code block```
```python
multi-line code block
(the first word after the backticks is the language identifier)
```
> quote line 1
> quote line 2
**> expandable quote, terminated with ||

Text Styles

StyleSyntaxNotes
Bold*text* or **text**Single and double asterisks are equivalent, both produce bold
Italic_text_
Underline__text__
Strikethrough~text~Single tilde
Spoiler||text||Content is hidden until tapped

Styles can be nested (e.g. *bold _bold italic_*) and can be used inside quotes. Note that ***text*** does not produce bold italic — the three asterisks are parsed as ** plus *, both of which are bold markers that cancel each other out, producing no formatting at all.

Code

SyntaxResult
`code`Inline code (monospace)
```code``` (on one line)Code block without a language identifier
Multi-line block delimited by ```Code block; the first word on the same line as the opening ``` is the language identifier (e.g. ```python)

Other formatting markers are not parsed inside code, but backslash escapes still apply (e.g. use \` inside inline code to output a literal backtick).

SyntaxResult
[text](https://example.com)Inline link. Only http://, https:// and safew:// URLs are supported; links with other schemes are dropped and only the text is kept
[text](safew://user?id=<user_id>)Mention a user (works without a username; tapping opens the user)
![placeholder](safew://emoji?id=<emoji_document_id>)Custom emoji; the URL must be exactly safew://emoji?id=<number>, the placeholder text is shown when the emoji is unavailable

Quotes

  • A > at the start of a line (optionally followed by a space) starts a quote; consecutive lines starting with > are merged into one quote.
  • **> at the start of a line is the expandable-quote syntax, terminated with ||. The syntax is accepted, but clients currently render it as a regular quote (collapsing is not supported yet).
  • Text styles and inline code can be used inside quotes; do not use spoiler markers inside an expandable quote (|| is treated as the quote terminator there).

Escaping

Prefix a marker character with a backslash \ to display it literally. The escapable character set is:

* _ ~ | [ ] ( ) ` > \

Differences from official Telegram MarkdownV2:

  • Official MarkdownV2 requires escaping all reserved characters such as . ! # + - = { }; SafeW does not — those characters have no special meaning here. Moreover, using \ before a character outside the set above keeps the backslash as-is (e.g. \. renders as \.).
  • Official MarkdownV2 returns a 400 error for unclosed markers; SafeW does not — an unclosed marker simply applies to the rest of the text. Always write markers in pairs.

Markdown Style

parse_mode=Markdown is fully equivalent to MarkdownV2 (same parser); the legacy-Markdown differences of official Telegram do not exist here. New integrations should simply use MarkdownV2.

HTML Style

html
<b>bold</b>, <strong>bold</strong>
<i>italic</i>, <em>italic</em>
<u>underline</u>, <ins>underline</ins>
<s>strikethrough</s>, <strike>strikethrough</strike>, <del>strikethrough</del>
<span class="safew-spoiler">spoiler</span>, <safew-spoiler>spoiler</safew-spoiler>
<a href="https://www.example.com">inline link</a>
<code>inline code</code>
<pre>code block</pre>
<pre class="language-python">code block with language</pre>
<blockquote>quote</blockquote>
<safew-emoji emoji-id="5368324170671202286">😀</safew-emoji>

Notes:

  • Only the tags above are supported; unsupported tags are rendered as-is, including the angle brackets (no error is returned).
  • <, > and & in the text must be written as &lt;, &gt; and &amp; respectively.
  • The code-block language identifier goes on the <pre> tag as class="language-xxx"; a nested <pre><code>...</code></pre> produces a single code-block entity.
  • <a> produces a link for any non-empty href value.
  • The expandable attribute of <blockquote> currently has no effect; it renders as a regular quote.
  • emoji-id on <safew-emoji> is the document ID of the custom emoji; the tag's inner text serves as the placeholder when the emoji is unavailable.

Examples

MarkdownV2

bash
curl -X POST "https://api.safew.bot/<token>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": 987654321,
    "text": "*Order shipped* 🎉\nTracking no: `SF1234567890`\n>Click [here](https://example.com/track) for logistics info",
    "parse_mode": "MarkdownV2"
  }'

HTML

bash
curl -X POST "https://api.safew.bot/<token>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{
    "chat_id": 987654321,
    "text": "<b>Order shipped</b> 🎉\nTracking no: <code>SF1234567890</code>\n<blockquote>Click <a href=\"https://example.com/track\">here</a> for logistics info</blockquote>",
    "parse_mode": "HTML"
  }'