Every Platform Picked a Side

Two API changes, six weeks apart, tell you everything about where the AI agent war in messaging is heading.

On December 31, 2025, Telegram shipped Bot API 9.3 with a new method called sendMessageDraft — “allowing partial messages to be streamed to a user while being generated.” A first-class streaming primitive, designed explicitly for LLM traffic, available to every developer with a bot token.

On January 15, 2026, Meta’s updated WhatsApp Business terms took effect: general-purpose AI assistants are banned from the WhatsApp Business API. ChatGPT, Perplexity, and every other horizontal assistant that had been quietly building distribution on WhatsApp had to leave.

One platform is building APIs for AI agents. The other is deciding which AI agents are allowed to exist — while shipping its own.

I do R&D on an AI assistant and the frameworks that let it talk to users over messaging channels — the work covered in earlier posts on the reactive Telegram bot framework, the RAG pipeline, and draft-message streaming. WhatsApp, Messenger, and Instagram have been on my radar since the first days. This article is the evaluation I actually ran: start from what an LLM needs from a chat API, then hold each platform against those requirements — registration, bot API surface, markdown rendering, and streaming.

The recent timeline, for context:

Date Move What it signals
Oct 2024 Telegram Bot API 7.11: allow_paid_broadcast — up to 1,000 msg/s Throughput becomes a product, not a wall
Mar 2025 WhatsApp Cloud API adds typing indicators (25 s max) Meta acknowledges bots need latency cover
May 2025 xAI pays Telegram $300M to distribute Grok Telegram sells the assistant slot, keeps the platform open
Jul 2025 WhatsApp moves to per-delivered-message pricing Message volume is now a metered cost
Oct 2025 Meta bars general-purpose AI assistants from WhatsApp API (effective Jan 15, 2026) The landlord picks tenants
Dec 2025 Telegram Bot API 9.3: sendMessageDraft Native streaming for LLM output
Mar 2026 Bot API 9.5: drafts available to all bots Streaming is table stakes
Jun 2026 Bot API 10.1: Rich Messages — “stream AI-generated replies with seamless rich formatting” Telegram renders LLM markdown natively
Jun 2026 Meta Business Agent goes global on WhatsApp/Messenger Meta’s own agent is your competitor

What an LLM Actually Needs from a Chat API

Before comparing platforms, define the requirements. They fall out of four properties of large language models that no amount of engineering on your side can remove.

Problem 1: Generation is slow, and getting slower

First tokens arrive in about a second. Full answers take 15–60 seconds. Add retrieval, tool calls, and reasoning steps — the norm for anything called an “agent” — and total generation time stretches to several minutes. Web chat UIs solved this with token streaming: ChatGPT, Claude, and Gemini all render partial text while the model thinks.

A messaging platform gives you no render loop — only discrete messages. So the API must offer at least one of:

  • a draft or partial-message channel that can be updated frequently and cheaply,
  • message editing with a rate budget generous enough for progressive updates,
  • or, at minimum, a typing indicator that survives a multi-minute generation.

Silence is not an option. A user who sees nothing for 90 seconds assumes the bot is dead and sends “hello??” — which, in a naive pipeline, enqueues a second LLM run behind the first.

Problem 2: Models speak Markdown

LLMs are trained on Markdown. Left alone, they emit **bold**, fenced code blocks, ## headings, [links](url), numbered lists, and tables. You can prompt the model to output plain text, but you pay for it in answer quality and you fight the model on every response. The pragmatic approach is to let the model write Markdown and make the channel deal with it — which means the platform needs a formatting system with enough expressive power to represent what the model produces.

Problem 3: Answers are long

A thorough answer with a code sample runs 3,000–6,000 characters without trying. Platform text limits range from 1,000 to 4,096 characters. Someone has to split messages — and splitting has rules (never inside a code fence, prefer paragraph boundaries) and consequences (each chunk is a separate push notification).

Problem 4: Token streams collide with rate limits

