Rich messages
Telegram examples. Choose your platform →
Text and images
| Format | Description |
|---|---|
text | A text ad with a CTA. Use inject() to append it to a bot reply, or fetch() to render it yourself. |
image | A photo or animation with a caption and CTA. Use fetch() with image accepted, or fetch_image() / fetchImage(). Choose sendPhoto or sendAnimation from media_type. |
Rich formats
Beyond the classic text CTA, Sidekick serves four rich ad formats built on Telegram Bot API 10.3 rich messages. The server assembles the complete Bot API payload — your bot (or SDK) only adds chat_id and forwards it. Everything is opt-in: bots that don't declare rich support keep today's behavior byte-for-byte.
| Format | Description |
|---|---|
response | Sponsored response — brand header (logo + name), ad copy, primary button, «Sponsored» footer. Reads like a native bot reply. |
card | Sponsored card — brand header, banner image, short text, button row, footer. The visual banner format. |
consent | Consent ad — a two-line question with «Tell me» / «Not interested». Agreeing reveals the full pitch (slideshow + CTA); declining opts the user out of the campaign. |
quiz | Sponsored quiz — questions edited in place, followed by a result card and CTA. Up to 9 questions; any match percentage comes from the campaign’s configured result. |
Request additions
Three optional fields on POST /api/v1/ad (and inject()). Omit all of them and nothing changes — you get text ads exactly as today. Unknown accept_formats values are ignored by the server, never rejected, so a newer SDK against an older server keeps serving.
| Field | Type | Description |
|---|---|---|
accept_formats | string[] | Formats your bot can render: "text", "response", "card", "consent", "quiz". Defaults to ["text"]. If no supported, capability-compatible format remains, the server falls back to ["text"]. |
capabilities | object | Python/HTTP: rich_messages, callbacks, custom_emoji. Node.js: richMessages, callbacks, customEmoji. Rich formats need rich_messages; consent/quiz also need callbacks. Declare custom_emoji only when your bot can use it; otherwise the logo becomes a bold brand name. |
bot_is_admin | boolean | Whether the bot is an admin of the group chat. With group_id, allows ephemeral delivery of scene 1. SDK 0.8.0 sends bot_is_admin but not group_id; use HTTP for group-aware requests. |
Response — rich ad served
200 OK
{"message": "Here is your answer.\n\nРеклама от Sidekick 👇\n\nTry Example for your next project.","has_ad": true,"impression_id": "imp_example","ad": {"text": "Try Example for your next project.","formatted_text": "Try Example for your next project.","button_text": "Learn more","button_url": "https://sidekick-ads.com/api/v1/click/imp_example","format": "response","send": {"method": "sendRichMessage","params": {"rich_message": {"blocks": [{"type": "paragraph","text": [{"type": "bold","text": "Example"}]},{"type": "paragraph","text": "Try Example for your next project."},{"type": "buttons","align": "left","buttons": [{"text": "Learn more","style": "primary","url": "https://sidekick-ads.com/api/v1/click/imp_example"}]},{"type": "footer","text": "Sponsored · реклама подобрана Sidekick"}]}}},"fallback": {"format": "text","text": "Try Example for your next project.","formatted_text": "Try Example for your next project.","button_text": "Learn more","button_url": "https://sidekick-ads.com/api/v1/click/imp_example"}}}
- •
ad.sendis a ready Bot API call: forwardsend.paramswith yourchat_idadded tosend.method. Media inside blocks are HTTPS URLs — Telegram downloads them on send, no uploads on your side. - •The invariant:
messageis always filled with the classic text version (your reply + spliced CTA), andad.fallbackcarries the same as separate fields — rendered for yourparse_mode. On any Telegram error, send those instead. A rich ad can never break your bot. - •
send.ephemeral: true(group scene 1 for admin bots) means the payload includes ephemeral delivery — visible only to the target user. If Telegram answersBOT_NOT_ADMIN(rights revoked since your cache), retry the same payload withoutephemeral_message_parameters. The SDK send helper does this automatically. - •Interactive buttons (consent, quiz) carry
callback_dataprefixedsk:. Forward the tap toPOST /api/v1/ad/interact(same Bearer token) — the server renders the next scene and returns another{ method, params }to forward. Include the samecapabilitiesobject as on/ad— withoutcustom_emojithe next scene swaps the brand logo for a bold name (the SDK re-sends it automatically). Taps are free: billing follows the campaign model (CPM per impression, or per confirmed action for CPA offers) and never charges per tap; clicks keep going through the tracked redirect.