# X/Twitter Keyword & Hashtag Tweet Search (`nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search`) Actor

Search X (Twitter) by keyword, phrase or hashtag and get tweet text, author, engagement metrics, media and language. Every row says which keyword found it. No login required.

- **URL**: https://apify.com/nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Social media, Automation, Lead generation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## X/Twitter Keyword & Hashtag Tweet Search

Give this actor a list of keywords, phrases or hashtags and it pulls back matching X (formerly Twitter) posts — full text, engagement counts, media and the author who wrote each one. No sign-in, cookies or developer credentials needed; it reads the same public search results any visitor sees.

### What this actor does

- Runs each entry in `keywords` as its own independent search, so a single job can cover several unrelated topics at once.
- Targets up to 1,000 posts per keyword via `maxTweets`; how many actually come back depends on how much volume that keyword has on X.
- Lets you sort by `Top` (most engagement) or `Latest` (newest first), and narrow by language, a date window, retweets/replies, verification, media presence, and minimum like/retweet/reply counts.
- Stamps every row with `searchTerm` so a multi-keyword run stays easy to split apart afterward.
- Emits a one-line `status` record for a keyword that returns nothing, rather than leaving you guessing why a keyword is missing from the dataset.
- Drops any field with no data for that post — you will never see `null`, an empty string, or an empty array/object in the output.

### Output per post

Core fields on every post record: `id`, `url`, `text`, `createdAt`, `language` (when X reports one), and `searchTerm`.

Engagement comes through `replyCount`, `retweetCount`, `likeCount`, `quoteCount`, `bookmarkCount`, and `viewCount`, plus a computed `engagementRate` — `(likes + retweets + replies + quotes) ÷ followers` — included only once the author's follower count is known and nonzero.

Post-type context: `isReply`, `isRetweet`, `isQuote`, `isNoteTweet`, and, for replies, `conversationId`, `inReplyToTweetId`, `inReplyToUserId`, `inReplyToUsername`, `parentTweet` (a nested summary of the post being replied to, when available).

Entities parsed out of the text: `hashtags`, `mentions`, `urls`, `cashtags`.

Attachments and extras, when present: `media` (one entry per photo/video/GIF with `type`, `url`, `previewImageUrl`, pixel dimensions, `durationSeconds`, `viewCount`, `altText`, `variants`), `quotedTweet` / `quotedTweetId`, `poll`, `card`, `possiblySensitive`, `withheldInCountries`, `place`, `postedFrom`, `isEdited`, `editControl` (edit history metadata), `newsActionType`.

The author rides along as a nested `author` object — `id`, `username`, `name`, `bio`, `followers`, `isBlueVerified`, `verified`, `profileImageUrl`, and more.

Every post closes with `type: "post"` and `collectedAt`.

#### Sample record

```json
{
  "type": "post",
  "id": "1923456789012345678",
  "url": "https://x.com/i/status/1923456789012345678",
  "text": "Just shipped a new feature after three weeks of testing. Feels good. #buildinpublic",
  "createdAt": "2026-06-02T09:15:00+00:00",
  "language": "en",
  "searchTerm": "buildinpublic",
  "replyCount": 34,
  "retweetCount": 112,
  "likeCount": 1870,
  "quoteCount": 9,
  "bookmarkCount": 265,
  "viewCount": 54300,
  "isReply": false,
  "isRetweet": false,
  "isQuote": false,
  "hashtags": ["buildinpublic"],
  "author": {
    "id": "1092834756",
    "username": "makerjane",
    "name": "Jane Builds",
    "followers": 18400,
    "isBlueVerified": false
  },
  "collectedAt": "2026-06-02T10:03:41+00:00"
}
```

### Output per status row