A model produces 30–80 tokens per second. Messaging rate limits were designed for notifications — a few messages per user per minute. Streaming means dozens of mutations of a single logical message. If every mutation is a full-price API call against a per-chat budget, streaming is arithmetically impossible. The platform either provides a cheap high-frequency channel for partial content, or streaming dies at the rate limiter.

Two more requirements come from operating an agent as a business, not a demo:

  • An agent is an application. It needs buttons, callbacks, file exchange, voice input, and payments — tool results have to land somewhere richer than prose.
  • You build on someone else’s land. Registration friction, per-message cost, and — as of 2026 — whether your agent category is allowed to exist are all part of the API contract.

The scorecard, then:

# Requirement Derived from
R1 Frictionless registration & integration Iteration speed; agents are software, not campaigns
R2 Rich bot API surface (buttons, files, payments) Agents act, not just answer
R3 Markdown-compatible formatting Models emit Markdown
R4 Streaming: drafts, edits, or durable typing signals, with a workable rate budget Minutes-long generation
R5 Throughput & cost that scale with conversation volume Token streams, chunked output
R6 Policy that permits third-party AI agents The 2026 reality

Round 1: Registration and Integration

Telegram. Message @BotFather, send /newbot, receive a token. Under a minute, no company entity, no review, no phone number. Development runs over long polling (getUpdates), so you can build from a laptop with zero public infrastructure — no webhook, no TLS certificate, no tunnel. Webhooks are available when you want push delivery in production, but they are optional. The one restriction: bots cannot initiate conversations — a user must press Start first. That is Telegram’s entire anti-spam model, and it costs an agent nothing in practice.

WhatsApp. You need a Meta developer app, a Meta Business portfolio, business verification (documents, days-to-weeks of waiting), a dedicated phone number that is not already registered to a personal WhatsApp account, a webhook served over public HTTPS, and a system-user access token. The sandbox test number can message five pre-registered recipients. There is a reason an entire industry of Business Solution Providers exists to resell this onboarding.

Messenger. A Facebook app plus a Facebook Page plus App Review for pages_messaging advanced access — including a screencast of your bot and a written use case. Until review passes, the bot answers only app admins and testers.

Instagram. A professional (business/creator) account, and one genuine improvement: since 2024, the Instagram API with Instagram Login lets you integrate messaging without a linked Facebook Page — Meta’s simplest onboarding. App Review for messaging permissions still applies for production access.

R1 verdict: Telegram measures onboarding in seconds; Meta measures it in review cycles. For an agent product where iteration speed is survival, this gap compounds: every new bot, every staging environment, every customer tenant on Telegram is one BotFather command away.


Round 2: The Bot API Surface

An LLM agent without tools is a chatbot; an agent’s tools need UI. Booking a slot, paying an invoice, and choosing from search results all require interaction primitives beyond text.

Capability Telegram WhatsApp Messenger Instagram
Inline buttons + callbacks ✅ arbitrary keyboards, callback_query ⚠️ max 3 reply buttons / 10-row list ✅ buttons + postbacks (3/msg) ⚠️ quick replies (13), ice breakers
Structured forms ✅ Mini Apps (full webview apps) ✅ WhatsApp Flows — genuinely good ⚠️ webview extensions
Media in/out ✅ photo, video, docs to 50 MB (2 GB via local server) ✅ ~16–100 MB by type ✅ 25 MB ✅ image 8 MB, video 25 MB
Voice messages ✅ native, both directions
Payments ✅ in-chat (Stars, providers) ⚠️ region-dependent (IN/BR/SG) ❌ deprecated
Edit sent message editMessageText
Delete sent message
Groups / communities ✅ groups, channels, topics ⚠️ limited groups API
Message drafts (streaming) sendMessageDraft

Two honest observations about Meta’s column. First, WhatsApp Flows deserve credit: declarative, versioned, in-chat forms with validation are better than anything Telegram offers for a rigid checkout funnel. Second, Messenger’s template system (generic, button, receipt templates) was designed in 2016 for decision-tree bots — it is a fine CRM widget kit, but it assumes the developer knows the conversation shape in advance. An LLM agent doesn’t. Its output is open-ended prose with occasional structure, which is exactly the shape templates cannot hold.

