# X (Twitter) Community Top Posts Scraper (`maximedupre/twitter-communities-top-posts-scraper`) Actor

Find public X Community posts by one keyword or phrase, or from public Community IDs or URLs. Choose Top or Latest ranking and get structured rows with post text, community, author, engagement, media, and source links.

- **URL**: https://apify.com/maximedupre/twitter-communities-top-posts-scraper.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Marketing, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.10 / 1,000 community posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 🏘️ See what X Communities are posting

Researchers, marketers, and developers can use this X (Twitter) Community Top Posts Scraper to find public X Community posts with one keyword or phrase, or public Community IDs or URLs. It returns structured rows with post text, community details, author context, engagement counts, media links, and source links, so you can study conversations and compare popular or recent posts.

**Use cases**

- Compare high-engagement posts across public X Communities with **[Twitter Communities Top Posts Scraper](https://apify.com/maximedupre/twitter-communities-top-posts-scraper/examples/twitter-communities-top-posts)**.
- Collect posts from a named public X Community with **[X Community Posts Scraper](https://apify.com/maximedupre/twitter-communities-top-posts-scraper/examples/x-community-posts-scraper)**.
- Search public X Community posts for one topic with **[X Community Posts](https://apify.com/maximedupre/twitter-communities-top-posts-scraper/examples/x-community-posts)**.
- Build a research set from a public X Community with **[X Community Scraper](https://apify.com/maximedupre/twitter-communities-top-posts-scraper/examples/x-community-scraper)**.
- Review recent public Twitter Community discussions with **[Twitter Community Scraper](https://apify.com/maximedupre/twitter-communities-top-posts-scraper/examples/twitter-community-scraper)**.

#### 🧾 See each post with its community context

Each saved row is a public X Community post. It keeps the post ID, URL, text, publish time, source community, author context, engagement counts, media links, language, posting source, conversation references, sensitivity flag, and quoted-post context when the source exposes them.

#### ▶️ Choose how to find the posts

Choose Keyword to search across public X Communities, or Community IDs or URLs to collect from specific public Communities. Choose Top for high-engagement posts or Latest for newest posts first. Page and cursor handling stay inside the Actor. Leave `maxItems` empty to return all available posts until the source is exhausted.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
|---|---|---|
| `discoveryMethod` | string | Chooses `keyword` to search across public X Communities or `community` to use Community IDs or URLs. Only fields for the selected method are used. |
| `keyword` | string | Searches public X Communities with one keyword or phrase. Do not enter a list. |
| `communityIds` | string\[] | Accepts one or more public X Community IDs or canonical Community URLs, one value per line. |
| `ranking` | string | Uses `top` for high-engagement posts or `latest` for newest posts first. |
| `maxItems` | integer | Stops after this many posts. Leave it empty to return all available posts until the source is exhausted. |

**Example input**

This is the public input from the successful beta default-input run:

```json
{
  "discoveryMethod": "keyword",
  "keyword": "AI startups",
  "ranking": "top",
  "maxItems": 4
}
```

#### 🧾 Output

The run exposes `datasetItems` as a string link that opens the collected posts as JSON rows.

Every dataset row uses the community post shape below. Optional fields are left out when the public source does not expose them.

**Community post row**

| Field | Type | What it does |
|---|---|---|
| `postId` | string (required) | Stable ID for the post from X. |
| `postUrl` | string (optional) | Canonical X URL for opening the post. |
| `text` | string (required) | Text published in the post. |
| `publishedAt` | string (required) | Time when the post was published, in ISO 8601 format. |
| `community` | object (required) | Public X Community that contains the post. |
| `community.id` | string (required) | Stable ID for the public X Community. |
| `community.name` | string (optional) | Name of the public X Community. |
| `author` | object (optional) | Author details exposed with the post. |
| `author.id` | string (required when present) | Stable ID for the post author. |
| `author.handle` | string (required when present) | X handle of the post author, without `@`. |
| `author.displayName` | string (required when present) | Display name of the post author. |
| `author.isVerified` | boolean (optional) | Whether X marks the author as verified. |
| `author.followersCount` | integer (optional) | Number of followers shown for the author. |
| `author.profileImageUrl` | string (optional) | URL of the author's profile image. |
| `engagement` | object (optional) | Engagement counts shown for the post. |
| `engagement.likes` | integer (optional) | Number of likes shown for the post. |
| `engagement.reposts` | integer (optional) | Number of reposts shown for the post. |
| `engagement.replies` | integer (optional) | Number of replies shown for the post. |
| `engagement.quotes` | integer (optional) | Number of quote posts shown for the post. |
| `engagement.bookmarks` | integer (optional) | Number of bookmarks shown for the post. |
| `engagement.views` | integer (optional) | Number of views shown for the post. |
| `media` | object\[] (optional) | Photos, videos, or GIFs attached to the post. |
| `media[].type` | string | Type of the attached media: `photo`, `video`, or `animated_gif`. |
| `media[].url` | string | Direct URL for the attached media file. |
| `media[].thumbnailUrl` | string (optional) | URL for a thumbnail of the attached media. |
| `media[].width` | integer (optional) | Width of the media in pixels. |
| `media[].height` | integer (optional) | Height of the media in pixels. |
| `media[].durationSeconds` | number (optional) | Length of the video in seconds, when shown by the source. |
| `media[].variants` | object\[] (optional) | Other source URLs and formats for the media. |
| `media[].variants[].url` | string | Direct URL for a media variant. |
| `media[].variants[].contentType` | string (optional) | Internet media type for the variant. |
| `media[].variants[].bitrate` | integer (optional) | Bitrate of the variant in bits per second. |
| `media[].variants[].width` | integer (optional) | Width of the variant in pixels. |
| `media[].variants[].height` | integer (optional) | Height of the variant in pixels. |
| `language` | string (optional) | Language code shown for the post. |
| `postingSource` | string (optional) | App or service shown as the source of the post. |
| `conversation` | object (optional) | Conversation and reply references shown for the post. |
| `conversation.conversationId` | string | Stable ID for the conversation containing the post. |
| `conversation.inReplyToPostId` | string (optional) | ID of the post this post replies to, when shown by the source. |
| `isSensitive` | boolean (optional) | Whether the source marks the post as sensitive. |
| `quotedPost` | object (optional) | Quoted post details shown by the source. |
| `quotedPost.postId` | string (required when present) | Stable ID for the quoted post. |
| `quotedPost.postUrl` | string (optional) | Canonical X URL for opening the quoted post. |
| `quotedPost.text` | string (optional) | Text shown for the quoted post. |
| `quotedPost.author` | object (optional) | Author details shown for the quoted post. |
| `quotedPost.author.id` | string (required when present) | Stable ID for the quoted post author. |
| `quotedPost.author.handle` | string (required when present) | X handle of the quoted post author, without `@`. |
| `quotedPost.author.displayName` | string (required when present) | Display name of the quoted post author. |
| `quotedPost.author.isVerified` | boolean (optional) | Whether X marks the quoted author as verified. |
| `quotedPost.author.followersCount` | integer (optional) | Number of followers shown for the quoted author. |
| `quotedPost.author.profileImageUrl` | string (optional) | URL of the quoted author's profile image. |
| `quotedPost.engagement` | object (optional) | Engagement counts shown for the quoted post. |
| `quotedPost.engagement.likes` | integer (optional) | Number of likes shown for the quoted post. |
| `quotedPost.engagement.reposts` | integer (optional) | Number of reposts shown for the quoted post. |
| `quotedPost.engagement.replies` | integer (optional) | Number of replies shown for the quoted post. |
| `quotedPost.engagement.quotes` | integer (optional) | Number of quote posts shown for the quoted post. |
| `quotedPost.engagement.bookmarks` | integer (optional) | Number of bookmarks shown for the quoted post. |
| `quotedPost.engagement.views` | integer (optional) | Number of views shown for the quoted post. |

**Example output**

This complete row comes from the successful current-beta default-input run:

```json
{
  "postId": "1980908685468611013",
  "postUrl": "https://x.com/i/status/1980908685468611013",
  "text": "Good morning fam \n\nPrivacy-first AI is finally real. 🔒🤖\n\n@zama Concrete ML lets you train/run ML models directly on encrypted data — the model never sees raw inputs, and servers can’t leak or misuse info. 🧠🔐\n\nBuilt on the same FHE foundation that powers FHEVM. ⚙️ https://t.co/IV1n0mM7kY",
  "publishedAt": "2025-10-22T08:06:48.000Z",
  "community": {
    "id": "1938688998379266124",
    "name": "Zama Community"
  },
  "author": {
    "id": "1886863054987517954",
    "handle": "CryptoDoctor06",
    "displayName": "Doctor",
    "isVerified": false,
    "followersCount": 8889,
    "profileImageUrl": "https://pbs.twimg.com/profile_images/1969689999365885952/4WefRm5Q_normal.jpg"
  },
  "engagement": {
    "likes": 135,
    "reposts": 2,
    "replies": 133,
    "quotes": 0,
    "bookmarks": 5,
    "views": 1778
  },
  "media": [
    {
      "type": "photo",
      "url": "https://pbs.twimg.com/media/G32Z8t2WQAAx9er.jpg",
      "thumbnailUrl": "https://pbs.twimg.com/media/G32Z8t2WQAAx9er.jpg",
      "width": 1024,
      "height": 1024
    }
  ],
  "language": "en",
  "postingSource": "Twitter for Android",
  "conversation": {
    "conversationId": "1980908685468611013"
  },
  "isSensitive": false
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. The primary event applies to each public Community post saved to the dataset. Use `maxItems` to choose how many posts to save, or leave it empty to return all available posts until the source is exhausted. The current price is shown in Apify's Pricing tab.

#### 🔌 Integrations

**Video guide**

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

Use the Apify dataset or API to read the machine-readable post rows in your workflow.

#### ❓ FAQ

##### Can I search a private or members-only Community?

No. The Actor works with public X Communities. Private, restricted, deleted, or unavailable Communities are outside scope.

##### What should I enter for a keyword run?

Enter one keyword or phrase. A run does not support a list of separate keyword searches.

##### When should I use Community IDs or URLs?

Use them when you already know which public Communities to read. Add one value per line, using a Community ID or a canonical public Community URL.

##### What is the difference between Top and Latest?

`top` asks for high-engagement posts. `latest` asks for newest posts first. The public source controls which posts are available.

##### Can I use a canonical Community URL?

Yes. Add a URL such as `https://x.com/i/communities/1844947700867101063` in the Community IDs or URLs field.

##### Does the Actor collect replies?

It returns reply references and counts when the source shows them. It does not collect full reply threads or reply bodies.

##### Does it download media files?

No. It returns media references and available media metadata. It does not download or host media files.

##### Why can a field be missing?

Optional values are left out when the public source does not expose them.

##### Do I need an X login or API key?

No buyer-supplied X login or API credentials are needed.

### 📝 Changelog

**0.0: Initial release**

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~twitter-communities-top-posts-scraper/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Twitter (X) Scraper](https://apify.com/maximedupre/twitter-scraper): Collect broader public X posts, profiles, and trends when you need more than Community posts.
- [Twitter X Media Scraper](https://apify.com/maximedupre/twitter-media-scraper): Get direct image, video, and GIF links from public X posts.
- [Twitter X Community Posts Scraper](https://apify.com/igview-owner/twitter-x-community-posts): Collect posts from a public X Community timeline.
- [X (Twitter) Community Search Post Scraper 𝕏](https://apify.com/api-ninja/x-twitter-community-search-post-scraper): Search public X Communities for posts with community context.
- [X (Twitter) Community Post Search - All Communities](https://apify.com/seemuapps/x-community-post-search-scraper): Search public X Communities by keyword for broader post discovery.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `discoveryMethod` (type: `string`):

Choose Keyword to search across public X Communities, or Community IDs or URLs to collect from specific public Communities.

## `keyword` (type: `string`):

Enter one keyword or phrase to search across public X Communities. Do not enter a list.

## `communityIds` (type: `array`):

Enter one or more public X Community IDs or canonical Community URLs. Use one value per line.

## `ranking` (type: `string`):

Choose Top for high-engagement posts or Latest for newest posts.

## `maxItems` (type: `integer`):

Optional. Stop after this many posts. Leave it empty to return all available posts until the source is exhausted.

## Actor input object example

```json
{
  "discoveryMethod": "keyword",
  "keyword": "AI startups",
  "ranking": "top",
  "maxItems": 4
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Open the collected posts as JSON rows.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "discoveryMethod": "keyword",
    "keyword": "AI startups",
    "ranking": "top",
    "maxItems": 4
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/twitter-communities-top-posts-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "discoveryMethod": "keyword",
    "keyword": "AI startups",
    "ranking": "top",
    "maxItems": 4,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/twitter-communities-top-posts-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "discoveryMethod": "keyword",
  "keyword": "AI startups",
  "ranking": "top",
  "maxItems": 4
}' |
apify call maximedupre/twitter-communities-top-posts-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/twitter-communities-top-posts-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/DEebIhsdvgjKCvznT/builds/VEi35KkV1mlpRs7qp/openapi.json
