Skip to main content

Team Chat

Team Chat is internal messaging for the people running your Orbit workspace — support agents, admins, developers — not for customers. It sits alongside the customer-facing Inbox but is deliberately a separate surface: nothing posted in a team-chat channel or DM reaches a customer, and no outbound customer message is touched by any team-chat endpoint. Use it for the coordination that happens around customer work — an on-call handoff, a “heads up, deploy going out” note, a quick huddle while triaging an incident — without leaving Orbit for a separate chat tool. This guide walks through the workflows operators run on it every day, then the permissions, notification, and read-state model underneath those workflows. For the full request/response schema, see the Team Chat API reference.

Workflow 1 — On-call handoff: a channel the responders live in

The most common pattern: one standing channel per on-call rotation, [On-Call](/api-reference/oncall) decides who is responding, and the responders coordinate in the channel.
  1. Resolve who is on call with the On-Call APIPOST /api/v1/oncall/resolve returns the current member and the next handoff instant (see the on-call alerting guide for the full rotation setup).
  2. Post the handoff note in the rotation’s channel so both the outgoing and incoming responder see it, with a thread for anything that needs follow-up.
  3. Start a huddle in the same channel the moment a text thread gets too slow and someone just needs to talk it through.
Create the channel once, up front — the creator becomes its owner:
Add both responders (owner/admin only — see the permissions matrix below):
Post the handoff note when shift changes:
Keep anything that needs a back-and-forth in a thread off the main channel, so the channel stays scannable during an incident. Reply with POST .../messages/{messageId}/replies, and load the root plus its replies with GET .../messages/{messageId}/thread:
When the handoff turns into a live triage, start a huddle in the channel:
A huddle is an ad-hoc voice/video room scoped to one channel. Anyone in the channel can start one or join the one already running; it ends automatically when the last participant leaves — there is no separate “end meeting” step. A teammate can check whether a channel has a live huddle with GET .../channels/{channelId}/huddle, and leave theirs with POST .../channels/{channelId}/huddle/leave.

Workflow 2 — Support escalation: a channel paired with an Inbox ticket

The second everyday pattern: an agent working a customer conversation in the Inbox hits something they cannot resolve, and escalates to a specialist channel — without the customer ever seeing the internal discussion.
  1. The agent keeps the customer thread open in the Inbox.
  2. They post the escalation in an internal channel — #support-escalations, or a specialist channel like #billing-specialists — linking or pasting the conversation id.
  3. A specialist answers in a thread on the escalation post, or opens a huddle for anything that needs a live conversation.
  4. The agent takes the answer back into the Inbox conversation and replies to the customer there.
Because Team Chat never touches customer-facing surfaces, the specialist channel discussion is invisible to the customer; the only thing the customer sees is the answer posted back into their Inbox conversation.

Workflow 3 — Direct messages: etiquette and edge cases

DMs are for the 1:1 conversations that do not belong in a channel — a private handoff detail, a heads-up to one specific person. POST /team-chat/dms opens (or returns the existing) thread between the caller and another user, and GET /team-chat/dms lists the caller’s threads:
Two rules keep DMs tidy. First, only the two participants can read, post to, or delete a DM thread — no admin can browse someone else’s DM. Second, a DM you send is not marked read for the recipient until they call POST /team-chat/dms/{threadId}/read — so an unread DM badge means the other person has genuinely not opened it yet.
Team Chat also carries emoji reactions (POST/DELETE .../messages/{messageId}/reactions on channels and DMs), so a 👍 on a handoff post can close the loop without another message in the channel.

Permissions model

Team Chat has two role layers, and the difference matters in practice:
  • Per-channel role (owner / admin / member) — set on the channel’s membership. The creator of a channel becomes its owner; everyone else is added as member unless the owner promotes them.
  • Workspace role (the org-level Admin or Owner set in Settings > Team) — moderates every team channel, independent of channel membership role.
Membership is the authorization boundary everywhere: a DM endpoint returns 403 for a non-participant, channel reads for a non-member return nothing, and search drops a channel out of results the moment you are removed from it — there is no separate revocation path to manage.

Notifications and read state

Reading and attention tracking are designed for async teams:
  • Header notification — when someone posts a channel message, every other member of that channel gets a notification in the app header (the bell and its counter). The same goes for a new DM. This is how a handoff post reaches the incoming responder even while they are looking at the Inbox.
  • Unread countsGET /team-chat/channels returns each channel with unread_count and last_message_at, so a list call alone is enough to render a badge. The unread count is measured against the caller’s per-channel read cursor.
  • Mark a channel readPOST /team-chat/channels/{channelId}/read advances the read cursor to now; the channel’s unread count drops to zero until the next message arrives. DMs have their own equivalent, POST /team-chat/dms/{threadId}/read.
  • Presence and typingPOST /team-chat/presence/heartbeat keeps the caller visible as online (and accepts a status such as away); GET /team-chat/presence returns the online snapshot plus last-seen timestamps; POST /team-chat/presence (delete-style) marks the caller offline on a graceful disconnect. POST /team-chat/typing broadcasts a typing indicator to a channel. These power the “online” dots and typing row in the UI — they carry no message content.

Events and webhooks

Team Chat currently emits no outbound webhooks — there is no webhook event for a new channel message, a huddle, or a DM. The attention surfaces above (the header notification, unread counts, presence) are the integration contract. Two consequences for builders:
  • To drive an external system (for example, pushing on-call chatter into your own status page), poll GET /team-chat/channels for unread counts and fetch message history per channel — search and history are keyset-paginated, so a poll loop with a cursor is cheap.
  • Never point a customer-facing webhook consumer at Team Chat expecting events; the webhook catalog in Webhooks covers customer-facing surfaces (messages, calls, inbox), not internal chat.

Searching back through an incident

GET /team-chat/search finds messages by keyword across every channel the caller belongs to, ranked by relevance and keyset-paginated:
Add channel_id to narrow to one channel, or from/to to bound the search to a date range — the classic post-incident move is “everything in #on-call-platform mentioning the incident id between its start and resolution.” Search only ever covers channels the caller is a member of — it never surfaces messages from a channel they are not in.

Endpoints

See also