Dialog Bot API

Dialog has HTTP bot API. A bot is a Dialog account you own, driven by an external program that holds a secret token. Your program calls an HTTP API to send messages, and receives incoming messages by long-polling (getUpdates) or via a signed webhook. If you've used the Telegram Bot API, this will feel immediately familiar.

Create a bot → ★ View source on GitHub Markdown reference
On this page
  1. Create a bot
  2. Authentication
  3. chat_id format
  4. Receiving messages
  5. Sending messages
  6. Inline buttons
  7. The update object
  8. Commands
  9. Groups & privacy
  10. Method reference
  11. Examples

Base URL: https://dialogmsg.xyz  ·  Everything is a bot user (DMable, addable to groups).  ·  Inline keyboards & callback_query are supported.

1. Create a bot

Bots are self-serve — no approval needed.

Limit: 3 bots per account. Bot accounts cannot log in with a password. Regenerating a token invalidates the previous one instantly.

2. Authentication

Pass the token one of two ways:

# A) Token in the path (point any Telegram library's base URL here):
curl https://dialogmsg.xyz/bot<token>/getMe

# B) Bearer header, via the /api/bot/<method> route:
curl https://dialogmsg.xyz/api/bot/getMe -H "Authorization: Bearer <token>"

Parameters may be sent as a JSON body (Content-Type: application/json) or as a query string — the JSON body wins on conflict. Every response is { "ok": true, "result": … } or { "ok": false, "error_code": …, "description": … }.

3. chat_id — how chats are addressed

ChatFormatExample
Direct message@dm:<a>~<b> — the two logins sorted alphabetically@dm:demo_bot~vnx
Group@grp:<id>@grp:8f3a1c

Usually you just read chat.id off an incoming update and reply to it. A bot can only send to a chat it participates in, otherwise sendMessage returns 403.

4. Receiving messages

Option A — getUpdates (long-polling)

curl "https://dialogmsg.xyz/bot<token>/getUpdates?offset=0&timeout=30"

Option B — Webhook

curl -X POST "https://dialogmsg.xyz/bot<token>/setWebhook" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://your.app/dialog/hook","secret":"my-shared-secret"}'

5. Sending & managing messages

curl -X POST "https://dialogmsg.xyz/bot<token>/sendMessage" \
  -H 'Content-Type: application/json' \
  -d '{"chat_id":"@dm:demo_bot~vnx","text":"Hello 👋"}'

Media methods — sendPhoto / sendVideo / sendAudio / sendDocument — take the media as a data: URL or a public https: URL (field name any of media, photo, document, video, audio, url), plus optional caption and filename. Max 75 MB. You can also editMessageText and deleteMessage your own messages, and send a typing indicator with sendChatAction.

5b. Inline buttons (keyboards)

Attach an inline keyboard to any message with reply_markup (Telegram-shaped) — a list of rows, each a list of buttons. A button is a link (url, opens in the user's browser) or a callback (callback_data, ≤ 64 chars). Works on sendMessage and the media methods, and channel webhooks accept the same buttons field.

curl -X POST ".../sendMessage" -H 'Content-Type: application/json' -d '{
  "chat_id": "@dm:demo_bot~vnx",
  "text": "Pick one:",
  "reply_markup": { "inline_keyboard": [
    [ {"text":"👍 Yes","callback_data":"yes"}, {"text":"👎 No","callback_data":"no"} ],
    [ {"text":"Open site","url":"https://dialogmsg.xyz"} ]
  ] }
}'

When a user taps a callback button you receive a callback_query update (see below). Acknowledge it with answerCallbackQuery (optionally showing a toast/alert), and swap the keyboard or text with editMessageReplyMarkup / editMessageText.

// on a callback_query update:
await call("answerCallbackQuery", { callback_query_id: q.id, text: "You chose " + q.data });
await call("editMessageReplyMarkup", { message_id: q.message.message_id, reply_markup: { inline_keyboard: [] } });

6. The update object

Each item from getUpdates (and each webhook POST body) looks like:

{
  "update_id": 137,
  "message": {
    "message_id": 684,
    "from":  { "login": "vnx", "name": "Vanylix", "is_bot": false },
    "chat":  { "id": "@dm:demo_bot~vnx", "type": "private" },
    "date":  1783923794,
    "text":  "/start",
    "media_type": "image",
    "media": "https://…",
    "media_name": "cat.png"
  }
}

chat.type is "private" or "group". text is present for text; media_typeimage · video · audio · file for media. update_id is the acknowledgement cursor for getUpdates.

A button tap arrives as a callback_query update instead of a message:

{
  "update_id": 140,
  "callback_query": {
    "id": "a1b2c3…",
    "from": { "login": "vnx", "name": "Vanylix", "is_bot": false },
    "message": { "message_id": 684, "chat": { "id": "@dm:demo_bot~vnx", "type": "private" } },
    "data": "yes"
  }
}

7. Commands

Register slash-commands — they power the / command menu that appears in the composer when a user chats with your bot.

curl -X POST .../setMyCommands -H 'Content-Type: application/json' -d '{
  "commands": [
    { "command": "start", "description": "Say hello" },
    { "command": "ping",  "description": "Check the bot is alive" }
  ]
}'

8. Behavior in groups — privacy

Bots are added to groups through the normal member picker. By default a bot has group privacy ON: inside a group it only receives messages that start with a slash command (/…) or @mention the bot. Turn privacy off to receive every group message. Privacy never affects DMs.

9. Method reference

MethodParamsResult
getMebot identity
getMyCommands[{command, description}]
setMyCommandscommandstrue
setWebhookurl, secret?true
deleteWebhooktrue
getUpdatesoffset?, limit?, timeout?[update, …]
sendMessagechat_id, text, reply_markup?sent message
sendPhoto / Video / Audio / Documentchat_id, media, caption?, filename?, reply_markup?sent message
editMessageTextmessage_id, text, reply_markup?true
editMessageReplyMarkupmessage_id, reply_markuptrue
answerCallbackQuerycallback_query_id, text?, show_alert?true
deleteMessagemessage_idtrue
sendChatActionchat_id, actiontrue

10. Example — a polling echo bot (Node.js, zero deps)

const TOKEN = process.env.DIALOG_TOKEN;               // dlg_…
const BASE  = `https://dialogmsg.xyz/bot${TOKEN}`;

async function call(method, params = {}) {
  const r = await fetch(`${BASE}/${method}`, {
    method: "POST", headers: { "Content-Type": "application/json" },
    body: JSON.stringify(params),
  });
  return r.json();
}

let offset = 0;
await call("setMyCommands", { commands: [{ command: "start", description: "Say hi" }] });

while (true) {
  const { result: updates } = await call("getUpdates", { offset, timeout: 30 });
  for (const u of updates) {
    offset = u.update_id + 1;
    const msg = u.message;
    if (!msg?.text) continue;
    const reply = msg.text === "/start" ? "👋 Hi!" : `You said: ${msg.text}`;
    await call("sendMessage", { chat_id: msg.chat.id, text: reply });
  }
}

Run: DIALOG_TOKEN=dlg_… node bot.mjs (Node 18+ for built-in fetch). The full webhook example and every detail live in the Markdown reference on GitHub.

☁️ Arezzo · Tuscany, Italy ━━━━━━━━━━━━━━━━━━━━ 🌡️ 25°C feels like 27°C ☁️ Overcast 💧 Humidity 54% 🌬️ Wind 2 km/h 😎 Lovely out there. 🕐 08:44 · Europe/Rome

↑ A real bot built on this API in ~90 lines — see the polling example above.

← Back to Dialog