Early bird discounts live! Claim your offer

support.message.received

A member sends a message into a support conversation.

The message body is not in the payload. Webhook deliveries are logged and retried, and member text does not belong in a delivery log. Fetch it with GET /v1/support/conversations/{conversation_id}/messages.

When this fires

Every time a member sends an inbound message that lands in the support inbox — including the very first one, which also raises support.conversation.opened.

This is the workhorse of the family. If you are routing member questions into a helpdesk, an ops channel or an on-call rota, this is the event to subscribe to.

It does not fire when:

  • The text was a recognised bot command, or an answer the bot was waiting for mid-setup.
  • The member is blocked. Their messages are dropped without a trace in the inbox.
  • The member has tripped the inbound rate limit. Excess messages are dropped silently rather than queued.
  • The member edited an earlier message. The stored message is updated in place and no new event fires.

Required ability

support-conversation:view — token must carry this at mint time to subscribe an endpoint to this event.

Payload

{
  "id": "evt_01HX...",
  "type": "support.message.received",
  "created_at": "2026-08-20T10:05:00Z",
  "api_version": "2026-05-01",
  "project_id": "prj_01HX...",
  "data": {
    "message_id": "smg_01HX...",
    "conversation_id": "sup_01HX...",
    "project_id": "prj_01HX...",
    "subscriber_id": "usr_01HX...",
    "type": "text",
    "has_attachments": false
  }
}

Field reference

FieldTypeNotes
idstring ULIDUnique event id, prefixed evt_. Use for idempotent processing.
typestringAlways support.message.received for this event.
created_atISO 8601 timestampServer-side emission time.
api_versionstringWebhook API contract version.
project_idstring ULIDProject this event belongs to.
data.message_idstring ULIDThe stored message.
data.conversation_idstring ULIDThread the message belongs to.
data.project_idstring ULIDMirrors the envelope project_id.
data.subscriber_idstring ULIDThe member's project-scoped user id.
data.typestringOne of text, photo, video, audio, voice, document, sticker, animation, location, contact.
data.has_attachmentsbooleanWhether the message carried media. Use it to decide whether a fetch needs to handle files.

Caveats

  • No body, no name, no file ids. Everything human-readable is behind the API on purpose. Telegram file_id values are effectively credentials for downloading the file and are never sent in a webhook.
  • An album (several photos sent together) arrives as one event per part, each with its own message_id. They share a media_group_id visible through the API, not in the payload.
  • A captioned photo has type: "photo", and the caption is the message body — it is not a separate text message.
  • A caption that starts with / is parsed as a bot command upstream and never reaches the inbox.

How is this guide?

On this page

Subscriby is a product designed by you — for you.

No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request