Truth Social Scraper | Profiles, Posts & Search
Pricing
from $2.00 / 1,000 dataset items
Truth Social Scraper | Profiles, Posts & Search
Scrape public Truth Social profiles, posts, media, metrics, author data, and complete source objects using profile URLs, post URLs, or search queries.
Pricing
from $2.00 / 1,000 dataset items
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
6
Total users
2
Monthly active users
5 days ago
Last modified
Categories
Share
Truth Social Scraper: Posts, Profiles, Engagement Metrics & Media
Truth Social Scraper turns Truth Social into structured data. Point it at public profile or post URLs and get normalized posts, replies, profile metadata, media and engagement metrics, plus the complete source objects so no public field is lost. Resume an interrupted pull without being billed twice for posts you already collected, or schedule it and get only what's new, changed or gone since the last run. Export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two URL types, one field. Add public profile URLs or individual post URLs to the same list; the actor works out which is which automatically.
- Profile content controls. Pull profile metadata only, posts only, replies only, or both, per run.
- Rich, normalized output. Convenience fields for content, engagement (likes, ReTruths, replies, quotes, upvotes and downvotes) and author metadata, plus the complete source account/status object so nothing nested is dropped.
- Resume without re-paying. Point a new run at a previous run or dataset ID and it skips every post already saved there, stopping its pagination as soon as it catches up to that content.
- Built for scheduled monitoring. Incremental mode classifies every post as NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED against a remembered baseline, so a recurring run reports only what changed.
- Fails loudly, not silently. A run where every request is refused stops with a clear error instead of billing you for a "no data" result; a genuinely empty match still succeeds and pushes nothing.
- Send results onward. Optional MCP connectors push a summary of each record into Notion, Linear, Airtable or Apify as soon as the scrape finishes.
Use Cases
- Political and public-figure monitoring: track a public account's posts, edits and removed content over time.
- Media and journalism: pull post content, media and engagement metrics for reporting and fact-checking.
- Brand and reputation monitoring: watch a brand or organization's Truth Social activity on a schedule.
- Academic and social research: build datasets of public posts, engagement patterns and account metadata.
- Content archiving: keep a running record of a profile's posts, including ones later edited or removed.
- Competitive and market research: monitor announcements from organizations or public figures as they post.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
recordType | "post" (also "reply", or "profile" for profile records) |
postId | "113456789012345678" (the reposted source id for a repost, else the status id) |
id | "113456789012345678" (the status's own id; differs from postId for a repost) |
postUrl | "https://truthsocial.com/@exampleuser/113456789012345678" |
content | "Sample post text goes here." |
contentHtml | "<p>Sample post text goes here.</p>" |
createdAt | "2026-08-01T12:00:00.000Z" |
editedAt | null (set when the author edited the post) |
language | "en" |
repliesCount | 42 |
reTruthsCount | 15 |
likesCount | 320 |
upvotesCount / downvotesCount | 320 / 4 (Truth Social's own up/down tally, separate from likesCount) |
quotesCount | 2 |
isReblog / rebloggedByAcct | false / null |
mediaUrls | ["https://static-assets.truthsocial.com/sample.jpg"] |
tags | ["sample"] |
mentions | mentioned accounts on the post |
poll | poll options and vote counts, when present |
cardTitle / cardUrl | link-preview card title and URL, when present |
authorUsername / authorDisplayName | "exampleuser" / "Example User" |
pinned / sponsored | false / false |
quoteId | id of the quoted post, or null |
rawStatus | the complete source status object |
Profile records (recordType "profile", returned only when Profile content is profileOnly) carry userId, username, acct, displayName, bio and bioHtml, url, avatar and header images, followersCount, followingCount, statusesCount, createdAt, lastStatusAt, verified, locked, bot, website, location, premium, isGroupAccount, fields, emojis and the complete rawAccount object.
How to Use
- Add one or more Truth Social profile or post URLs under Start here. Leave it empty and the actor scrapes
@realDonaldTrumpby default. - For profile URLs, pick Profile content: profile only, posts only, replies only, or both.
- Set Max items to cap run size and cost; optionally set Max posts/replies per profile or Max pages.
- For recurring monitoring, turn on Incremental changes for scheduled runs under Resume and recurring updates, then click Start.
A single profile, posts and replies:
{"startUrls": [{ "url": "https://truthsocial.com/@realDonaldTrump" }],"profileContentType": "postsAndReplies","maxItems": 50}
Individual posts by URL:
{"startUrls": [{ "url": "https://truthsocial.com/@exampleuser/113456789012345678" },{ "url": "https://truthsocial.com/@anotheruser/113456789012345999" }],"includeRaw": false}
Profile metadata only, no posts:
{"startUrls": [{ "url": "https://truthsocial.com/@exampleuser" }],"profileContentType": "profileOnly"}
Recurring incremental monitoring:
{"startUrls": [{ "url": "https://truthsocial.com/@exampleuser" }],"profileContentType": "postsOnly","incrementalMode": true,"emitExpired": true,"stateKey": "exampleuser-posts"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/truthsocial-com-scraper").call(run_input={"startUrls": [{"url": "https://truthsocial.com/@realDonaldTrump"}],"maxItems": 50,})for post in client.dataset(run["defaultDatasetId"]).iterate_items():print(post["postId"], post["content"][:80])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/truthsocial-com-scraper').call({startUrls: [{ url: 'https://truthsocial.com/@realDonaldTrump' }],maxItems: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one interrupted pull: paste its run or dataset ID and the actor skips every post it already saved there. Truth Social's timeline is newest-first, so a resumed profile walk stops paginating as soon as it catches up, so it costs less than a full re-scrape, not just returns fewer rows. An id that cannot be resolved to a run or dataset fails the run immediately, before anything is collected or billed. - Incremental mode (
incrementalMode) is for running the same profile/post set again and again. Each post is classifiedNEW,UPDATED(withchangedFields),UNCHANGED(suppressed and not billed unlessemitUnchangedis on),REAPPEAREDorEXPIRED.EXPIREDis produced only once a run completely scans every tracked profile withemitExpiredon; a run cut short by Max items, Max pages, or combined with Resume skips EXPIRED detection that run and keeps the previous state as-is.REAPPEAREDonly appears for a post that an earlieremitExpiredrun had already marked missing and that then shows up again on any later run that finds it, complete scan or not; it is not produced on a normal or first run.stateKeynames or shares one monitoring baseline; left empty, a key is derived automatically fromstartUrlsandprofileContentType. Combining Incremental mode with Resume is allowed only on the very first run for a state key; once that key has tracked state, a run using both fails instead of mixing the two mechanisms.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed summary of each record, a title plus its key fields flattened to plain markdown text, not the full JSON. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify → Settings → Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created; if it's left blank for a Notion connector, that export is skipped with a warning. Other connectors ignore this field.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave mcpConnectors empty to skip export entirely.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
startUrls | array | []; falls back to https://truthsocial.com/@realDonaldTrump when left empty (prefill: one entry with that URL) | Public Truth Social profile or post URLs, mixed in the same list. Profile URLs return that account's posts; post URLs return the single post. |
profileContentType | string | postsAndReplies | For profile URLs: profileOnly, postsOnly, repliesOnly, or postsAndReplies. Ignored for post URLs. |
maxPostsPerProfile | integer | 0 | No per-profile cap by default; the run still stops at Max items. Fewer rows are returned when a profile has fewer public matching records. |
maxItems | integer | 20 (also prefilled as 20) | Maximum matching rows saved across the whole run. |
maxPages | integer | 0 | No page limit by default; the run stops at Max items. |
resumeFromRunId | string | none | Paste a previous run ID or dataset ID to continue a large pull without re-collecting or re-billing posts already saved there. |
incrementalMode | boolean | false (also prefilled as false) | Turn on for daily or recurring monitoring; later runs return only NEW and UPDATED posts by default. REAPPEARED only occurs after an earlier run with Emit expired posts on has marked a post missing. |
stateKey | string | none | Names or shares an incremental-mode baseline; left empty, a key is derived automatically from startUrls and profileContentType. |
emitUnchanged | boolean | false (also prefilled as false) | Also return (and bill) posts that have not changed since the last incremental run. |
emitExpired | boolean | false (also prefilled as false) | Also return (and bill) posts no longer found; only produced once a run has completely scanned every tracked profile, not when Max items, Max pages, or Resume cut it short. |
includeRaw | boolean | true | Keeps the complete source account/status object on every record. |
countryCode | string | US | Preferred connection country; US is recommended for Truth Social. |
proxyConfiguration | object | Apify Residential (useApifyProxy: true, group RESIDENTIAL; same as the prefill) | Connection settings. A working connection is required; a run configured with no connection at all is rejected outright and fails. |
mcpConnectors | array | none | Optional: send a summary of each record to apps you authorized under Integrations. |
notionParentPageUrl | string | none | Notion connector only: page under which records are created. Required only when exporting to Notion. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run; does not affect the dataset. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"recordType": "post","postId": "113456789012345678","id": "113456789012345678","uri": "https://truthsocial.com/@exampleuser/113456789012345678","postUrl": "https://truthsocial.com/@exampleuser/113456789012345678","content": "Sample post text goes here.","contentHtml": "<p>Sample post text goes here.</p>","createdAt": "2026-08-01T12:00:00.000Z","editedAt": null,"language": "en","repliesCount": 42,"reTruthsCount": 15,"likesCount": 320,"favouritesCount": 320,"quotesCount": 2,"inReplyToId": null,"sensitive": false,"visibility": "public","isReblog": false,"rebloggedByAcct": null,"mediaUrls": [],"tags": ["sample"],"mentions": [],"poll": null,"cardTitle": null,"cardUrl": null,"authorId": "900000000000000001","authorUsername": "exampleuser","authorAcct": "exampleuser","authorDisplayName": "Example User","authorUrl": "https://truthsocial.com/@exampleuser","upvotesCount": 320,"downvotesCount": 4,"pinned": false,"sponsored": false,"quoteId": null,"rawStatus": {},"scrapedAt": "2026-09-29T00:00:00.000Z"}
Plan Requirement
This actor needs a working residential connection to reach Truth Social; a run configured with no connection at all is rejected outright and fails rather than returning data. The default connection setting (Apify Residential) works out of the box. Keep the country code set to US, which the site responds to most reliably.
FAQ
How much does it cost?
You pay a small per-run start fee plus a per-record fee for each row saved to the dataset. The Pricing tab shows the current rates. Use Max items to cap the cost of any run.
Is it legal to scrape Truth Social?
This actor collects only publicly available profile and post data. You are responsible for how you use it: follow Truth Social's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Some public social media records may still contain personal data, so handle results accordingly.
Can I get only new or changed posts on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental changes for scheduled runs. Each run then returns only NEW and UPDATED posts by default (plus REAPPEARED once an earlier run with Emit expired posts on has marked one missing); UNCHANGED ones are suppressed and not billed unless emitUnchanged is on.
What's the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues one specific interrupted run using a pasted run or dataset ID. Incremental mode remembers its own baseline and is meant for running the same profile/post set repeatedly on a schedule. Combining the two is allowed only the first time you turn Incremental mode on for a state key; once that key has tracked state, a run using both fails instead of mixing the two mechanisms.
Why did my run fail instead of returning an empty dataset?
If every request to Truth Social is refused, the run stops with a clear error instead of billing you for a "no data" result. Retry with a residential connection (country US). If the site answered but nothing matched your input (for example, an account or post that doesn't exist), the run still succeeds with an empty dataset and reports why on the run's status message.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push a summary of each record into Notion, Linear or Airtable as soon as the run finishes.
🔗 Want more social media data?
Pair this actor with these related scrapers from the same team:
| 📱 Lemon8 Profile Scraper Scrape Lemon8 user profiles with automated multi-profile discovery. Extract profile data... | 📱 Lemon8 Search Scraper Scrape Lemon8 posts by keyword across multiple regions. Extract posts, images, videos... |
| 📱 Lemon8 Media Scraper Lightweight Lemon8 scraper for extracting image and video URLs from posts, with optional... | 👗 Lemon8 Feed Scraper Scrape Lemon8 feeds across 22 categories and 10+ regions. Extract posts, images, videos... |
| 📱 Mastodon From $1/1K. Scrape trending Mastodon profiles and related posts from any Mastodon... | 🏠 Cian RU Collect property listings from Cian.ru by search filters or direct URLs. Returns... |
💬 Support & custom scrapers
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email abotapi@proton.me or message Telegram @abotapi.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.