Skip to main content

Send Telegram Interactive Message

Full reference for the endpoint that sends Telegram interactive messages: inline buttons, reply keyboards, and force-reply prompts.

Written by Tarek Khalil

Endpoint

POST https://app.octopods.io/api/v1/telegram/interactive

Telegram’s own platform rules apply: the recipient must have already started a chat with your bot before your backend can message them.

Authentication

Include your Channel API Key in the request header:

X-Octopods-Auth: YOUR_CHANNEL_API_KEY

The key must belong to the Telegram channel connection you want to send from.

See API Key Authentication for how to find this key.

Required parameters

Send the request body as JSON with Content-Type: application/json.

  • destination_user_id — the Telegram chat ID for the recipient. This is the numeric ID Telegram assigns to the conversation between the user and your bot.

  • telegram_interactive_message — the interactive payload itself (see “Message structure” below). May be sent as an object or as a stringified JSON value.

Optional parameters

  • intercom_teammate_id — the ID of the Intercom teammate who should appear as the sender. Defaults to the workspace’s configured default sender.

Message structure

The telegram_interactive_message object always contains:

  • type — one of reply_buttons, reply_keyboard, remove_reply_keyboard, highlight_reply.

  • text — the message text shown to the recipient. Cannot be empty.

  • reply_markup — the interactive payload attached to the message. Required for every type.

Inline buttons (type: "reply_buttons")

Attach tappable buttons directly beneath the message. Each button either opens a URL or triggers an inline reply.

{
  "destination_user_id": "123456789",
  "telegram_interactive_message": {
    "type": "reply_buttons",
    "text": "Your order has shipped. Track or get help below.",
    "reply_markup": {
      "inline_keyboard": [
        [
          { "text": "Track order", "url": "https://example.com/track/ORD-9876" },
          { "text": "Need help",   "switch_inline_query_current_chat": "help order ORD-9876" }
        ]
      ]
    }
  }
}

Each row is an array inside inline_keyboard. Use url for a link button and switch_inline_query_current_chat to trigger an inline-query reply.

Reply keyboard (type: "reply_keyboard")

Replace the user’s keyboard with a custom one that offers text replies, a contact-share button, or a location-share button.

{
  "destination_user_id": "123456789",
  "telegram_interactive_message": {
    "type": "reply_keyboard",
    "text": "How can we help you today?",
    "reply_markup": {
      "keyboard": [
        [
          { "text": "Track my order" },
          { "text": "Return an item" }
        ],
        [
          { "text": "Share my number", "request_contact": true },
          { "text": "Share my location", "request_location": true }
        ]
      ],
      "resize_keyboard": true,
      "one_time_keyboard": true
    }
  }
}

Supported button kinds inside keyboard rows are plain text, request_contact, and request_location.

Remove reply keyboard (type: "remove_reply_keyboard")

Remove the custom reply keyboard and restore the recipient’s default keyboard.

{
  "destination_user_id": "123456789",
  "telegram_interactive_message": {
    "type": "remove_reply_keyboard",
    "text": "Thanks — we've got what we need.",
    "reply_markup": {
      "remove_keyboard": true
    }
  }
}

Force reply (type: "highlight_reply")

Prompt the recipient’s client to draft a reply to this message automatically. Useful for short follow-up questions.

{
  "destination_user_id": "123456789",
  "telegram_interactive_message": {
    "type": "highlight_reply",
    "text": "What's your order number?",
    "reply_markup": {
      "force_reply": true,
      "input_field_placeholder": "e.g. ORD-9876"
    }
  }
}

Example request

POST https://app.octopods.io/api/v1/telegram/interactive
X-Octopods-Auth: YOUR_CHANNEL_API_KEY
Content-Type: application/json{
  "destination_user_id": "123456789",
  "telegram_interactive_message": {
    "type": "reply_buttons",
    "text": "Ready to confirm your appointment?",
    "reply_markup": {
      "inline_keyboard": [
        [
          { "text": "Confirm",    "switch_inline_query_current_chat": "confirm" },
          { "text": "Reschedule", "switch_inline_query_current_chat": "reschedule" }
        ]
      ]
    }
  }
}

Success response

On success the API returns HTTP 201 Created:

{
  "request_id": "3e6b1d2a-9f4e-4c1d-8b7a-1b3c5d7e9f0a",
  "message_id": 7382914,
  "channel_message_id": "tg-2418"
}

Error response

{
  "request_id": "3e6b1d2a-9f4e-4c1d-8b7a-1b3c5d7e9f0a",
  "error_code": 4,
  "error": "You must supply Telegram Interactive Type as one of the valid types reply_buttons, reply_keyboard, remove_reply_keyboard, highlight_reply. Provided type: dropdown."
}

Error codes

Code

Name

When it happens

1

ARGUMENT_MISSING

destination_user_id or telegram_interactive_message is missing, or a required field inside the payload is absent (text, reply markup).

2

EMPTY_BODY

text is empty.

3

USER_INVALID

The recipient’s Telegram user cannot be found on this channel.

4

TYPE_MISMATCH

type is not one of the allowed values, or a field has the wrong shape.

5

TELEGRAM_ERROR

Telegram rejected the send (for example, the recipient has blocked your bot).

6

DEPRECATED_API_KEY

The API key has been rotated or revoked. Fetch the current key from Octopods.

Handling replies

When a recipient taps an inline button or replies via a custom keyboard:

  1. Telegram delivers the reply to Octopods.

  2. Octopods appends it to the same conversation in your Intercom or HubSpot inbox.

  3. Your automation or an agent handles the response like any other inbound Telegram message.

remove_reply_keyboard sends a confirmation message with no ongoing interactive element — there is no user reply to handle.


What’s next

Did this answer your question?