Vexaloom Labs

Use X Keyword Search with Mention & Reply Operators with Python

Search X (Twitter) by keyword with filters for date, language, engagement, media, verification, mentioned handle, author, reply target, and conversation thread, plus Top/Latest sort.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "excludeReplies": false,
  "excludeRetweets": false,
  "keywords": [
    "apify"
  ],
  "language": "Any language",
  "maxItems": 3,
  "mode": "search",
  "onlyImages": false,
  "onlyQuotes": false,
  "onlyVerifiedUsers": false,
  "onlyVideos": false,
  "sort": "Latest"
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
modestringrequiredSearch by keyword, collect an author's posts, fetch specific post URLs, or open a conversation thread.
keywordsarrayoptionalWords, phrases or hashtags to search for. Each keyword is collected separately and every row shows the keyword that found it (searchTerm).
authorHandlesarrayoptionalUsed by the 'Posts by author' mode. Accepts @handle, handle, or https://x.com/handle profile URLs.
postUrlsarrayoptionalUsed by the 'Specific post URLs' mode. Accepts x.com or twitter.com post links and bare post IDs.
conversationIdstringoptionalUsed by the 'Conversation thread' mode. Paste the root post ID or a post URL in that thread.
maxItemsintegeroptionalStop after this many posts per keyword or author. The URL and conversation modes use it as a total cap.
sortstringoptionalLatest is newest first. Top is ordered by likes and reposts. Top + Latest returns the top half by engagement, then the newest remaining posts.
languagestringoptionalOnly keep posts in this language. The default searches every language.
dateFromstringoptionalOnly keep posts published on or after this date (UTC).
dateTostringoptionalOnly keep posts published on or before this date (UTC).
excludeRetweetsbooleanoptionalDrop reposts and keep original posts only.
excludeRepliesbooleanoptionalDrop replies and keep top-level posts only.
onlyVerifiedUsersbooleanoptionalKeep posts from verified or blue-check accounts only.
onlyImagesbooleanoptionalKeep posts that contain at least one photo.
onlyVideosbooleanoptionalKeep posts that contain at least one video or GIF.
onlyQuotesbooleanoptionalKeep posts that quote another post.
minimumLikesintegeroptionalDrop posts below this like count. Posts whose count is unavailable are dropped and reported in the run summary.
minimumRetweetsintegeroptionalDrop posts below this repost count. Counts are filled from the public fallback source when available.
minimumRepliesintegeroptionalDrop posts below this reply count. Posts with no available reply count are dropped and reported.
mentioningstringoptionalOnly keep posts that mention this handle (with or without @). Applied after collection.
authorstringoptionalOnly keep posts written by this handle (with or without @).
inReplyTostringoptionalOnly keep posts that are replies to this handle (with or without @).
proxyConfigurationobjectoptionalOptional. No proxy is needed. If supplied, it is used for the best-effort guest search supplement as well as page requests.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/xgRc7Nc7IkbNcF3bC/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

X posts with full text, author profile, engagement counters, media, quoted post and reply context. Empty runs write a RUN_SUMMARY to the key-value store instead of a status row.

Questions before you run

Which inputs are required?

The published required fields are mode

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build I7cduHm9oKbw9FGRa and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.