# Truth Social Scraper (`simpleapi/truth-social-scraper`) Actor

📰 Truth Social Scraper extracts posts, profiles, timelines, hashtags, mentions & engagement metrics from Truth Social. ⚙️ Clean, structured data with pagination and CSV/JSON export. 🚀 Ideal for social listening, brand monitoring, research & competitive analysis.

- **URL**: https://apify.com/simpleapi/truth-social-scraper.md
- **Developed by:** [SimpleAPI](https://apify.com/simpleapi) (community)
- **Categories:** Social media, Developer tools, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.99 / 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.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### Truth Social Scraper — Posts, Replies and Media Attachments

Truth Social Scraper pulls public posts from any Truth Social profile — or a specific post by ID or link — and returns each one as typed JSON straight from Truth Social's own API: `id`, `created_at`, `content`, `url`, `account`, `media_attachments`, engagement counts, reply and retruth threads, and every other field the platform attaches to a status. It's built for political analysts, journalists, researchers and monitoring teams who need a named account's public activity without maintaining a browser session or reverse-engineering Truth Social's Cloudflare defenses themselves. Point it at a handle, set how many posts you want, and rows land in your dataset as each page finishes loading — no waiting for the full run to complete before you can start reading results.

### What is Truth Social Scraper?

Truth Social Scraper is an Apify Actor that turns a Truth Social profile's public timeline — or a single post URL — into a structured dataset of posts. It calls the same public status API that truthsocial.com's own web app uses, so results include the full status object Truth Social returns: text content, timestamps, media, and the poster's account details. No Truth Social account, login, or cookie is required — everything returned is visible to any anonymous visitor.

Key capabilities:

- **Discovery by handle or by URL/ID** — scrape a profile's timeline, or skip timelines entirely and fetch one or more specific posts by ID or link
- **Incremental runs** — pick up only the posts published since your last successful run for that username, tracked automatically per profile
- **Content filters** — replies only, media-only posts, or the normal (non-reply) feed
- **Readable or raw text** — optional HTML-to-plain-text cleaning of post content, applied recursively to retruthed and quoted posts too
- **Historical backfill** — jump to posts older than a specific 18-digit post ID
- **Standard Apify export** — every row lands in the Actor's dataset, downloadable as JSON, CSV, Excel, or read live through the Apify API

### What Truth Social data is publicly accessible without logging in?

Truth Social's own web client reads posts and profile details through a public status API that requires no session token or cookie — the same one this Actor calls. What's gated is anything tied to a logged-in viewer's own account, not the post or profile content itself.

| Data category | Publicly accessible | Requires a logged-in Truth Social session |
| --- | --- | --- |
| Post text, timestamps, URL | ✓ Public | — |
| Media attachments (images, video) | ✓ Public | — |
| Poster's account details (name, bio, follower counts) | ✓ Public | — |
| Reply, retruth and quote counts | ✓ Public | — |
| Whether *you* have liked/retruthed/bookmarked a post | ✗ | Requires authenticated session |
| Direct messages | ✗ | Requires authenticated session |

Because the Actor makes unauthenticated requests, viewer-relative flags in the output — `favourited`, `reblogged`, `bookmarked` — always read `false`. There is no logged-in viewer to attach them to. Everything else in the status object is the same public data Truth Social serves to any visitor.

### What data can I extract with Truth Social Scraper?

Every row is the complete status object Truth Social's API returns for a post — not a trimmed subset. The fields below are grouped by what they describe.

| Field | Example value | Use case |
| --- | --- | --- |
| `id` | `"113847449027767807"` | Unique post identifier, used for `startFromPostId` and deduplication |
| `created_at` | `"2025-01-18T04:23:30.018Z"` | Timeline ordering, date-range analysis |
| `content` | `"Coming up this weekend…"` | Text/sentiment analysis; HTML-cleaned when `cleanContent` is on |
| `url` | `"https://truthsocial.com/@realDonaldTrump/113847449027767807"` | Direct link back to the post |
| `uri` | `"https://truthsocial.com/@realDonaldTrump/113847449027767807"` | Internal API reference for the same post |
| `visibility` | `"public"` | Confirms the post's audience setting |
| `language` | `"en"` | Language-code filtering downstream |
| `sensitive` | `false` | Content-warning flag |
| `spoiler_text` | `""` | Warning text shown when `sensitive` is true |
| `in_reply_to_id` | `null` | Non-null when the row is a reply; drives `onlyFetchReplies` |
| `in_reply_to_account_id` | `null` | Account ID of the post being replied to |
| `quote_id` | `null` | Non-null when the post quotes another post |
| `media_attachments` | `[{ "type": "image", "url": "…" }]` | Image/video URLs for archiving or display |
| `mentions` | `[]` | Accounts tagged in the post |
| `tags` | `[]` | Hashtags used in the post |
| `card` | `null` | Link-preview card when the post links out |
| `poll` | `null` | Poll data when the post contains one |
| `emojis` | `[]` | Custom emoji shortcodes used in the content |
| `group` | `null` | Group context, when the post was made in a group |
| `sponsored` | `false` | Whether Truth Social marks the post as sponsored |
| `replies_count` | `2435` | Number of replies |
| `reblogs_count` | `5407` | Number of retruths |
| `favourites_count` | `22713` | Number of likes |
| `favourited` / `reblogged` / `bookmarked` | `false` | Viewer-relative flags — always `false` on unauthenticated requests |
| `muted` / `pinned` | `false` | Notification-mute and profile-pin flags |
| `reblog` | `null` | Full nested status object when this row is a retruth |
| `quote` | `null` | Full nested status object when this row quotes another post |
| `account` | `{ "username": "realDonaldTrump", … }` | The full poster account object — see below |

Field names are returned exactly as Truth Social's API names them — `created_at`, `media_attachments`, `replies_count`, snake\_case throughout — rather than remapped to a different naming convention. That matters if you're joining this data against another tool that expects the platform's native field names, or against a dataset scraped by a different Truth Social Actor: checked on the Apify Store on 26 July 2026, `tri_angle/truth-scraper`'s documented output uses `createdAt` and `mediaAttachments` (camelCase), a different shape for the same underlying data.

#### Poster account fields

`account` is a nested object carrying everything Truth Social's API attaches to the poster: `id`, `username`, `acct`, `display_name`, `avatar`, `avatar_static`, `header`, `header_static`, `note` (bio, as HTML), `url`, `locked`, `bot`, `discoverable`, `group`, `created_at`, `followers_count`, `following_count`, `statuses_count`, `last_status_at`, `verified`, `location`, `website`, `unauth_visibility`, `emojis`, and `fields`. These are the identity and reach signals — follower counts and `verified` are what most analysts filter or sort on when comparing accounts.

Each entry in `media_attachments` is itself a nested object, carrying `id`, `type` (`image`, `video`, or similar), `url` (the full-resolution file), `preview_url` (a smaller preview image), `description` (alt text, when the poster added one), plus additional technical fields Truth Social attaches for rendering, such as dimension and processing metadata. Only `url`, `preview_url`, `type` and `description` are typically needed for archiving or display purposes.

#### Reply, retruth and thread fields

`in_reply_to_id` and `in_reply_to_account_id` mark a post as a reply and identify its parent; use `onlyFetchReplies` to isolate these. `reblog` and `quote` carry the *complete* nested status object of the retruthed or quoted post — recursively HTML-cleaned when `cleanContent` is on — so a retruth's original text and account are available without a second lookup. `replies_count`, `reblogs_count` and `favourites_count` are the engagement signals attached to every post, reply, retruth and quote alike.

### How do I run Truth Social Scraper?

Truth Social Scraper runs entirely on Apify — there's no separate signup, install, or local setup.

1. Open Truth Social Scraper on the Apify Store and click **Try for free**
2. Enter one or more usernames under **Who should we scrape?** (the `@` is optional), or expand **Advanced** and paste post IDs/URLs into **Fetch one or more posts** to skip timeline mode entirely
3. Set **How many posts?** to the number of posts you want per profile (5–5,000)
4. Toggle **Replies only**, **Posts with photos/video only**, and **Clean, readable text** to match your use case
5. Click **Start** — rows begin appearing in the dataset as soon as the first page of posts loads, before the run finishes
6. Download the finished dataset as JSON, CSV or Excel, or read it back through the Apify API for automated pipelines

For recurring monitoring, turn on **Pick up where you left off** and put the Actor on an Apify **Schedule** — each scheduled run only returns posts published since the previous one for that username, and the cursor is stored automatically per profile.

### Why not build this yourself?

Truth Social does not publish a general-purpose developer API for third-party access — none of the established Truth Social scrapers on Apify document one either. The internal status API this Actor calls is unauthenticated and public, but reaching it reliably at any volume is the actual engineering problem.

Truth Social's edge sits behind Cloudflare, and datacenter IPs get challenged quickly. This Actor escalates through three connection tiers rather than failing on the first block: a direct request, then Apify's auto-proxy, then Apify Residential proxy — each residential attempt uses a fresh session ID, retried up to eight times before giving up. On the residential tier, requests are additionally tried with `curl-cffi` browser-TLS impersonation (Chrome 131 fingerprint) before falling back to a standard HTTP client, since that ordering produces fewer Cloudflare 403s in practice. HTTP 429 responses honor the platform's `Retry-After` header when present (capped at 10 minutes), and timeline pages are paced with a deliberate pause between requests specifically because fast, back-to-back pagination calls trigger Cloudflare more often. None of that is a one-time build — Cloudflare's rules and Truth Social's own rate tolerance shift, so it needs ongoing maintenance to keep working.

Build it yourself if you need a bespoke pipeline and are prepared to maintain proxy rotation and TLS fingerprinting against a moving target. Use Truth Social Scraper when you want the data without owning that maintenance burden.

### How does Truth Social Scraper handle blocking and rate limits?

Every request goes through the same escalation ladder rather than failing at the first sign of trouble. On tier 0 (direct), a block or network error moves the run to tier 1 (Apify's `auto` proxy group); a further block moves it to tier 2 (Apify Residential), which is retried with a freshly rotated session ID up to eight times before the run gives up entirely. Across all three tiers combined, the Actor allows up to 47 total connection attempts on a single API call before raising an error — network retries use exponential backoff (`1.0 * 2^attempt`, capped at 64 seconds, plus jitter) so repeated failures don't hammer the same path.

HTTP 429 responses are handled distinctly: if Truth Social sends a `Retry-After` header, the Actor waits that long (plus 0.5–2 seconds of jitter, capped at 10 minutes); if it doesn't, the wait falls back to a 2.5x-per-attempt exponential backoff with a 20-second floor. A response is treated as blocked not just on HTTP 401/403/429, but also when the response body itself contains Cloudflare's own challenge markers ("cloudflare", "just a moment", "challenge") — so a soft-blocked 200 response doesn't get parsed as if it were real data. On the residential tier, a detected Cloudflare interstitial adds an extra cooldown on top of the normal one (up to 6 seconds, scaling with how many residential attempts have already been tried) before the next rotated-IP attempt.

Timeline pagination itself is deliberately paced — roughly 4.5 seconds plus up to 1.25 seconds of jitter between pages — specifically because fast, back-to-back paginated calls are what tends to trigger Cloudflare in the first place. None of this backoff and escalation logic is configurable from the Actor's input; it runs the same way on every request so a run either completes cleanly or fails loudly, never silently returning a partial or fabricated row.

### How to use data extracted from Truth Social

#### Political analysts and campaign researchers

The most direct use of this data: track a public figure's statements as they're posted, without refreshing a browser tab all day. Set `truthSocialUsername` to the account you're following, enable `continueFromLastPostId` so every scheduled run only returns posts published since the previous one, and pull `content`, `created_at` and `media_attachments` into a timeline view, a spreadsheet log, or an internal alert feed. Because `cleanContent` strips the platform's HTML wrapper down to plain text by default, the output is ready to paste into a report or feed to a text-analysis step without a cleanup pass. `onlyFetchPostsWithMedia` isolates image and video posts specifically, which is useful when the workflow is archiving visual statements — rally photos, campaign graphics, video clips — separately from text-only posts.

#### Journalists and media-monitoring teams

Running this on a schedule against several accounts turns it into a standing monitoring feed rather than a one-off pull. `onlyFetchReplies` isolates reaction threads on a specific account — useful when the story is how other public figures or the public are responding to a post, not the post itself — while the default (replies hidden) view tracks only the account's own original statements. Because `continueFromLastPostId` is tracked in a separate key-value entry per username, a newsroom can monitor dozens of accounts on independent schedules without one account's cursor interfering with another's, and without re-fetching posts already logged in a previous run.

#### Market research and social-sentiment intelligence

Pull `replies_count`, `reblogs_count` and `favourites_count` alongside `created_at` across a large `maxPosts` run to chart engagement over time for one account, or run the same input against several comparable accounts to benchmark relative reach and engagement rate. Because `reblog` and `quote` carry the complete nested status object of whatever was retruthed or quoted, a retruth's original engagement numbers travel with it in the same row — so amplification of outside content is visible without a second lookup or a separate API call to resolve the original post.

#### AI agents and automated pipelines

Every row is typed JSON with a stable field set, so `content` and `account` can be indexed into a RAG store or handed straight to an LLM for summarization or sentiment scoring without a cleanup pass. Because the Actor runs on Apify, any agent framework that can call the Apify API — LangChain, CrewAI, a custom tool definition, or a plain HTTP call — can trigger a run and read the dataset back.

### ⬇️ Input sample

| Parameter | Required | Type | Description | Example value |
| --- | --- | --- | --- | --- |
| `truthSocialUsername` | No | array | One or more profile handles, one per line. The `@` symbol is optional. Ignored when `fetchSinglePostByIdOrUrl` has entries. Defaults to `realDonaldTrump` if left empty. | `["realDonaldTrump"]` |
| `maxPosts` | No | integer | Number of posts to collect per profile. Minimum `5`, maximum `5000`, default `20`. Not used in single-post mode. | `100` |
| `continueFromLastPostId` | No | boolean | On: only posts newer than the last successful run for that username. Off (default): fetch fresh from the top of the feed. Cannot be combined with `startFromPostId`. | `true` |
| `onlyFetchReplies` | No | boolean | On: only reply posts. Off (default): normal posts, replies excluded. | `false` |
| `onlyFetchPostsWithMedia` | No | boolean | On: only posts containing images or video. Off (default): all posts. | `true` |
| `cleanContent` | No | boolean | On (default): `content` returned as plain, readable text. Off: original HTML formatting preserved. | `true` |
| `startFromPostId` | No | string | Optional 18-digit post ID; loads posts older than this ID. Cannot be combined with `continueFromLastPostId`. Advanced. | `"113847449027767807"` |
| `fetchSinglePostByIdOrUrl` | No | array | One or more post IDs or full Truth Social post URLs, one per line. When populated, profile-timeline mode is skipped entirely and only these posts are fetched. Advanced. | `["https://truthsocial.com/@realDonaldTrump/113847449027767807"]` |
| `proxyConfiguration` | No | object | Apify Proxy settings. Optional — the Actor escalates to Apify proxy tiers automatically when the site blocks a direct request. Prefilled with `useApifyProxy: true`. | `{"useApifyProxy": true}` |

#### Example input

```json
{
  "truthSocialUsername": ["realDonaldTrump"],
  "maxPosts": 50,
  "continueFromLastPostId": true,
  "onlyFetchReplies": false,
  "onlyFetchPostsWithMedia": false,
  "cleanContent": true
}
```

#### Common pitfall

Don't set both `continueFromLastPostId` and `startFromPostId` in the same run — the Actor rejects that combination outright ("Don't combine 'Pick up where you left off' with 'Start older than this post' — choose one."). Pick the incremental cursor for recurring monitoring, or the fixed post-ID anchor for a one-off historical backfill, not both. Also note `startFromPostId` must be exactly 18 digits — a truncated or copy-pasted URL fragment instead of the raw ID will fail validation.

### ⬆️ Output sample

Each dataset row is the full Truth Social status object described above — typed JSON, same field set on every post, reply, retruth and quote. Download it as JSON, CSV or Excel from the Actor's dataset tab, or read it live through the Apify API.

#### Example output

```json
{
  "id": "113847449027767807",
  "created_at": "2025-01-18T04:23:30.018Z",
  "in_reply_to_id": null,
  "in_reply_to_account_id": null,
  "quote_id": null,
  "sensitive": false,
  "spoiler_text": "",
  "visibility": "public",
  "language": "en",
  "uri": "https://truthsocial.com/@realDonaldTrump/113847449027767807",
  "url": "https://truthsocial.com/@realDonaldTrump/113847449027767807",
  "content": "Coming up, an important weekend ahead. Stay tuned. DJT",
  "account": {
    "id": "107780257626128497",
    "username": "realDonaldTrump",
    "acct": "realDonaldTrump",
    "display_name": "Donald J. Trump",
    "locked": false,
    "bot": false,
    "discoverable": false,
    "group": false,
    "created_at": "2022-02-11T16:16:57.705Z",
    "note": "<p></p>",
    "url": "https://truthsocial.com/@realDonaldTrump",
    "avatar": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/accounts/avatars/107/780/257/626/128/497/original/454286ac07a6f6e6.jpeg",
    "avatar_static": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/accounts/avatars/107/780/257/626/128/497/original/454286ac07a6f6e6.jpeg",
    "header": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/accounts/headers/107/780/257/626/128/497/original/ba3b910ba387bf4e.jpeg",
    "header_static": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/accounts/headers/107/780/257/626/128/497/original/ba3b910ba387bf4e.jpeg",
    "followers_count": 8541456,
    "following_count": 71,
    "statuses_count": 24750,
    "last_status_at": "2025-01-18",
    "verified": true,
    "location": "",
    "website": "www.DonaldJTrump.com",
    "unauth_visibility": true,
    "emojis": [],
    "fields": []
  },
  "media_attachments": [
    {
      "id": "113847448939449294",
      "type": "image",
      "url": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/media_attachments/files/113/847/448/939/449/294/original/098be9d5bdb0c201.jpg",
      "preview_url": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/media_attachments/files/113/847/448/939/449/294/small/098be9d5bdb0c201.jpg",
      "description": null
    }
  ],
  "mentions": [],
  "tags": [],
  "card": null,
  "poll": null,
  "group": null,
  "quote": null,
  "reblog": null,
  "sponsored": false,
  "replies_count": 2435,
  "reblogs_count": 5407,
  "favourites_count": 22713,
  "favourited": false,
  "reblogged": false,
  "bookmarked": false,
  "muted": false,
  "pinned": false,
  "emojis": []
}
```

Each successful row triggers one `row_result` pay-per-event charge. A post that can't be found — a stale or mistyped ID under `fetchSinglePostByIdOrUrl` — is logged and skipped without being pushed to the dataset, so it is not charged. If your Apify spend limit is reached mid-run, a row can still be written but report zero as the actually-charged count for that event.

### How do you filter and target specific posts?

Two decisions shape every run: **which posts** and **how many**. For "which posts," choose between profile mode (`truthSocialUsername`, scans the account's timeline) and direct mode (`fetchSinglePostByIdOrUrl`, which bypasses the timeline entirely and fetches only the exact posts you name) — direct mode is the precise choice when you already know the post IDs or links you need, profile mode is right for ongoing coverage of an account.

Within profile mode, narrow further with `onlyFetchReplies` (isolate reaction threads) or `onlyFetchPostsWithMedia` (isolate image/video posts) — both apply as real filters on the timeline, not a post-hoc trim. For historical scope, `startFromPostId` anchors the fetch to posts older than a given 18-digit ID for a one-off backfill, while `continueFromLastPostId` maintains a persistent per-username cursor for recurring monitoring runs — the two are mutually exclusive by design. `maxPosts` (5–5,000) is the volume control; internally the Actor pages through Truth Social's timeline 40 posts at a time until it reaches your limit or the feed runs out.

Three real examples:

**Daily incremental monitoring of one account:**

```json
{ "truthSocialUsername": ["realDonaldTrump"], "continueFromLastPostId": true, "maxPosts": 100 }
```

**Media-only backfill from a known point in history:**

```json
{ "truthSocialUsername": ["realDonaldTrump"], "onlyFetchPostsWithMedia": true, "startFromPostId": "113847449027767807", "maxPosts": 200 }
```

**Fetching specific posts only, bypassing the timeline:**

```json
{ "fetchSinglePostByIdOrUrl": ["https://truthsocial.com/@realDonaldTrump/113847449027767807", "113847449027767808"] }
```

### ▶️ Want to try other social scrapers?

Truth Social is a single-platform niche, so there's no second Truth Social Actor in this catalogue to pair it with — these are the closest equivalents for monitoring public posts on other platforms:

| Scraper name | What it extracts |
| --- | --- |
| Twitter/X Posts Scraper — Replies | Posts and reply threads from a given X/Twitter account |
| X/Twitter Posts Search by Advanced Keyword Filters | Keyword- and filter-driven post search on X/Twitter |
| Threads User Posts Scraper — Engagement Cadence Report | Posting cadence and engagement stats from a Threads profile |
| Reddit User Profile Posts and Comments Scraper | A Reddit user's posts and comments in one dataset |

Each follows the same pattern as this Actor: point it at a handle, set a volume limit, and get typed JSON rows back on the same Apify dataset/export surface.

### How to extract Truth Social data programmatically

Truth Social Scraper runs on Apify, so every run is a standard Apify API call — start it, poll it, and read typed JSON back from the dataset. No separate signup or API key beyond your Apify account token.

#### Python example

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("<YOUR_USERNAME>/truth-social-scraper-pay-per-events").call(run_input={
    "truthSocialUsername": ["realDonaldTrump"],
    "maxPosts": 50,
    "onlyFetchPostsWithMedia": True,
})

for post in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(post["created_at"], post["content"][:80], post["favourites_count"])
```

Works the same way in Go, Ruby, Node.js or a plain `curl` call against the Apify API — any language that can make an HTTP request.

#### Export to spreadsheets or CRM

Download the dataset as CSV directly from the Actor's dataset tab and import it into Excel, Google Sheets, or a CRM's bulk-import tool. `content`, `created_at`, `url` and the flattened `account.username` / `account.display_name` map cleanly to spreadsheet columns for a quick monitoring log.

### Is it legal to scrape Truth Social?

Scraping public Truth Social posts is generally permissible when the data is accessible without logging in, which is exactly what this Actor collects — nothing behind an authenticated session. Truth Social's public profile pages and posts exist to be seen by anyone, logged in or not.

Because each row includes the poster's account details — username, display name, avatar, bio, follower counts — this output does contain personal data under regimes like the GDPR and CCPA when the poster is an identifiable individual rather than an organization. That means a lawful basis is needed for storing and using it, particularly at scale or for anything beyond individual research. Truth Social's own terms of service also govern automated access to the platform, separately from whether the underlying data is personal.

In practice this means keeping storage proportionate to your actual purpose — a political-monitoring workflow that keeps a rolling window of an account's recent public statements sits on firmer ground than an indefinite archive of every reply an ordinary user has ever posted. Consult legal counsel for commercial applications involving bulk storage of personal data, especially where the accounts scraped belong to private individuals rather than public figures.

### ❓ Frequently asked questions

#### What happens if a post is deleted or a fetched ID doesn't exist?

The Actor treats a 404 from Truth Social's API as "not found" — it logs `⏭️ Post {id} not found — skipped.` and moves on without writing a row or triggering a charge. In profile-timeline mode, a post that has since been deleted simply doesn't appear in the timeline page it would have been on.

#### Can I get the poster's account details along with each post?

Yes — every row's `account` object carries the poster's username, display name, avatar, bio, follower and following counts, verification status and more. It's embedded in the same row as the post; there's no separate profile lookup or extra charge for it.

#### How accurate is the engagement data?

Replies, retruth and favourite counts (`replies_count`, `reblogs_count`, `favourites_count`) reflect what Truth Social's API reports at the moment the post is fetched. These numbers change continuously on the platform, so a re-run at a later time will return updated counts for the same post.

#### How many posts can I get per run?

`maxPosts` accepts 5 to 5,000 per profile, defaulting to 20. Internally, the Actor pages through the timeline 40 posts per request until it hits your limit or the profile's feed runs out — whichever comes first. `maxPosts` doesn't apply in single-post mode, where you get exactly the posts/URLs you list.

#### Can I fetch one specific post instead of a whole timeline?

Yes — populate `fetchSinglePostByIdOrUrl` with one or more post IDs or full Truth Social post links. When this field has entries, profile-timeline mode is skipped entirely and only those exact posts are fetched and saved.

#### Does Truth Social Scraper work with Claude, ChatGPT and other AI agent frameworks?

Yes. It's callable as a standard HTTP endpoint through the Apify API, so any agent framework that can issue a request — LangChain, CrewAI, n8n, or a custom tool definition — can trigger a run and read back typed JSON directly.

#### How does Truth Social Scraper compare to other Truth Social scrapers?

Checked on the Apify Store on 26 July 2026: `muhammetakkurtt/truth-social-scraper`'s own documentation states that if a requested post ID can't be found, "you will be charged for the post ID" regardless. This Actor's pay-per-event charge (`row_result`) fires only when a row is actually pushed to the dataset — a 404'd post is skipped and logged, not charged. `tri_angle/truth-scraper` documents a "peek" mode for cheap detect-then-fetch polling and a `postsNewerThan` date filter, neither of which this Actor exposes; this Actor's equivalent for recurring monitoring is `continueFromLastPostId`. `louisdeconinck/truth-social-scraper` is priced as a flat monthly subscription rather than pay-per-event.

#### Can I use Truth Social Scraper without a Truth Social account or API key?

Yes. No Truth Social login, cookie or API key is required — the Actor calls Truth Social's public status API directly. The only credential you need is your own Apify account to run the Actor.

#### Can I get only replies, or only posts with media?

Yes, both are real filters, not a post-hoc trim: `onlyFetchReplies` restricts results to reply posts (or excludes them, by default), and `onlyFetchPostsWithMedia` restricts results to posts carrying at least one image or video attachment. Both can be combined with either profile mode or the incremental cursor.

#### What happens if Truth Social adds or removes fields from its API?

New fields appear in your dataset automatically, without waiting on an Actor update. The Actor pushes the complete status object Truth Social's API returns rather than mapping it onto a fixed, hand-picked list of keys — so if the platform adds a field tomorrow, it shows up on the next run's rows; if a field is removed, it's simply absent rather than returned as a fabricated null.

### Conclusion

Truth Social Scraper turns any public Truth Social profile — or a specific post you already have the link for — into structured, typed JSON: post content, timestamps, media, engagement counts, and the full poster account object, in one row. It's built for political analysts, journalists, researchers and automated pipelines that need reliable coverage of public Truth Social activity without maintaining proxy rotation or Cloudflare workarounds themselves. The distinguishing detail is fidelity: every field Truth Social's API attaches to a post is passed through as-is, under its original name, so the dataset stays aligned with the platform's own data model release after release. Open Truth Social Scraper on the Apify Store, add a username or a post link, and click **Start** to get your first rows in minutes.

### 💬 Your feedback

Found a field missing from the output, or a run that behaved unexpectedly? Open an issue on the Actor's Issues tab on Apify — reports that include the username or post ID involved are the fastest to act on.

# Actor input Schema

## `truthSocialUsername` (type: `array`):

✏️ Add one or more profile handles (example: **realDonaldTrump**). One entry per line. The **@** symbol is optional — we’ll figure it out.

## `maxPosts` (type: `integer`):

🎯 Number of posts to collect from that profile’s feed (between **5** and **500**). Not used when you only fetch single posts in Advanced.

## `continueFromLastPostId` (type: `boolean`):

✅ **On:** only *new* posts since your last successful run for this profile.
⬜ **Off:** fetch fresh from the top of the feed (within your limit).

## `onlyFetchReplies` (type: `boolean`):

⬜ **Off:** normal posts (replies hidden).
✅ **On:** only reply posts.

## `onlyFetchPostsWithMedia` (type: `boolean`):

✅ **On:** keep posts that include images or video.
⬜ **Off:** everything (text-only included).

## `cleanContent` (type: `boolean`):

✅ **On (recommended):** plain text you can read at a glance.
⬜ **Off:** keep original formatting.

## `startFromPostId` (type: `string`):

📌 Optional **18-digit** post ID — we’ll load posts *older* than this. Don’t use together with **Pick up where you left off**.

## `fetchSinglePostByIdOrUrl` (type: `array`):

➕ Add post IDs or full Truth post links — one per line. When this list has items, **profile mode is skipped** and only these posts are saved.

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

🔐 If the site is picky about traffic, Apify can route through proxies you’ve enabled on your account. Totally optional for many runs.

## Actor input object example

```json
{
  "truthSocialUsername": [
    "realDonaldTrump"
  ],
  "maxPosts": 20,
  "continueFromLastPostId": false,
  "onlyFetchReplies": false,
  "onlyFetchPostsWithMedia": false,
  "cleanContent": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped items in the Actor's default dataset.

# 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 = {
    "truthSocialUsername": [
        "realDonaldTrump"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("simpleapi/truth-social-scraper").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 = {
    "truthSocialUsername": ["realDonaldTrump"],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("simpleapi/truth-social-scraper").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 '{
  "truthSocialUsername": [
    "realDonaldTrump"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call simpleapi/truth-social-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,simpleapi/truth-social-scraper"
        }
    }
}

```

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/RAkLQBnMsMH5ngxhw/builds/JtPhdTDkwRcQ0Q6DW/openapi.json
