X (Twitter) Public Intel - Profiles, Posts, Engagement Velocity
Pricing
from $8.00 / 1,000 profile records
X (Twitter) Public Intel - Profiles, Posts, Engagement Velocity
Profile intel, post records, and engagement-velocity signals from X's public logged-out surfaces. No login, no cookies, no API keys. Built for brand monitoring, competitor watch, and agent pipelines - with watchlist monitor mode. Recent posts per profile (about 20), not a firehose.
Pricing
from $8.00 / 1,000 profile records
Rating
0.0
(0)
Developer
Seibs.co
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
X (Twitter) Public Intel
TL;DR for brand, competitor-watch, and AI-agent teams: A logged-out, public-data intelligence actor for X (Twitter). Give it handles, get back a clean profile snapshot (followers, following, post count, verified, bio, created date), the profile's recent posts as normalized records, and an engagement-velocity signal per profile - average engagement, engagement-per-follower, posting cadence, newest-post velocity, and a momentum flag when a post is taking off. Plus a brand_monitor mode for Apify Schedules that emits new-post and follower-delta digests. No login, no cookies, no API key. Honest cap: roughly the 20 most recent posts per profile that X's public syndication surface exposes - this is an intel tool, not a firehose. The official X API runs pay-per-use up to $42k+/mo enterprise; this reads the same public surface anonymous visitors already see.
Run it in 30 seconds
# Via the Apify Python SDKfrom apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("seibs.co/x-twitter-intel").call(run_input={"mode": "profile_intel","handles": ["nasa", "openai"]})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Or via curl:
curl -X POST "https://api.apify.com/v2/acts/seibs.co~x-twitter-intel/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"mode": "profile_intel", "handles": ["nasa", "openai"]}'
Or click "Try for free" on this page if you prefer the no-code UI.
What you get
Each run produces:
- A clean dataset, filterable in the Apify console and downloadable as CSV or JSON
- Four dataset views:
overview(AI-agent skim),signals(one row per profile),posts(every post field), andprofiles - A sample-output preview at ./.actor/sample-output.json
Three record types:
profile_record- handle, display name, bio, followers, following, post count, verified flags, account-created date, profile URLpost_record- text, author, timestamp, like/retweet/reply/quote counts (where the public surface exposes them), media/link flags, hashtags, mentions, reply/quote/retweet flags, conversation idengagement_velocity_signal- the intel layer, one per profile (see below)
Live example output
Real, unmodified output from runs against live public profiles (no login required to view):
- Profile intel showcase (
profile_intelover a few well-known public handles): aprofile_record+ recentpost_records + oneengagement_velocity_signalper handle, with momentum flags where a recent post is outrunning the account's median pace. - Posts lookup (
posts_lookupover a list of tweet ids / status URLs): onepost_recordeach, resolved from the public per-post surface.
To reproduce: run profile_intel with handles=["nasa","openai"], or posts_lookup with a couple of status URLs. If a profile fetch returns a fetch_error that mentions rate limiting, switch apify_proxy_groups to ["RESIDENTIAL"] (see Responsible use, below).
What does X Public Intel do?
It reads X's public, logged-out syndication surfaces - the same data X serves to anonymous visitors through its embeddable timeline and tweet widgets - and layers an intelligence engine on top.
- For a handle, it fetches the public profile-timeline surface, extracts the profile fields and the ~20 recent posts the surface renders, normalizes each post, and computes one engagement-velocity signal.
- For a tweet id or status URL, it fetches the public per-post surface and normalizes it (with an oEmbed fallback if that surface returns nothing).
- In brand_monitor mode under an Apify Schedule, it compares against a stored baseline and emits only the change - new posts and follower deltas - as a digest.
It does this without logging in, without cookies, and without the paid X API.
Responsible use / data scope
This is the most important section on this actor. Read it.
This actor is a public-data tool, and that is a deliberate design and legal posture, not an afterthought:
- Logged-out, public data only. It reads only X's public, logged-out syndication surfaces - the same data X serves to an anonymous visitor through its embeddable widgets. It does not log in, does not use or accept cookies or session tokens, and does not use the paid X API. Because it never creates an account, it never accepts X's terms of service (the legally relevant distinction: courts have held that terms do not bar logged-off scraping of public data).
- No login, no paywall bypass. There is no credential field, anywhere. Protected (private) accounts are not publicly readable, so they are out of scope. DMs, follower/following lists, and any non-public surface are out of scope.
- Respects the public surface limits. X's public logged-out surface renders roughly the 20 most recent posts per profile, and there is no public "load more" without a login. This actor caps at that and says so plainly. It does not pretend to firehose, and it cannot keyword-search (logged-out search is not publicly exposed - track handles instead).
- PII minimized. Records carry only what X already shows publicly on the logged-out widget: handle, display name, public bio, public follower/following/post counts. We do not enrich into private contact data, and we do not collect anything the public widget does not already render.
- Proportionate-visitor behavior. Real-browser TLS fingerprint, low concurrency (default 2), jittered delays, and backoff - so the actor behaves like a normal visitor, both as a courtesy and as a legal mitigation.
- You are responsible for lawful use of the outputs. Public does not mean unregulated: GDPR (EU) and CCPA (CA) apply to personal data even when it is public. Use the outputs lawfully for your jurisdiction and purpose.
- Not affiliated. This actor is not affiliated with, endorsed by, or sponsored by X Corp. "X" and "Twitter" are trademarks of their owner and are used here only to describe what the actor reads.
AI / RAG / Agent
A turn-key social-intel feed for AI agents, brand-monitoring copilots, and research bots. Records arrive pre-normalized - engagement_velocity_signal exposes avg_engagement, engagement_per_follower_permille, posts_per_week, and momentum_flag so an agent can ask "which of my competitors posted something that is taking off right now?" without parsing raw HTML. The overview dataset view is a narrow, token-efficient slice; an MCP-compatible link returns the first 50 records as a clean JSON array. Compatible with LangChain, LlamaIndex, Pinecone, Weaviate, Chroma, and any MCP-aware agent runtime (see the sibling mcp-x-twitter-intel actor for direct tool-call wiring with agentic payments).
Features
- Profile intel - one clean snapshot per handle: followers, following, post count, verified flags, bio, account-created date, profile URL.
- Recent-post records - up to ~20 recent posts per profile, normalized: text, timestamp, full per-post engagement counts (likes, retweets, replies, quotes), media/link flags, hashtags, mentions, reply/quote/retweet flags, conversation id.
- Engagement-velocity engine - the intel layer: average engagement, engagement-per-follower (per 1,000), posts-per-week cadence, hours since the last post, newest-post likes-per-hour, and a
momentum_flagwhen the newest post outruns the profile's median pace by 2x. - Posts lookup - resolve a list of tweet ids or status URLs to post records, with an oEmbed fallback for posts the primary surface cannot return.
- Brand monitor + Schedules - run a watchlist on a cron; monitor mode emits only the delta (new posts + follower changes) with an optional Slack digest.
- Block-aware - if X rate-limits a datacenter IP, the actor backs off, rotates its session, and (if still blocked) emits a
fetch_errorthat tells you to switch to residential proxies - never a crashed run. - Cost-control - per-run budget guard + demo-mode soft-fail so runs finish SUCCEEDED.
Use cases
- Brand monitoring - track your own accounts' follower trajectory, posting cadence, and which posts are taking off (momentum flag).
- Competitor watch - the same metrics across a list of competitor handles; compare engagement-per-follower, not just raw follower counts.
- Campaign / launch tracking - point posts_lookup at a set of campaign status URLs and pull engagement into your own dashboard.
- AI agent grounding - a clean, pre-normalized profile + post feed an agent can reason over via the MCP-friendly views.
- Alt-data / research - account growth and engagement signals over time via scheduled monitor runs.
Modes
| Mode | What it returns |
|---|---|
profile_intel | Per handle: a profile_record, a post_record per recent post (up to ~20), and one engagement_velocity_signal. |
posts_lookup | Per tweet id / status URL: one post_record. Partial metrics on this surface (likes + replies; retweet/quote counts are not exposed per-post). |
brand_monitor | profile_intel over a watchlist, built for Apify Schedules. Under a schedule it emits the new-posts + follower-delta digest. |
Input
See ./.actor/input_schema.json for the full form. Key fields:
{"mode": "profile_intel","handles": ["nasa", "openai"],"max_posts_per_profile": 20,"include_replies": false,"use_apify_proxy": true,"apify_proxy_groups": ["DATACENTER"]}
For posts_lookup:
{"mode": "posts_lookup","post_inputs": ["20", "https://x.com/nasa/status/1234567890123456789"]}
No API key or login is required - these are public syndication surfaces. Handles work with or without a leading @.
Output
One engagement_velocity_signal per profile (the headline), then one profile_record and the post_records for each handle.
{"record_type": "engagement_velocity_signal","handle": "skylinebrew","followers_count": 48230,"posts_analyzed": 20,"avg_engagement": 380.0,"engagement_per_follower_permille": 7.8789,"posts_per_week": 11.29,"hours_since_last_post": 5.2,"newest_post_likes_per_hour": 173.08,"momentum_ratio": 2.41,"momentum_flag": true,"follower_delta": 412,"new_post_count": 3}
{"record_type": "post_record","tweet_id": "1799001234567890123","author_handle": "skylinebrew","text": "New drop: Ethiopia Guji, washed. Blueberry, jasmine, a long syrupy finish.","created_at": "2026-06-12T08:51:00.000Z","like_count": 900,"retweet_count": 118,"reply_count": 82,"quote_count": 24,"is_reply": false,"has_media": true,"hashtags": ["coffee", "singleorigin"],"status_url": "https://x.com/skylinebrew/status/1799001234567890123","metrics_source": "profile_timeline"}
Failed fetches still emit a fetch_error record with a reason (and, on a block, guidance to switch to residential proxies) for a complete audit.
Pricing
Pay-per-event:
| Event | Price | When charged |
|---|---|---|
profile_record | $0.008 | Per public profile snapshot returned. |
post_record | $0.003 | Per post returned (profile_intel posts, posts_lookup results). |
engagement_velocity_signal | $0.010 | Once per profile - the intel-layer rollup. |
scheduled_delta_run | $0.050 | Once per scheduled brand_monitor run (the delta digest). |
A run that returns nothing costs nothing. A typical 2-handle profile_intel run (profile + ~20 posts + 1 signal each) costs roughly $0.14 - $0.16 total.
FAQ
Q: Why only ~20 posts per profile? A: That is roughly the most X's public, logged-out syndication surface renders. There is no public "load more" without a login, and this actor stays logged-out by design (that is the whole legal posture - see Responsible use). So it caps at the public surface and tells you so, rather than pretending to firehose. If you need deep historical volume, that requires the paid X API or a logged-in scraper - neither of which this actor is.
Q: Can it search by keyword or hashtag? A: No. Logged-out keyword/hashtag search is not exposed on the public surface, so this actor does not offer it. Track specific handles instead (your accounts, competitors, campaign authors) - that is what the public surface supports, and it is the higher-signal approach for brand and competitor monitoring anyway.
Q: Will it get blocked?
A: X rate-limits bare datacenter IPs on the profile-timeline surface aggressively - you may see fetch_error records that say "rate-limited / blocked". The actor handles this: it backs off, rotates its session, and surfaces a clear reason rather than crashing. The fix is to set apify_proxy_groups to ["RESIDENTIAL"] and keep concurrency at 1-2. The per-post (tweet id) surface is much more tolerant and usually works on datacenter proxies. Behaving like a normal visitor - residential IP, real browser fingerprint, low rate - is both the technical fix and the legal posture.
Q: Why not just use the official X API? A: Cost. X's official API has no real free tier, runs pay-per-use, and tops out at $42,000-$50,000+/month for enterprise volume. Anyone who needs more than a trickle is priced out. This actor reads the same public surface an anonymous visitor already sees, for Apify pay-per-event cents - no API token, no subscription.
Q: Does it work for private accounts? A: No. Protected (private) accounts are not publicly readable, so they are out of scope. The actor only reads what X serves to a logged-out visitor.
Q: Some posts_lookup records are missing retweet/quote counts. Why?
A: The public per-post surface (used by posts_lookup) exposes like_count and reply_count but not separate retweet/quote counts. Those fields come through fully via the profile-timeline surface, so use profile_intel when you need complete per-post metrics. Each record carries a metrics_source and a metrics_note so you always know what you are looking at.
Save your input as an Apify Task
Apify Tasks let you save a configured input once and re-run it with one click - the foundation for schedules, brand_monitor mode, and the follower/post baseline (the baseline is most useful when the same handle list runs on a cadence).
- Click
Runwith your input configured. - Click
Save as task. - Name it (e.g.
competitor-watch - daily). - Reload the task page and click
Startanytime.
Run this daily with Apify Schedules
- Save your input as a Task (above), with
modeset tobrand_monitor. - Go to https://console.apify.com/schedules and
Create new schedule. - Pick your Task and set a cron expression (daily 9am:
0 9 * * *). - Save. Each run refreshes the baseline and surfaces the day's new posts and follower changes.
Monitor mode (beta)
When this actor runs under an Apify Schedule in brand_monitor mode, monitor mode emits only the change-delta (new posts + follower deltas across the watchlist) with a digest record at the top, instead of re-emitting everything. Provide monitor_webhook_url and the digest also fires to your Slack channel. Cost: one scheduled_delta_run event ($0.05) per scheduled run plus standard PPE on the records emitted.
Related Actors
- hiring-signal-intel - live job-postings intent signals from public ATS feeds; pair social momentum with hiring momentum.
- reddit-topic-watcher - watch Reddit topics for the same brand/competitor monitoring, on a different platform.
- google-maps-reviews-pro - public review intelligence to round out a brand-monitoring stack.
Support
Open an issue via the Apify Store contact link. Include the run ID and input config so the issue is reproducible.
Changelog
See ./CHANGELOG.md.
Found this useful?
If this actor saved you time or money, please leave a quick review on the Apify Store. Reviews help other buyers find work that solves their problem: https://apify.com/seibs.co/x-twitter-intel#reviews