Skip to main content

Team Chat Webhook

SendSeven can push a webhook event for messages posted into your Team Chat, so you can build integrations that react to Team Chat -- not just post into it as a bot. Subscribe an endpoint to team_chat.message.created and you'll receive the text, sender, and attachments of every qualifying message in near real time.

Direct messages never emit this webhook

team_chat.message.created fires only for messages posted to a channel. Direct messages -- 1:1 or group DMs, including bot DMs -- are completely invisible to webhooks. There is no event, no flag, and no way to subscribe to DM traffic. If you are building "notify me on any Team Chat message," be aware that DMs will silently never reach your endpoint -- design around channels, not DMs, for anything that needs external visibility.

What triggers it

The event fires for a channel message from either a human teammate or a bot (Bot API), but only when the channel it was posted to has "Allow Bots to send messages" turned on:

  • If a channel's allow_bots is true, every message posted there -- human or bot -- emits team_chat.message.created.
  • If a channel's allow_bots is false (the default), no message posted there emits the event, even from a human teammate.
  • The Knowledge Base system channel never emits this event, regardless of its settings.

This is a fail-closed gate: if SendSeven can't confirm a channel's allow_bots state for some reason, the event is not emitted rather than risking a leak of internal Team Chat traffic to an external endpoint.

In other words, the gate is on the channel, not on who sent the message -- this is what makes the event useful for "read everything posted to this integration channel" use cases, since you don't need separate logic for bot vs. human senders.

Enabling it

  1. Turn on "Allow Bots to send messages" for each channel you want events from -- in that channel's settings (see Team Chat Overview).
  2. Register a webhook endpoint subscribed to team_chat.message.created -- see Webhook Setup.

Payload

The event uses the standard webhook envelope. event_id is the Team Chat message's own ID (a UUID, distinct from the customer-messaging API's msg_... IDs), so it doubles as your deduplication key.

Example -- a bot message:

{
"id": "evt_7f3a2b1c9d8e4f56",
"type": "team_chat.message.created",
"event_id": "9b21e7c4-13ad-4f0a-8f52-6c9d0e3a7711",
"created_at": "2026-08-04T14:30:00Z",
"tenant_id": "tenant_abc123",
"data": {
"channel": {
"id": "3f7c1a92-5d84-4b1e-9a3c-70e2f8d41b05",
"name": "general",
"display_name": "General",
"allow_bots": true,
"is_system": false
},
"message": {
"id": "9b21e7c4-13ad-4f0a-8f52-6c9d0e3a7711",
"channel_id": "3f7c1a92-5d84-4b1e-9a3c-70e2f8d41b05",
"text": "Deploy finished successfully :rocket:",
"sender_type": "bot",
"sender_user_id": null,
"sender_username": "Deploy Bot",
"bot_name": "Deploy Bot",
"mentioned_user_ids": [],
"mentioned_all": false,
"parent_message_id": null,
"attachment_ids": [],
"attachments": [],
"created_at": "2026-08-04T14:30:00Z"
}
}
}

Example -- a human teammate's message (same channel, same gate -- allow_bots only controls whether bots may post, not whether human messages are reported):

{
"id": "evt_1a2b3c4d5e6f7081",
"type": "team_chat.message.created",
"event_id": "c4d5e6f7-8091-4a2b-9c3d-4e5f6a7b8c9d",
"created_at": "2026-08-04T14:32:00Z",
"tenant_id": "tenant_abc123",
"data": {
"channel": {
"id": "3f7c1a92-5d84-4b1e-9a3c-70e2f8d41b05",
"name": "general",
"display_name": "General",
"allow_bots": true,
"is_system": false
},
"message": {
"id": "c4d5e6f7-8091-4a2b-9c3d-4e5f6a7b8c9d",
"channel_id": "3f7c1a92-5d84-4b1e-9a3c-70e2f8d41b05",
"text": "Nice, thanks for the heads up!",
"sender_type": "user",
"sender_user_id": "4c8a0f11-92be-4d7a-b0f3-1d5e6a82c904",
"sender_username": "Alice Johnson",
"bot_name": null,
"mentioned_user_ids": [],
"mentioned_all": false,
"parent_message_id": "9b21e7c4-13ad-4f0a-8f52-6c9d0e3a7711",
"attachment_ids": [],
"attachments": [],
"created_at": "2026-08-04T14:32:00Z"
}
}
}

data.channel fields

FieldTypeDescription
idstringChannel ID.
namestringChannel name (lowercase, no spaces).
display_namestring | nullChannel display name shown in the UI.
allow_botsbooleanAlways true -- the event never fires otherwise.
is_systemboolean | nullWhether this is a system channel.

data.message fields

FieldTypeDescription
idstringMessage ID (matches event_id).
channel_idstringThe channel the message was posted to.
textstring | nullMessage text. null for an attachment-only message.
sender_typestring"user" or "bot".
sender_user_idstring | nullThe human sender's user ID. null for a channel bot message.
sender_usernamestring | nullThe human sender's display name. For a bot message, this is set to the bot's bot_name rather than left null, so a consumer that only reads sender_username still gets a sensible label either way.
bot_namestring | nullThe bot's display name. null for a human message.
mentioned_user_idsarrayUser IDs @mentioned in the message.
mentioned_allbooleanWhether @all was used.
parent_message_idstring | nullSet when the message is a thread reply.
attachment_idsarrayLinked attachment IDs.
attachmentsarrayEnriched attachment info (id, filename, content_type, file_size, public_url, and width/height/duration where applicable).
created_atstringISO 8601 creation timestamp.

Direct messages are invisible to this webhook

To repeat the caution above with the mechanism behind it: the publisher that emits team_chat.message.created is wired only into the channel message-send paths (both the human send endpoint and the bot channel endpoint). The DM bot endpoint and the human DM endpoints never call it -- not because of a gate that could be turned on, but because the code path simply doesn't publish anything for DMs. If your integration needs bot-to-human round trips today, keep that conversation in a channel with "Allow Bots" enabled rather than a DM.

Next