> This page is for For Developers.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://whop.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://whop.ferndocs.com/_mcp/server.

# Forums

> Create forum posts, fetch threads, and add comments or reactions inside any Whop community.

Use the Forums API to publish posts, comment on existing threads, and react to posts inside a Whop community's forum experience. Forum content is scoped by `experience_id`, so each forum tile in a community sidebar is a separate experience.

## Initialize the SDK

**`TypeScript`**

```typescript TypeScript
import Whop from "@whop/sdk";

const client = new Whop({
  appID: "app_xxxxxxxxxxxxx",
  apiKey: process.env.WHOP_API_KEY,
});
```

**`Python`**

```python Python
import os
from whop_sdk import Whop

client = Whop(
    app_id="app_xxxxxxxxxxxxx",
    api_key=os.environ["WHOP_API_KEY"],
)
```

## Create a post

Posts support Markdown. Optional fields let you pin the post, paywall it, or mark it as a mention.

**`TypeScript`**

```typescript TypeScript
const post = await client.forumPosts.create({
  experience_id: "exp_xxxxxxxxxxxxx",
  content: "This is the post body in **Markdown**.",
  title: "Optional title for paywalled posts",
  pinned: false,
  is_mention: false,
  paywall_amount: 0, // cents; 500 = $5.00
});
```

**`Python`**

```python Python
post = client.forum_posts.create(
    experience_id="exp_xxxxxxxxxxxxx",
    content="This is the post body in **Markdown**.",
    title="Optional title for paywalled posts",
    pinned=False,
    is_mention=False,
    paywall_amount=0,
)
```

## Read posts

List operations auto-paginate.

**`TypeScript`**

```typescript TypeScript
for await (const page of client.forumPosts.list({
  experience_id: "exp_xxxxxxxxxxxxx",
  first: 10,
})) {
  console.log(page);
}

const post = await client.forumPosts.retrieve("post_xxxxxxxxxxxxx");
```

**`Python`**

```python Python
for page in client.forum_posts.list(
    experience_id="exp_xxxxxxxxxxxxx",
    first=10,
):
    print(page)

post = client.forum_posts.retrieve("post_xxxxxxxxxxxxx")
```

## Comment on a post

Comments are posts with a `parent_id`. Fetch them by passing the parent's ID to `list`.

**`TypeScript`**

```typescript TypeScript
const comment = await client.forumPosts.create({
  experience_id: "exp_xxxxxxxxxxxxx",
  content: "Great post!",
  parent_id: "post_xxxxxxxxxxxxx",
});

for await (const page of client.forumPosts.list({
  experience_id: "exp_xxxxxxxxxxxxx",
  parent_id: "post_xxxxxxxxxxxxx",
  first: 10,
})) {
  console.log(page);
}
```

**`Python`**

```python Python
comment = client.forum_posts.create(
    experience_id="exp_xxxxxxxxxxxxx",
    content="Great post!",
    parent_id="post_xxxxxxxxxxxxx",
)

for page in client.forum_posts.list(
    experience_id="exp_xxxxxxxxxxxxx",
    parent_id="post_xxxxxxxxxxxxx",
    first=10,
):
    print(page)
```

## Like a post

> **Note**
>
> Forum reactions are always `:heart:`. Chat messages accept any emoji, but forum reactions ignore other values.

**`TypeScript`**

```typescript TypeScript
await client.reactions.create({
  resource_id: "post_xxxxxxxxxxxxx",
  emoji: ":heart:",
});
```

**`Python`**

```python Python
client.reactions.create(
    resource_id="post_xxxxxxxxxxxxx",
    emoji=":heart:",
)
```

## Advanced features

### Pinned posts

Pinned posts appear above the feed. Set `pinned: true` on create.

**`TypeScript`**

```typescript TypeScript
await client.forumPosts.create({
  experience_id: "exp_xxxxxxxxxxxxx",
  content: "Important announcement!",
  pinned: true,
});
```

**`Python`**

```python Python
client.forum_posts.create(
    experience_id="exp_xxxxxxxxxxxxx",
    content="Important announcement!",
    pinned=True,
)
```

### Mention users

Use `<@username>` inline. Mentioned users get notified.

**`TypeScript`**

```typescript TypeScript
await client.forumPosts.create({
  experience_id: "exp_xxxxxxxxxxxxx",
  content: "Hey <@username> check this out!",
});
```

**`Python`**

```python Python
client.forum_posts.create(
    experience_id="exp_xxxxxxxxxxxxx",
    content="Hey <@username> check this out!",
)
```

### Paywalled posts

`paywall_amount` is in cents. Readers must pay to see the full content.

**`TypeScript`**

```typescript TypeScript
await client.forumPosts.create({
  experience_id: "exp_xxxxxxxxxxxxx",
  title: "Premium post",
  content: "Exclusive content here",
  paywall_amount: 500, // $5.00
});
```

**`Python`**

```python Python
client.forum_posts.create(
    experience_id="exp_xxxxxxxxxxxxx",
    title="Premium post",
    content="Exclusive content here",
    paywall_amount=500,
)
```

### Pagination with cursors

Beyond auto-pagination, you can step through pages manually using the `cursor` returned on each response.

**`TypeScript`**

```typescript TypeScript
const first = await client.forumPosts.list({
  experience_id: "exp_xxxxxxxxxxxxx",
  first: 10,
});

const next = await client.forumPosts.list({
  experience_id: "exp_xxxxxxxxxxxxx",
  first: 10,
  before: first.cursor,
});
```

**`Python`**

```python Python
first = client.forum_posts.list(
    experience_id="exp_xxxxxxxxxxxxx",
    first=10,
)

next_page = client.forum_posts.list(
    experience_id="exp_xxxxxxxxxxxxx",
    first=10,
    before=first.cursor,
)
```

## Required permissions

Add these to your app's permission list from the [Permissions guide](/developer/guides/permissions) before publishing.

| Permission          | Needed for                     |
| ------------------- | ------------------------------ |
| `forum:read`        | Reading posts and comments     |
| `forum:post:create` | Creating posts and comments    |
| `chat:read`         | Creating and reading reactions |

#### Post object shape

```typescript
{
  id: string;
  comment_count: number;
  content: string | null;
  is_edited: boolean;
  is_pinned: boolean;
  is_poster_admin: boolean;
  like_count: number | null;
  parent_id: string | null; // null = top-level, set = comment
  title: string | null;
  view_count: number | null;
  user: { id: string; name: string | null; username: string };
}
```

Full schema: see the [Forum posts API reference](/api-reference/forum-posts/forum-post).

## Next steps

#### [Build a chat bot](/developer/guides/chat)

Pair forum posts with live chat messages in the same community.

#### [Listen to events with webhooks](/developer/guides/webhooks)

React to forum posts and comments in realtime on your server.

#### [Send notifications](/developer/guides/notifications)

Push users back to your forum when there's something new.

#### [Upload files](/developer/guides/upload-files)

Attach images and videos to posts.