R2 verdict: Telegram treats a bot as a first-class application runtime. WhatsApp treats it as a structured business channel. Messenger and Instagram treat it as a support-inbox automation.


Round 3: Rendering LLM Output

This round is where “we support formatting” and “we render what a model writes” turn out to be very different claims.

Telegram: three generations of formatting

Telegram gives you three ways to format a message, and the progression maps neatly onto the history of trying to ship LLM output.

Generation 1: MarkdownV2, the trap. It looks like the obvious choice — the model speaks Markdown, the API accepts Markdown. Then the first real answer arrives:

Latency dropped 3.2x (p99: 41ms -> 12ms) - nice!
400 Bad Request: can't parse entities: Character '.' is reserved
and must be escaped with the preceding '\'

MarkdownV2 reserves eighteen characters — _ * [ ] ( ) ~ ` > # + - = | { } . ! — and every unescaped occurrence anywhere in the text is a hard 400. LLM output is full of periods, dashes, parentheses, and exclamation marks by construction. Escaping them without breaking the intentional formatting requires parsing the Markdown anyway — at which point you should not be emitting MarkdownV2 at all.

Generation 2: parse the Markdown yourself, emit Telegram HTML. Telegram’s HTML parse mode accepts a small, forgiving tag set: <b>, <i>, <s>, <code>, <pre>, <a>, <blockquote>. In our platform, a renderer walks the CommonMark AST — never regex — and maps each node onto that subset:

/**
 * Converts LLM Markdown to Telegram-compatible HTML via the
 * commonmark-java AST. Everything untrusted is escaped on the way in.
 */
final class TelegramHtmlRenderer extends AbstractVisitor {

    private final StringBuilder html = new StringBuilder();

    @Override
    public void visit(Heading heading) {          // Telegram has no <h1>
        html.append("<b>");
        visitChildren(heading);
        html.append("</b>\n");
    }

    @Override
    public void visit(ListItem item) {            // ...and no <ul>/<li>
        html.append(ordered ? index++ + ". " : "• ");
        visitChildren(item);
        html.append("\n");
    }

    @Override
    public void visit(FencedCodeBlock code) {
        html.append("<pre><code class=\"language-")
            .append(sanitizeLanguage(code.getInfo()))   // no attr injection
            .append("\">")
            .append(escapeHtml(code.getLiteral()))
            .append("</code></pre>\n");
    }

    @Override
    public void visit(Image image) {              // no <img> — degrade to link
        if (isSafeUrl(image.getDestination())) {
            html.append("<a href=\"")
                .append(escapeHtml(image.getDestination()))
                .append("\">");
            visitChildren(image);
            html.append("</a>");
        }
    }

    @Override
    public void visit(Text text) {
        html.append(escapeHtml(text.getLiteral()));  // & < > " always escaped
    }
}

Headings become bold lines, list bullets are synthesized manually, images degrade to links, raw HTML from the model gets escaped rather than trusted, and code-fence language strings are sanitized so a creative model (or a prompt-injecting user) cannot smuggle attributes into your markup. This renderer has been the workhorse of our Telegram channel — ~200 lines, no surprises, no 400s.

Generation 3: let Telegram render the Markdown. Bot API 10.1 (June 2026) introduced Rich Messages. The InputRichMessage payload takes raw HTML or raw Markdown and renders it server-side — including things ordinary messages never supported: tables, section headings, collapsible details, math expressions, even slideshows. The changelog says it plainly: rich messages let bots “stream AI-generated replies with seamless rich formatting.”

// The platform now does what TelegramHtmlRenderer did — natively.
client.sendRichMessage(chatId, InputRichMessage.markdown(llmAnswer), ...);

Read that arc again: developers spent 2024–2025 building Markdown-to-Telegram translators, and in 2026 Telegram absorbed the translator into the API. That is what it looks like when a platform treats LLM output as a first-class content type.

WhatsApp: close enough to hurt

WhatsApp text formatting looks Markdown-adjacent, which lulls you: *bold*, _italic_, ~strikethrough~, `inline code`, ``` blocks, plus bulleted/numbered lists and > quotes (added in 2024). But it is a dialect, not Markdown:

  • Bold is single-asterisk *bold*. The model’s **bold** renders as stray asterisks wrapping bold text.
  • There are no headings## Summary arrives as literal hash marks.
  • There are no hyperlinks[docs](https://…) renders as bracket soup; URLs must appear raw.
  • There are no tables.

So WhatsApp needs the same AST treatment with a downgrade profile:

final class WhatsAppDialectRenderer extends AbstractVisitor {
    // heading   -> *Bold line*
    // **bold**  -> *bold*
    // [t](url)  -> "t (url)"
    // table     -> ``` monospace grid ```
    // <html>    -> stripped
}

Workable — we wrote it — but every downgrade loses information, and monospace pseudo-tables on a phone screen are a war crime against your own UX.

Messenger and Instagram: plain text, full stop

The Messenger Send API supports no text formatting at all. No bold, no italic, no code, no links-with-labels — a text field capped at 2,000 characters, rendered verbatim. Instagram is the same model with a tighter cap (1,000 UTF-8 bytes — even less for non-Latin scripts). Structure is supposed to live in templates and quick replies, which, per Round 2, cannot hold open-ended LLM output.

For an agent that explains, reasons, and shows code, this is disqualifying by itself: a code block rendered as proportional-font plain text is unreadable noise.

R3 verdict: Telegram renders what models write — natively since 10.1. WhatsApp renders a lossy dialect of it. Messenger and Instagram render none of it.


Round 4: Streaming a Two-Minute Answer

The defining round. An agent that does retrieval plus two tool calls plus generation will regularly run 60–120 seconds. What does each platform let you show the user during that time?

Telegram: from throttled edits to purpose-built drafts

Even before drafts, Telegram was the only platform where streaming was possible: send a message, then repeatedly editMessageText as tokens accumulate. It worked — our earlier implementation ran on exactly this pattern — but edits are full-price API calls against the ~1 msg/s per-chat budget, each edit re-parses entities (so partial Markdown with an unclosed fence can 400), and the message flickers as it grows.

Bot API 9.3 replaced the workaround with a primitive. sendMessageDraft pushes partial text into an ephemeral draft bubble identified by a draft_id:

  • each call replaces the previous draft content — no ordering gymnastics;
  • the draft is a temporary ~30-second preview, not a real message — it is designed to be overwritten at high frequency;
  • empty text is allowed (since 10.0), so you can show a “thinking” bubble before the first token;
  • when generation completes, one sendMessage (or sendRichMessage) persists the final answer.

The reactive pipeline barely changes from the edit-based version — buffer the token flux, replace the draft each tick, finalize once:

int draftId = ThreadLocalRandom.current().nextInt();
StringBuilder acc = new StringBuilder();

return chatService.streamAnswer(conversationId, question)   // Flux<String> of tokens
        .buffer(Duration.ofSeconds(2))                       // collapse 30-80 tok/s
        .concatMap(batch -> {                                // strictly in order
            acc.append(String.join("", batch));
            return client.sendMessageDraft(
                    chatId, null, draftId,
                    acc.toString(),                          // full accumulated text
                    null, null);                             // plain while partial
        })
        .then(Mono.defer(() ->                               // persist final answer,
                client.sendRichMessage(chatId,               // rendered natively
                        InputRichMessage.markdown(acc.toString()), ...)));

Two details carry the design. concatMap guarantees draft n completes before draft n+1 starts — with flatMap, concurrent updates could arrive out of order and the bubble would jitter backwards. And the stream sends plain text drafts but finalizes with a rich message: partial Markdown (unclosed fences, half-written links) never hits a parser, while the persisted answer gets full native rendering. sendRichMessageDraft exists too, when you want formatted partials.

      sequenceDiagram
    participant U as User
    participant TG as Telegram
    participant A as Agent
    participant LLM as LLM

    U->>TG: question
    TG->>A: update (long polling)
    A->>TG: sendMessageDraft(draft_id, "")
    Note over U: "thinking" bubble appears
    A->>LLM: streaming request

    loop every ~2 s of tokens
        LLM-->>A: token batch
        A->>TG: sendMessageDraft(draft_id, accumulated)
        TG-->>U: draft bubble grows in place
    end

    LLM-->>A: complete
    A->>TG: sendRichMessage(full markdown)
    TG-->>U: final formatted message persists
    

The user experience is indistinguishable from ChatGPT’s web UI — inside a native chat, over a bot API.

WhatsApp: 25 seconds of typing, then silence

WhatsApp’s entire latency story is the typing indicator added in 2025: mark the inbound message read, show “typing…” for at most 25 seconds, after which it expires. There is no draft channel. There is no message editing — businesses cannot edit or delete anything they have sent, ever. There is no way to mutate content in place.

      sequenceDiagram
    participant U as User
    participant WA as WhatsApp Cloud API
    participant A as Agent
    participant LLM as LLM

    U->>WA: question
    WA->>A: webhook POST
    A->>WA: typing_indicator (25 s max)
    A->>LLM: streaming request
    Note over U,WA: 40-120 s of dead air<br/>indicator expired at 25 s
    LLM-->>A: complete response
    A->>A: downgrade markdown to dialect
    A->>WA: send message(s), ≤4096 chars each
    WA-->>U: everything arrives at once
    

The tempting workaround — stream by sending multiple messages as chunks complete — makes things worse: every chunk is a separate bubble with a separate push notification, pair rate limits throttle rapid sends to the same user, and since July 2025 message volume is literally a line item on your invoice. Production WhatsApp agents converge on the same compromise: keep answers short, or accept dead air with a periodic “still working on it…” message that is itself spam.

Messenger and Instagram: same wall, smaller rooms

Messenger has sender_action: typing_on (displays for up to ~20 seconds) and mark-seen; Instagram supports the same sender actions. No edits, no drafts, single-shot delivery into 2,000- and 1,000-character limits respectively. A two-minute agent run on these platforms is 20 seconds of typing indicator followed by 100 seconds of nothing followed by a wall of plain text split across bubbles.

R4 verdict:

Telegram WhatsApp Messenger Instagram
Typing signal ✅ 5 s/call, repeatable ⚠️ 25 s, then expires ⚠️ ~20 s ⚠️ ~20 s
Edit sent message
Draft / partial channel ✅ purpose-built
True streaming UX

Telegram is not merely ahead here. It is the only entrant.


Round 5: Throughput, Cost, and the Policy Wall

Telegram. The API is free. Guidance limits: ~30 messages/second globally, ~1 message/second per chat, 20/minute per group; exceed them and you get 429 with a retry_after you must honor. When 30 msg/s is not enough, allow_paid_broadcast buys up to 1,000 msg/s, paid in Stars per message. There is no session window at all: once a user starts your bot, you can message them tomorrow or next month — free-form, no template approval, no per-message invoice. (You still cannot cold-message strangers, which is the correct trade.)

WhatsApp. Inside the 24-hour customer-service window (opened by an inbound user message), free-form messages are allowed and — since the July 2025 pricing change — free. Outside it, you may only send pre-approved template messages, billed per delivered message, gated by initiation tiers that start at 250 unique customers per day. Default throughput of 80 msg/s auto-scales to 1,000 for high-volume senders, with pair rate limits per recipient. It is a well-engineered pipe — priced and shaped for business notifications, not for chatty agents.

Messenger / Instagram. Free, with the 24-hour standard messaging window and enumerated message tags (HUMAN_AGENT stretches to 7 days) outside it. Rate limits are generous enough not to matter — the formatting and streaming walls bind long before throughput does.

And then, policy — the requirement nobody prices in. In October 2025, Meta changed the WhatsApp Business terms to prohibit general-purpose AI assistants outright, effective January 15, 2026. OpenAI, Perplexity, Luzia, and Poke — products with millions of WhatsApp users — were shown the door. Task-specific business bots (support, bookings, order tracking) remain allowed. Meanwhile Meta’s own Business Agent went global in June 2026, with over a million businesses onboarded and CRM partnerships with Salesforce, Microsoft, and Zendesk. The message is coherent: on Meta’s surfaces, the assistant is Meta AI, the business agent is Meta’s Business Agent, and third-party agents exist in the gaps Meta chooses to leave.

Telegram made the opposite trade: it sold the assistant slot — the $300M Grok deal puts xAI’s model in the search bar, with Telegram taking 50% of subscription revenue — and left the platform open. Your agent competes with Grok on equal API terms, drafts and rich messages included. You are a developer on Telegram; you are a policy exception on WhatsApp.


Building for All Four Anyway

None of this lets you skip Meta’s platforms — three billion people live there, and “meet customers where they are” is the entire pitch of a messaging agent. The engineering answer is the one that survived contact in our platform: a channel-agnostic core, and adapters that negotiate capabilities instead of pretending channels are equal.

      graph LR
    subgraph Core["Channel-agnostic core"]
        LLM["LLM + tools + memory"] --> RP["Reply pipeline<br/>Flux&lt;ReplyAction&gt;"]
    end

    RP --> GW["Outbound gateway<br/>(queue per channel)"]

    GW --> TGA["Telegram adapter<br/>DRAFT / rich markdown"]
    GW --> WAA["WhatsApp adapter<br/>TYPING_ONLY / dialect"]
    GW --> MSA["Messenger adapter<br/>TYPING_ONLY / plain"]
    GW --> IGA["Instagram adapter<br/>TYPING_ONLY / plain"]

    TGA --> TG["Bot API"]
    WAA --> WA["Cloud API"]
    MSA --> MS["Send API"]
    IGA --> IG["Messaging API"]
    

The core emits channel-neutral intents; each adapter declares what it can actually do:

public record ChannelCapabilities(
        StreamingMode streaming,      // DRAFT, EDIT, TYPING_ONLY
        Formatting formatting,        // NATIVE_MARKDOWN, HTML_SUBSET, DIALECT, PLAIN
        int maxMessageChars,
        boolean canEditSent,
        boolean sessionWindow) {
}

public sealed interface ReplyAction {
    record Typing(String conversationId) implements ReplyAction {}
    record StreamChunk(String conversationId, String accumulatedMarkdown) implements ReplyAction {}
    record Finalize(String conversationId, String markdown, List<Button> buttons) implements ReplyAction {}
}

public interface ChannelAdapter {
    ChannelCapabilities capabilities();
    Mono<Void> dispatch(ReplyAction action);
}

The Telegram adapter maps StreamChunk onto sendMessageDraft and Finalize onto sendRichMessage. The WhatsApp adapter drops StreamChunk on the floor, refreshes the typing indicator while the window allows, renders Finalize through the dialect downgrade, and splits at 4,096 characters outside code fences. Messenger and Instagram strip formatting entirely and move buttons into quick replies. The reply pipeline upstream consults capabilities() once and shapes its emission accordingly — the LLM core never learns what a parse mode is. The outbound gateway between them is the same queue-per-channel pattern (Pulsar, in our case) described in the poller/worker architecture post, so a slow channel back-pressures its own queue instead of the model.

One confession about how evaluation meets reality. Our integration registry has an enum of channel providers. It was written two years ago with all the ambition in the world:

public enum ChannelProvider {
    TELEGRAM,
    WEB_CHAT,
//  WHATSAPP,
//  MESSENGER,
//  INSTAGRAM,
}

The commented-out lines are not laziness. Each one is a business case that kept losing: WhatsApp costs money per message and cannot stream; Messenger cannot render a code block; Instagram cannot fit an answer in a bubble. The enum is the verdict, in source control.


The Scoreboard

Requirement Telegram WhatsApp Messenger Instagram
R1 Registration 🟢 1 minute, BotFather 🔴 verification + phone + webhook 🔴 Page + App Review 🟡 IG Login flow, review
R1 Dev loop 🟢 long polling, no infra 🔴 public HTTPS webhook 🔴 webhook + review 🔴 webhook + review
R2 API surface 🟢 apps, payments, groups 🟡 Flows are excellent; rest limited 🟡 2016-era templates 🔴 minimal
R3 Markdown 🟢 native since 10.1; HTML subset before 🟡 lossy dialect 🔴 none 🔴 none
R4 Streaming 🟢 drafts, purpose-built 🔴 25 s typing, then silence 🔴 ~20 s typing 🔴 ~20 s typing
R4 Editing 🟢 🔴 🔴 🔴
Max text 🟢 4,096 + rich blocks 🟢 4,096 🟡 2,000 🔴 1,000 bytes
R5 Cost 🟢 free (paid tier optional) 🔴 per delivered template message 🟢 free 🟢 free
R5 Windows 🟢 none after /start 🔴 24 h + templates 🟡 24 h + tags 🟡 24 h + tags
R6 AI agent policy 🟢 open platform 🔴 general-purpose agents banned 🟡 Meta’s agents favored 🟡 Meta’s agents favored

Who Wins

The developer war is over, and Telegram won it by knockout. It is the only platform where an LLM agent can register in a minute, stream a two-minute answer token by token, and hand the platform raw Markdown to render — tables, math, code and all. Read the Bot API changelog for 2025–2026 and it is hard to miss what it resembles: an LLM-agent product roadmap. Drafts for streaming. Rich messages for model output. Paid broadcast for scale. No other messaging platform ships any of these.

The distribution war belongs to Meta — for Meta. WhatsApp’s reach is three billion people, and for a narrow, task-shaped business agent (order status, bookings, support triage) inside the 24-hour window, it remains the highest-value channel on Earth. But you operate there as a tenant whose landlord runs a competing store on the ground floor: general-purpose assistants are banned by contract, Meta’s Business Agent is one click away for every merchant, and your unit economics are metered per delivered message.

So the answer splits cleanly along what your agent is:

  • If the agent is the product — an assistant, a copilot, anything open-ended — Telegram is not just the best choice; it is close to the only choice among the four. Pair it with your own web chat, where you control the surface outright.
  • If the agent is a feature of an existing business — WhatsApp, inside Meta’s rules, with answers short enough to survive single-shot delivery. Treat Messenger and Instagram as capture channels that route into a richer surface.

The deeper pattern is worth naming. LLMs did not change what a chat API is — they exposed what each platform always believed bots were. Telegram has treated bots as first-class applications since 2015, so when agents arrived it just kept extending the same contract. Meta has always treated bots as call-center automation, so when agents arrived it fenced them into that shape and reserved the interesting territory for itself. APIs are opinions with an SLA — and in 2026, only one platform’s opinion of your AI agent is that it deserves to exist.


The Distribution Math

One more table before you rewrite your roadmap around that verdict. Everything above measured API quality; distribution is the counterweight, and it points the other way.

Platform Monthly active users Where it is the default channel
WhatsApp 3B+ (passed 3 billion in Q1 2025) India (~half a billion users), Brazil, most of Latin America, Africa, southern Europe
Instagram 3B (announced September 2025) Consumer discovery and social commerce, globally
Messenger ~1B US, Canada, parts of Southeast Asia
Telegram 1B+ (crossed 1 billion in March 2025, ~500M daily actives) CIS, Iran, Middle East, parts of Asia; growing in Europe

Deduplicated, Meta’s family reaches nearly 4 billion monthly active people. Telegram — the platform that just won every technical round — is the smallest column on the board. Which is why “the API is better, let’s move everything to Telegram” is a decision that deserves its own risk list:

  1. Your customers decide where the conversation happens, not your architecture. In WhatsApp-default markets — Brazil, India, most of the Global South — a business that is not on WhatsApp is simply invisible. Asking a customer to install a new app to talk to you inverts the entire premise of a messaging channel: you were supposed to meet them where they already are. Every “install Telegram first” is a funnel cliff.
  2. The acquisition machine belongs to Meta. Click-to-message ads — Facebook and Instagram placements that open directly into a WhatsApp or Messenger thread — are a multi-billion-dollar pipeline feeding Meta’s channels. Telegram has nothing comparable: its ad platform is small and channel-oriented, so customers reach your bot through links, QR codes, and search. Great for intent, useless for scale.
  3. Telegram has zero cold reach — by design. A WhatsApp identity is a phone number, which means your existing customer base is addressable via (paid, templated) business-initiated messages. A Telegram bot cannot initiate anything: until a customer taps Start, they do not exist. It is the best anti-spam model in messaging and the worst re-activation model in commerce. If your business lives on reminders, win-backs, and notifications to people who never opted into a bot, Telegram alone cannot carry it.
  4. Telegram is also somebody’s platform. The technical winner is still a single company with its own risk surface: Durov’s 2024 arrest in France, recurring bans and restrictions across jurisdictions, and a policy that could pivot just as WhatsApp’s did. Moving everything from one landlord to another is not independence — it just changes whose terms-of-service update ruins your quarter.

This is exactly why the channel-adapter architecture earlier is not multi-platform hygiene — it is the hedge. Telegram is where the agent can be good; Meta’s channels are where the customers are; the adapter layer is what lets you refuse to choose.

⚠️ A notice before you onboard onto Meta’s Business Agent. The path Meta offers small businesses — an agent “up and running within minutes” — is a closed, managed service. It runs exclusively on Meta’s own models, on Meta’s infrastructure; the underlying model is not even disclosed. There is no way to bring your own: not a fine-tuned model that knows your domain, not your RAG stack over your own knowledge base, not your guardrails, not a self-hosted model for data that must stay in-house. For a small or medium business, that fine print is the whole deal: your conversation history, customer data, and the agent’s learned behavior live inside Meta’s black box — you cannot audit it, export it, or move it to another channel. Your agent answers with the same brain as the competitor next door, so it can never become a moat. And when Meta changes the pricing, the model, or the policy — as it just did for the entire general-purpose-assistant category — your switching cost is starting from zero. Over a million businesses accepted that trade in the first months. The convenient path and the sovereign path have never been further apart.

The synthesis fits in one line: rent the reach, own the brain. Distribute through whichever platform holds your customers — but keep the agent itself, its model, its memory, and its knowledge on infrastructure you control, behind adapters that treat every messenger as a replaceable last mile.


References

  1. Telegram Bot API
  2. Telegram Bot API Changelog
  3. Telegram Bot API — sendMessageDraft
  4. Telegram Bot API — sendRichMessage
  5. WhatsApp Cloud API — Typing Indicators
  6. WhatsApp Cloud API — Send Messages
  7. TechCrunch — WhatsApp changes its terms to bar general-purpose chatbots
  8. TechCrunch — Meta’s AI agent for WhatsApp Business is now available globally
  9. TechCrunch — xAI to pay Telegram $300M to integrate Grok
  10. Messenger Platform — Send API
  11. Messenger Platform — Sender Actions
  12. Instagram API with Instagram Login — Messaging
  13. CNBC — Instagram now has 3 billion monthly active users
  14. Infobip — WhatsApp statistics: global usage & market overview
  15. Business of Apps — Telegram revenue and usage statistics
  16. Streaming LLM Responses to Telegram with Reactive Draft Messages
  17. Reactive Telegram Client: Polling, Pipelines, and Pulsar
  18. Building a RAG-Powered News Assistant with LangChain4J and Qdrant
  19. Building Reactive Telegram Bot Framework with Java
  20. Running Local LLMs for Coding and Private Agents