The channel and message resources
TeamChat is internal, workspace-to-workspace messaging: a channel is one thread of conversation scoped to your organization, and a message is one post inside it. A channel carries itsid, name, and (optional) description;
each message carries a body plus two fields your own integrations write —
mentions (resolved user ids) and attachments.
Membership is the authorization boundary: you must be a member of a channel
to read its history or post to it, and only owner/admin roles manage
members. When you create a channel, you join it automatically as owner.
Every response on this page follows the same { data, meta } envelope — a
data payload plus a meta block carrying request_id and timestamp — so
the examples below hold for every endpoint here. Errors follow Devotel Orbit’s
{ error, meta } envelope, shown once under Error envelope.
Worked sequence: create, post, read back
The run-through every integration does first: create the channel, post a message that mentions a teammate, then read the history back with sender identity hydrated.1. Create the channel
POST /api/v1/team-chat/channelsname is required (1–120 characters). description is optional (up to
500 characters). The caller is inserted as the channel’s owner member.
Request
my_role: "owner" as a convenience — the channels list
endpoint returns the same field on every row you are a member of.
2. Post a message with @-mentions
POST /api/v1/team-chat/channels/{channelId}/messagesbody or at least one attachment — an empty post is
rejected with 422. body accepts plain text or Slack-style markdown
(**bold**, _italic_, ~strike~, back-tick code blocks, and lists) and is
capped at 8000 characters.
mentions is an array of resolved user ids — write @name in the body text
for the reader and pass the same person’s user id in mentions so the
notification fan-out knows whom to ping without re-parsing your text.
Request
edited_at is null until somebody edits the message. Posting a message also
pushes a realtime refresh hint to every open dashboard and creates a
persistent notification for each other channel member, so an empty client poll
is never required to learn about a new post.
3. Read the channel history back
GET /api/v1/team-chat/channels/{channelId}/messageslimit
query parameter — default 50, maximum 200. Replies live inside their
parent’s thread so a busy thread never floods the channel feed; each root
carries reply_count and last_reply_at when it has replies.
The GET hydrates each row with the sender’s human-readable identity from
your user directory — sender_name and sender_avatar_url — so a UI renders
a person, not the internal sender_user_id. When the sender row was deleted
(or was a system sender) both fields come back null and the id stays.
4. React to a message
POST /api/v1/team-chat/channels/{channelId}/messages/{messageId}/reactionsGET …/messages/reactions?message_ids=….
Request
Error envelope
Schema failures return422 with a VALIDATION_ERROR code and the offending
fields listed under details. The classic case is an empty message — no
body, no attachments:
422
403
NOT_A_MEMBER — handle it before you code a retry loop. On the creation
path a 500 means the insert itself failed; channel names and descriptions are
server-scrubbed only for length, so a narrower client-side validation never
shadows a server accept.