Truth Social Scraper
Pricing
from $1.00 / 1,000 dataset items
Truth Social Scraper
Scrape Truth Social posts, profiles, replies and group timelines as clean JSON. Track any account or group, get engagement metrics, media and playable video URLs, and run incrementally for duplicate-free monitoring. No login required. Pay only for results.
Pricing
from $1.00 / 1,000 dataset items
Rating
0.0
(0)
Developer
axly
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Extract public data from Truth Social — posts ("truths"), account profiles, replies, media and group timelines — as clean, structured JSON.
This scraper talks directly to Truth Social's own JSON API instead of driving a browser. That makes it fast, cheap and stable, and it means you get the complete record for every post: full text, engagement counts, media attachments, group context and the author's live follower numbers.
No Truth Social account, API key or login required.
Who it's for
| You are | You get |
|---|---|
| Journalist / newsroom | A timestamped archive of what public figures posted, with engagement at the moment of capture |
| Political researcher / academic | A clean, labelled post corpus ready for NLP, sentiment and discourse analysis |
| Market / finance analyst | Low-latency incremental polling of the accounts that move markets |
| Brand, OSINT & social analyst | Community-level visibility through Groups — a surface no other Truth Social scraper covers |
| Developer | A dependable JSON feed with pagination, retries and rate-limit handling already solved |
What makes it different
- Groups. Scrape
truthsocial.com/group/<slug>— the group record and its full public timeline. No other Truth Social scraper on the Store does this. - Playable video URLs. Turn on
resolveVideoUrlsand posts with Rumble-hosted video come back with direct MP4 renditions and thumbnails, not just an embed ID. - Pinned posts. Optionally capture the posts an account pinned to the top of its profile.
- Everything in one run. Mix profile URLs, usernames, group slugs and individual post URLs in a single run — there is no per-run account limit.
- Incremental monitoring. Truth Social post IDs are monotonic, so incremental mode returns exactly the posts published since your last run. No duplicates, no wasted rows.
- Partial-failure tolerance. A dead handle or a deleted group never kills the run; the remaining sources still finish and the run reports what failed.
Output fields
Every row carries recordType, which is post, profile or group.
Post rows
| Field | Description |
|---|---|
postId | Numeric post ID (monotonic — useful for ordering and deltas) |
postUrl | Direct link to the post |
content | Post text with HTML stripped, ready for analysis |
contentHtml | Original markup, always preserved |
createdAt / editedAt | Publication and last-edit timestamps (ISO 8601, UTC) |
language, visibility, sensitive, spoilerText | Post metadata |
repliesCount, reTruthsCount, favouritesCount | Engagement at capture time |
upvotesCount, downvotesCount | Vote counts where the platform uses them |
isReply, inReplyToId, inReplyToAccountId | Conversation context |
isReTruth, reTruthOfId, reTruthOfUrl, quoteId | Re-share and quote context |
isPinned, isSponsored | Post flags |
media[], mediaUrls[], hasMedia | Attachments with type, dimensions, duration and preview URLs |
videoRenditions[] | Playable Rumble MP4 renditions and thumbnails (when resolveVideoUrls is on) |
tags[], mentions[] | Hashtags and mentioned handles |
poll, card, cardUrl, cardTitle | Poll object and link-preview card |
groupId, groupSlug, groupName | Group the post was published in, if any |
authorId, authorUsername, authorDisplayName, authorUrl, authorAvatar | Author identity |
authorVerified, authorFollowersCount, authorFollowingCount, authorStatusesCount | Author profile stats at capture time |
sourceType, sourceKey, scrapedAt | Provenance of the row |
raw | The complete untouched API object (when includeRaw is on) |
Profile rows
userId, username, acct, displayName, bio, bioHtml, profileUrl, avatar, header, website, location, followersCount, followingCount, statusesCount, createdAt, lastStatusAt, verified, isBot, isGroup, isLocked, acceptingMessages, fields[]
Group rows
groupId, slug, displayName, note, noteHtml, groupUrl, avatar, header, membersCount, visibility, membershipRequired, discoverable, isLocked, createdAt, tags[], ownerId, ownerUsername
Use cases
Archive a public figure's statements. Point the scraper at one or more handles, set maxItems to the depth you need, and you get a complete, timestamped record with engagement — the raw material for fact-checking, timelines and reporting.
Detect market-moving posts fast. Schedule an incremental run every few minutes on the handles you care about. Each run returns only what is new, so the cost of monitoring stays proportional to actual activity rather than to how often you poll.
Build an NLP dataset. cleanContent gives you plain text with entities decoded and markup removed, alongside language codes, hashtags, mentions and engagement — everything a supervised model or topic study needs, with no HTML cleanup step.
Map a community through Groups. Pull a group's record and timeline to see who posts there, how often and with what reach. Combine several groups to profile a movement rather than a single account.
Collect media at scale. Set onlyMedia to capture just the visual posts, and resolveVideoUrls to get direct MP4 links for archiving or downstream video analysis.
Track engagement over time. Re-scrape the same posts on a schedule and diff favouritesCount, reTruthsCount and repliesCount to measure how reach accumulates after publication.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
startUrls | array | [] | Any mix of profile, post and group URLs |
usernames | array | [] | Handles, with or without @ |
groupSlugs | array | [] | Group slugs, e.g. patriots, crypto |
postIds | array | [] | Numeric post IDs or post URLs |
resultsType | enum | posts | posts, replies, postsAndReplies or profile |
maxItems | integer | 100 | Row cap for the whole run; 0 means unlimited |
maxPostsPerSource | integer | 0 | Per-account/group cap so one busy profile cannot use the whole budget |
postsNewerThan | string | "" | ISO date/date-time; stops paginating past it |
onlyMedia | boolean | false | Only posts with attachments |
includePinned | boolean | false | Also fetch pinned posts |
resolveVideoUrls | boolean | false | Resolve Rumble MP4 renditions (one extra request per video) |
incrementalMode | boolean | false | Return only posts published since the previous run |
stateKey | string | "" | Name the monitoring campaign; auto-derived when empty |
cleanContent | boolean | true | Strip HTML from content (contentHtml is always kept) |
includeRaw | boolean | false | Attach the full untouched API object as raw |
proxyConfiguration | object | Apify residential, US | Recommended for runs of more than a few hundred rows |
Example input
{"usernames": ["realDonaldTrump"],"groupSlugs": ["patriots"],"resultsType": "posts","maxItems": 30,"maxPostsPerSource": 10,"cleanContent": true,"proxyConfiguration": {"useApifyProxy": true,"apifyProxyGroups": ["RESIDENTIAL"],"apifyProxyCountry": "US"}}
Example output
{"recordType": "post","postId": "117257273512193853","postUrl": "https://truthsocial.com/@realDonaldTrump/117257273512193853","content": "Such a great golfer. Too bad I have very little time to play!!!","contentHtml": "<p>Such a great golfer. Too bad I have very little time to play!!!</p>","createdAt": "2026-09-12T09:06:42.567Z","language": "en","visibility": "public","isReply": false,"isReTruth": false,"repliesCount": 3557,"reTruthsCount": 3098,"favouritesCount": 16861,"hasMedia": true,"mediaUrls": ["https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/media_attachments/..."],"tags": [],"mentions": [],"groupSlug": null,"authorId": "107780257626128497","authorUsername": "realDonaldTrump","authorDisplayName": "Donald J. Trump","authorFollowersCount": 13049236,"sourceType": "profile","sourceKey": "realDonaldTrump","scrapedAt": "2026-09-13T10:22:05Z"}
A group row looks like this:
{"recordType": "group","groupId": "110231299744521512","slug": "patriots","displayName": "patriots","note": "All things patriotism","groupUrl": "https://truthsocial.com/group/patriots","membersCount": 20,"visibility": "everyone","membershipRequired": true,"createdAt": "2023-04-20T00:00:00.000Z"}
Scheduling and webhooks
Use the Apify scheduler to run the actor on a cron expression — 0 * * * * for hourly monitoring, 0 6 * * * for a daily digest. Pair it with incrementalMode: true and a fixed stateKey so each run returns only new posts.
Add a webhook on ACTOR.RUN.SUCCEEDED to push fresh rows straight into Slack, a Google Sheet, Airtable, a database or your own endpoint the moment a run finishes. Combine both and you have a live Truth Social feed with no polling code of your own.
Use with AI agents (MCP)
This actor works as a tool for any AI assistant that supports the Model Context Protocol.
{"mcpServers": {"apify": {"type": "http","url": "https://mcp.apify.com/?tools=axlymxp/truth-social-scraper"}}}
Then ask your assistant things like:
- "Get the last 50 posts from realDonaldTrump on Truth Social and summarize the main themes."
- "Scrape the Truth Social group
cryptoand list the most-engaged posts this week." - "Which of these Truth Social accounts posted the most in the last 24 hours?"
API usage
from apify_client import ApifyClientclient = ApifyClient("<YOUR_API_TOKEN>")run = client.actor("axlymxp/truth-social-scraper").call(run_input={"usernames": ["realDonaldTrump"],"resultsType": "posts","maxItems": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["createdAt"], item["content"][:80])
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });const run = await client.actor('axlymxp/truth-social-scraper').call({groupSlugs: ['patriots'],maxItems: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`${items.length} rows`);
FAQ
Do I need a Truth Social account? No. Everything this actor returns is visible to a logged-out visitor.
Can it scrape comments and replies under someone else's post?
No. Truth Social requires a logged-in account to read a post's reply thread — that is a platform restriction, not a limitation of the scraper. You can scrape an account's own replies with resultsType: "replies", and you get repliesCount on every post.
Can it search Truth Social or scrape hashtags and trends? No. Search, trending and hashtag timelines are gated behind a login by Truth Social itself. This actor deliberately only covers what is genuinely public.
How many posts can I get from one account?
There is no fixed ceiling — pagination follows the platform's own cursor until the timeline ends. Use maxItems and maxPostsPerSource to control volume and cost.
Why did I get fewer rows than maxItems?
The account or group has fewer public posts than you asked for, a filter such as onlyMedia or postsNewerThan excluded the rest, or an incremental run found nothing new. All three are logged.
Do I need a proxy? For small runs, no. Truth Social throttles a single IP after roughly a hundred rapid requests, so for anything beyond a few hundred rows use the default Apify residential US proxy — the actor rotates the exit IP automatically when it is throttled.
How fresh is the data?
It is fetched live at run time. Engagement counts are a snapshot of the moment the post was captured, which is why every row carries scrapedAt.
How do I avoid duplicates when monitoring?
Set incrementalMode: true and keep stateKey stable. The actor remembers the newest post ID per source and returns only what came after it.
Is scraping Truth Social legal? This actor only reads content that is publicly visible without a login, which is broadly treated the same as other public social media content. Public posts can still contain personal data, so use the results lawfully and in line with GDPR and any other rules that apply to you. See Apify's guide to web scraping legality.