Skip to navigation

Chat

Use the Chat API to send messages, manage channels, open support conversations, and read reactions. Channels are identified by experience_id or channel_id.

This page covers the server-side Chat API, for calling Whop from your backend to post, read, or moderate messages. If you want to render a live Whop chat UI inside your own frontend, see the embedded chat quickstart instead.

Initialize the SDK

import Whop from "@whop/sdk";
const client = new Whop({
appID: "app_xxxxxxxxxxxxx",
apiKey: process.env.WHOP_API_KEY,
});

Send a message

Messages support Markdown and optional attachments uploaded via the Files API.

const message = await client.messages.create({
channel_id: "chat_feed_xxxxxxxxxxxxx", // or an experience_id
content: "Hello! **Markdown** is supported.",
attachments: [
{ id: "file_xxxxxxxxxxxxx" }, // upload via the Files API first
],
});

Read messages

List operations auto-paginate. Iterate the response and the SDK fetches additional pages for you.

for await (const page of client.messages.list({
channel_id: "chat_feed_xxxxxxxxxxxxx",
direction: "desc",
first: 20,
})) {
console.log(page);
}
const single = await client.messages.retrieve("msg_xxxxxxxxxxxxx");

Manage channels

Update moderation settings (banned words, cooldowns, who can post or react) or list every channel on a company.

const channel = await client.chatChannels.update("chat_feed_xxxxxxxxxxxxx", {
ban_media: false,
ban_urls: false,
banned_words: ["spam", "scam"],
user_posts_cooldown_seconds: 10,
who_can_post: "members_only",
who_can_react: "everyone",
});
for await (const page of client.chatChannels.list({
company_id: "biz_xxxxxxxxxxxxx",
first: 10,
})) {
console.log(page);
}

who_can_post and who_can_react accept everyone, members_only, or admins_only.

React to a message

await client.reactions.create({
resource_id: "msg_xxxxxxxxxxxxx",
emoji: "😀", // Unicode or ':heart:' shortcode
});

Support channels

Support channels are 1:1 threads between a user and a company, useful for help desks or concierge flows. create returns the existing channel if one already exists for the user.

const support = await client.supportChannels.create({
company_id: "biz_xxxxxxxxxxxxx",
user_id: "user_xxxxxxxxxxxxx",
});
for await (const page of client.supportChannels.list({
company_id: "biz_xxxxxxxxxxxxx",
open: true,
order: "last_post_sent_at",
direction: "desc",
first: 10,
})) {
console.log(page);
}

Required permissions

Add these from the Permissions guide before publishing your app.

PermissionNeeded for
chat:readReading messages, channels, reactions
chat:message:createPosting messages
chat:moderateUpdating channel settings
support_chat:createOpening support channels
support_chat:readReading support channels
{
id: string;
content: string | null;
created_at: string;
is_edited: boolean;
is_pinned: boolean;
message_type: "text" | "image" | "video" | "poll";
poll: { options: Array<{ id: string; text: string }> | null } | null;
poll_votes: Array<{ count: number; option_id: string | null }>;
reaction_counts: Array<{ count: number; emoji: string | null }>;
replying_to_message_id: string | null;
updated_at: string;
user: { id: string; name: string | null; username: string };
}

Full schema: see the Messages API reference.

Next steps