Hanzo

Channels

Package channels is one inbox for the chat apps you connect — Discord, Slack, Teams, Telegram.

Package channels is one inbox for the chat apps you connect — Discord, Slack, Teams, Telegram.

Base URLhttps://api.hanzo.ai
Operations7
AuthAuthorization: Bearer $HANZO_API_KEY

channels

POST /v1/channels/{channel}/send

Send a message from your org's bot to one chat room

Delivers text, attachments and actions to one room on a connected chat transport — discord, slack, teams or telegram — and answers that transport's own receipt, the messageId it assigned and the Unix second it landed. An unknown channel is a 404.

The body is the envelope's NARROW outbound projection: room, text, attachments, actions, replyTo and idempotency, and nothing else. Identity is not a field — the channel is the path segment and the sender is the caller's validated org — so a body carrying sender, account or channel is refused with 400 rather than having it silently dropped. room.id is required, and so is something to say: text, or at least one attachment.

Requires a validated principal; 403 without one. The room must already belong to the caller's org — each transport verifies the binding itself, so a room this org has not bound is 403 and a room whose route the bot has never learned is 409, meaning someone has to message the bot there first. A transport that fails answers 502 carrying status and shape only, never a token.

Sending is at-most-once only if you ask for it: pass an idempotency string and a replay answers 200 with the PRIOR receipt instead of sending twice, while a send that fails releases the key so the caller can re-attempt. Bodies over 1 MiB are refused. All four transports currently render text only, so attachments and actions are flattened deterministically to one line each after the text rather than dropped.

ParameterInTypeRequiredDescription
channelpathstringyes

GET /v1/channels/allowlist

Returns the caller org's access policy for one channel: whether DMs are pairing-gated, allowlisted or open, whether group rooms are open, allowlisted or disabled, the config-managed DM and group allow entries, the senders approved through PAIRING (read-only here), and the org's named access groups. An unknown channel is a 404.

ParameterInTypeRequiredDescription
channelquerystringChannel is the transport to read: discord, slack, teams or telegram.

PUT /v1/channels/allowlist

Edits the caller org's access policy for one channel and answers the policy as GET would, so both verbs return ONE shape. It requires ORG ADMIN. Every field but channel is optional and applied only when provided: an empty policy string leaves that policy alone, an absent or null list leaves that list alone, and an EMPTY list clears it. It writes only CONFIG-sourced allow entries — senders approved through pairing belong to the approval flow, so a policy edit can never revoke one. An unknown channel is a 404.

Request bodyapplication/json (required)

FieldTypeRequiredDescription
accessGroupsobjectAccessGroups REPLACES the org's named access groups, as group name -> channel -> entries.
channelstringChannel is the transport to edit: discord, slack, teams or telegram.
dmstring[]DM REPLACES the config-managed DM allow entries. Absent or null leaves them alone; an empty list clears them.
dmPolicystringDMPolicy sets how direct messages are admitted: "pairing" (a person must be approved first), "allowlist" (only listed…
groupstring[]Group REPLACES the config-managed group allow entries.
groupPolicystringGroupPolicy sets how group and thread rooms are admitted: "open", "allowlist" or "disabled".

GET /v1/channels/inbox

Returns the messages people have sent to the caller org's connected chat bots, oldest first, in the portable envelope shape every transport normalises into. It is a CURSOR feed, not a search: pass the returned cursor back as since to get only what has arrived since. Only this org's messages are stored under this org, so the feed can never carry another tenant's chat.

ParameterInTypeRequiredDescription
sincequerystringSince is the exclusive cursor: only messages with a higher row id come back. Empty starts at the beginning.
limitquerystringLimit caps how many messages come back.

POST /v1/channels/pairing/approve

Turns one pending pairing code into a standing allow entry, so that person can DM the org's bot on that channel from now on. It requires ORG ADMIN, not merely membership. The first approval an org makes on a channel also bootstraps that sender as the channel's owner, which the answer reports. An unknown or expired code is a 404, and a code always belongs to exactly one org, so it can never approve someone into another tenant.

Request bodyapplication/json (required)

FieldTypeRequiredDescription
channelstringChannel is the transport the request came in on: discord, slack, teams or telegram.
codestringCode is the pairing code from GET /v1/channels/pairing.

GET /v1/channels/pairing

Returns the pairing requests waiting for the caller org to approve — one per person who messaged a connected bot on a channel whose DM policy is "pairing" and who is not allowed yet. Each row carries the CODE an org admin passes to POST /v1/channels/pairing/approve. Expired requests are not returned. Codes are capability strings: they are shown here, and never logged.

GET /v1/channels

Returns every chat transport channels can talk to — Discord, Slack, Teams and Telegram — with the caller org's own facts on each: whether it is connected and to which account, what the transport supports, the org's DM and group access policies, and how many pairing requests are pending approval. The order is fixed, so a console can render the same rows every time. A policy that cannot be read leaves that channel's policy fields empty rather than failing the whole listing.


All Hanzo APIs · Interactive reference

How is this guide?

On this page