When a keyword comes back empty, the actor pushes exactly one record carrying `type: "status"`, `status`, `message`, `searchTerm` (which keyword it's reporting on), and `collectedAt` — a signal, not a silent zero.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `keywords` | array | – | **Required.** Words, phrases, hashtags or full search queries; each runs separately. |
| `maxTweets` | integer | `20` | Target number of posts per keyword (1–1000). |
| `maxItems` | integer | – | Same as `maxTweets` — use whichever name you prefer. |
| `searchType` | string | `Top` | `Top` for the most engaged posts, `Latest` for newest-first. |
| `sort` | string | – | Same as `searchType`. |
| `language` | string | `Any language` | Restrict to one of 40 common X language codes, e.g. `en`, `es`, `ja`. |
| `dateFrom` | date | – | Earliest post date to include. |
| `dateTo` | date | – | Latest post date to include. |
| `excludeRetweets` | boolean | `false` | Drop retweets/reposts, keep only original posts. |
| `excludeReplies` | boolean | `false` | Drop replies, keep only top-level posts. |
| `onlyVerifiedUsers` | boolean | `false` | Keep only posts from verified accounts. |
| `onlyImages` | boolean | `false` | Keep only posts containing at least one image. |
| `onlyVideos` | boolean | `false` | Keep only posts containing at least one video or GIF. |
| `minimumLikes` | integer | – | Floor on like count. |
| `minimumRetweets` | integer | – | Floor on retweet count. |
| `minimumReplies` | integer | – | Floor on reply count. |
| `proxyConfiguration` | object | – | Optional; useful for large or repeated runs from the same IP. |
| `startDate` / `endDate` | string | – | Older aliases for `dateFrom` / `dateTo` (`YYYY-MM-DD`). |

#### Example: two unrelated topics in one run

```json
{
  "keywords": ["apify", "web scraping"],
  "maxTweets": 50
}
```

#### Example: live brand-mention watch

```json
{
  "keywords": ["#YourBrand", "\"your brand\""],
  "searchType": "Latest",
  "language": "en",
  "maxTweets": 200,
  "excludeRetweets": true,
  "excludeReplies": true
}
```

#### Example: top posts in a date window, above an engagement floor

```json
{
  "keywords": ["artificial intelligence"],
  "maxTweets": 500,
  "minimumLikes": 100,
  "minimumRetweets": 20,
  "dateFrom": "2026-01-01",
  "dateTo": "2026-06-30"
}
```

### Use cases

- **Brand monitoring** — catch new mentions of a product, campaign or handle as they post.
- **Trend and topic tracking** — measure how a subject's volume and engagement shift over weeks or months.
- **Breaking-news watch** — pair `Latest` with a tight date range to follow a fast-moving story.
- **Content research** — surface the highest-engagement posts around a theme for inspiration.
- **Academic or policy research** — assemble a dataset of public discourse on a topic, language or time period.
- **Competitor comparison** — run several competing keywords side by side and compare volume and engagement.

### FAQ

**Do I need an X account or developer credentials?**
No — there's no credential field in the input at all. The actor reads what any logged-out visitor can already see on X's own search.

**How many posts will I actually get per keyword?**
Up to `maxTweets`, but that's a ceiling, not a promise. A trending keyword might fill close to 500 rows; an obscure one may return only a handful, because that's genuinely all X's search surface has for it.

**Why did I get a different count on a second identical run?**
X's logged-out search doesn't expose stable, full pagination, and what it surfaces can shift between requests. If you need more rows, try again or narrow the date window rather than assuming something broke.

**Should I use `Top` or `Latest`?**
`Latest` for anything time-sensitive — breaking news, live mentions, a campaign in progress. `Top` when you want the posts with the strongest engagement regardless of when they went up.

**Is a proxy required?**
No, it's optional. Add one mainly if you're running large or frequent jobs from the same IP and want extra headroom against rate limiting.

**How current is the data?**
Fully live — each run queries X at the moment it executes. Put the actor on a schedule for ongoing monitoring.

**How do I get the results into another tool?**
Pull the dataset from the run page or the Apify API, wire up a webhook, or connect it to Zapier, Make, Google Sheets, or similar no-code tools.

**Is this affiliated with X?**
No. This is an independent, third-party actor that reads publicly available X search results.

# Actor input Schema

## `keywords` (type: `array`):

Words, phrases, hashtags or full X search queries to monitor. Each keyword is searched separately, and every result row tells you which keyword found it (searchTerm).

## `maxTweets` (type: `integer`):

Stop after this many tweets for each keyword.

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

Alias of Maximum tweets per keyword. The actor accepts either name.

## `searchType` (type: `string`):

Top returns the most relevant and popular tweets. Latest returns the newest tweets first — best for real-time monitoring.

## `sort` (type: `string`):

Alias of Result order. The actor accepts either name.

## `language` (type: `string`):

Only return tweets written in this language. Leave the default to search all languages.

## `dateFrom` (type: `string`):

Only return tweets posted on or after this date. Leave empty for no lower bound.

## `dateTo` (type: `string`):

Only return tweets posted on or before this date. Leave empty for no upper bound.

## `excludeRetweets` (type: `boolean`):

Skip retweets/reposts and keep only original posts.

## `excludeReplies` (type: `boolean`):

Skip replies and keep only top-level posts.

## `onlyVerifiedUsers` (type: `boolean`):

Only return tweets from verified (blue check) accounts.

## `onlyImages` (type: `boolean`):

Only return tweets that contain at least one image.

## `onlyVideos` (type: `boolean`):

Only return tweets that contain at least one video or GIF.

## `minimumLikes` (type: `integer`):

Only return tweets with at least this many likes. Leave empty for no minimum.

## `minimumRetweets` (type: `integer`):

Only return tweets with at least this many retweets. Leave empty for no minimum.

## `minimumReplies` (type: `integer`):

Only return tweets with at least this many replies. Leave empty for no minimum.

## `proxyConfiguration` (type: `object`):

Optional. Use a proxy if you run large jobs or see frequent IP-based rate limits.

## `startDate` (type: `string`):

Deprecated — use 'Start date' instead. Kept so existing saved inputs keep working. Format: YYYY-MM-DD.

## `endDate` (type: `string`):

Deprecated — use 'End date' instead. Kept so existing saved inputs keep working. Format: YYYY-MM-DD.

## Actor input object example

```json
{
  "keywords": [
    "web scraping",
    "data mining",
    "#AI"
  ],
  "maxTweets": 20,
  "searchType": "Top",
  "language": "Any language",
  "excludeRetweets": false,
  "excludeReplies": false,
  "onlyVerifiedUsers": false,
  "onlyImages": false,
  "onlyVideos": false
}
```

# Actor output Schema

## `tweets` (type: `string`):

Dataset containing one row per tweet plus status rows when a run needs attention.

# 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 = {
    "keywords": [
        "apify"
    ],
    "maxTweets": 20,
    "searchType": "Top",
    "language": "Any language",
    "excludeRetweets": false,
    "excludeReplies": false,
    "onlyVerifiedUsers": false,
    "onlyImages": false,
    "onlyVideos": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search").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 = {
    "keywords": ["apify"],
    "maxTweets": 20,
    "searchType": "Top",
    "language": "Any language",
    "excludeRetweets": False,
    "excludeReplies": False,
    "onlyVerifiedUsers": False,
    "onlyImages": False,
    "onlyVideos": False,
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search").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 '{
  "keywords": [
    "apify"
  ],
  "maxTweets": 20,
  "searchType": "Top",
  "language": "Any language",
  "excludeRetweets": false,
  "excludeReplies": false,
  "onlyVerifiedUsers": false,
  "onlyImages": false,
  "onlyVideos": false
}' |
apify call nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/x-twitter-keyword-and-hashtag-tweet-search"
        }
    }
}
```

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/XJyPDggYTy5zS42Q1/builds/JUGXgeVuZX6MAfJ01/openapi.json
