Ephemeral Messages¶
Bot API 10.2 — July 2026
An ephemeral message is sent into a group but shown to one person. Nobody else in the chat sees it, and it is not part of the chat’s history — there is no message id to fetch later, no forwarding, no search.
It is what a bot should use for anything addressed to one member: an error, a private prompt, a result nobody else asked for. Before this existed the choices were spamming the group or starting a private chat the user may not have opened.
Ephemeral messages are sent by bots.
Sending one¶
from pyrogram import Client, filters
app = Client("my_bot")
@app.on_message(filters.command("balance"))
async def balance(client, message):
await client.send_ephemeral_message(
chat_id=message.chat.id,
receiver_id=message.from_user.id,
text=f"Your balance is {get_balance(message.from_user.id)} Stars.",
)
app.run()
chat_id is the group it appears in; receiver_id is the only person who will see it.
Both are required — an ephemeral message with no receiver has nowhere to go.
Keyboards, replies and rich text¶
The message is otherwise a normal one. It takes a reply_markup, so a private prompt can
carry buttons; reply_parameters, so it can quote the message that triggered it; and
rich_text with rich_text_media for a full rich message:
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
await app.send_ephemeral_message(
chat_id=group_id,
receiver_id=user_id,
text="Only you can see this. Continue?",
reply_markup=InlineKeyboardMarkup([[
InlineKeyboardButton("Yes", callback_data="go"),
InlineKeyboardButton("No", callback_data="stop"),
]]),
)
query_id answers a guest bot query with an ephemeral message — see
Guest Mode and Managed Bots.
Deleting one¶
await app.delete_ephemeral_message(
chat_id=group_id,
receiver_id=user_id,
message_id=sent.id,
)
The receiver has to be named again, because the message only ever existed for them.
Gotchas¶
disable_web_page_previewis accepted and ignored. The RPC behind ephemeral messages has no link preview field; the parameter is kept so existing call sites do not break.These messages are not in the chat history. Do not expect
get_messages()to find one, and do not build a flow that needs to read it back — hold what you need in your own state.Everything about them is per-receiver. To tell three people something privately, send three messages.