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,
MarkdownandMarkdownV2are handled by the same parser and behave identically. - When
parse_modeis provided, theentities/caption_entitiesparameters in the request are ignored; manually supplied entity lists are only used withoutparse_mode.
Where parse_mode applies:
| Method | Field |
|---|---|
| sendMessage, sendMessageDraft, editMessageText | text |
| sendPhoto, sendVideo, sendVoice, sendAudio, sendDocument, sendMediaGroup | caption |
MarkdownV2 Style
Syntax overview:
*bold* or **bold**
_italic_
__underline__
~strikethrough~
||spoiler||
[inline link](https://www.example.com)
[user mention](safew://user?id=123456789)

`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
| Style | Syntax | Notes |
|---|---|---|
| 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
| Syntax | Result |
|---|---|
`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).
Links, Mentions and Custom Emoji
| Syntax | Result |
|---|---|
[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) |
 | 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
<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<,>and&respectively.- The code-block language identifier goes on the
<pre>tag asclass="language-xxx"; a nested<pre><code>...</code></pre>produces a single code-block entity. <a>produces a link for any non-emptyhrefvalue.- The
expandableattribute of<blockquote>currently has no effect; it renders as a regular quote. emoji-idon<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
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
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"
}'