# Truth Social Scraper & Monitor - New, Edited, Deleted Posts (`neverempty/truth-social-posts-monitor`) Actor

For trading alerts, newsrooms and bots that poll a Truth Social account such as @realDonaldTrump every few minutes: only posts new since the last run, plus edits (with the text before) and deletions. Runs took 3.5-6.2 s on 2026-09-24. No login; unreadable runs are free. JSON, CSV, Excel.

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

## Pricing

from $2.80 / 1,000 post returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Truth Social Posts Monitor - New, Edited & Deleted Posts

Watch one Truth Social account and get **only what changed since your last run**: new posts (Truths and ReTruths), posts that were **edited**, and posts that were **deleted**. Built for alert bots, trading and news-monitoring pipelines, and researchers that poll an account such as `@realDonaldTrump` every few minutes and do not want to receive, store and pay for the same posts again.

- **One account per run, a few seconds.** Production runs on 2026-09-24 took 3.5-6.2 s of run time at 256 MB.
- **Only new posts.** The Actor remembers what it already returned (in a named key-value store), so a scheduled run with nothing new returns one free row that says "no new post".
- **Edits and deletions.** It also re-checks the account's 20 newest posts (the first page Truth Social lists) against what it saw before: an edited post comes back with `changeType: "edited"` and the text before the edit; a deleted post comes back with `changeType: "deleted"` and the last text seen. A post is only called deleted when Truth Social answers **HTTP 404** for that post; if Truth Social does not answer, it is checked again on the next run instead of being guessed.
- **No charge when Truth Social cannot be read.** If every attempt is refused, the run ends with a free row that says so and exits with an error; no start fee is charged.
- **Clean JSON.** Plain text with working links (not HTML fragments), plus the original HTML, media URLs, ReTruth and quote details, hashtags, mentions and counts.

Unofficial. Uses Truth Social's public, logged-out web API and returns only public posts. No login, no cookies, no account needed.

### What you get

One row per change. Example (production run, 2026-09-24):

```json
{
  "status": "ok",
  "changeType": "new",
  "username": "realDonaldTrump",
  "accountId": "107780257626128497",
  "postId": "117320581360547091",
  "postUrl": "https://truthsocial.com/@realDonaldTrump/117320581360547091",
  "createdAt": "2026-09-23T13:26:43.671Z",
  "editedAt": null,
  "text": "Victor Davis Hanson on Canada — A MUST SEE! President DONALD J. TRUMP",
  "isRepost": false,
  "mediaCount": 1,
  "repliesCount": 685,
  "repostsCount": 2133,
  "likesCount": 6361,
  "minutesAfterPosted": 163,
  "previousText": null,
  "isFirstCheck": true,
  "checkedAt": "2026-09-23T16:09:32.430Z"
}
```

| Column | Meaning |
|---|---|
| `status` | `ok` for a post row. Other values are free rows that say why nothing was returned (below). |
| `changeType` | `new`, `edited` or `deleted` |
| `username`, `accountId` | The watched account |
| `postId`, `postUrl` | The post (for a ReTruth, the ReTruth itself) |
| `createdAt`, `editedAt` | ISO times from Truth Social. `editedAt` is null for posts never edited |
| `text` | Plain text of the post with paragraphs as line breaks and full link URLs. Null for a post with only media |
| `contentHtml` | The post exactly as Truth Social sends it (HTML) |
| `language`, `sensitive` | As Truth Social reports them |
| `isReply`, `inReplyToPostId` | Replies (only when `onlyReplies` is on) |
| `isRepost`, `repostOfPostId`, `repostOfUsername`, `repostOfUrl`, `repostOfText` | ReTruth details: the original post, its author and text |
| `quoteOfPostId` | The quoted post, if any |
| `links`, `cardUrl`, `cardTitle` | Link URLs in the post and the link preview |
| `media`, `mediaCount` | Images and videos: `type`, `url`, `previewUrl` |
| `hashtags`, `mentions` | Tag names and mentioned accounts |
| `repliesCount`, `repostsCount`, `likesCount` | Counts at the time of the check (null if Truth Social did not send one) |
| `minutesAfterPosted` | Minutes between the post and this check - how fresh the alert is |
| `previousText` | For `edited`: the text before the edit. For `deleted`: the last text seen |
| `isFirstCheck` | True for rows returned on the first run of a watch |
| `note` | Free rows only: why nothing (or not everything) was returned |
| `checkedAt` | Time of the check |

#### Free rows (not charged)

| `status` | When |
|---|---|
| `no-new-posts` | Nothing new, edited or deleted since the last run |
| `watch-started` | First run with `maxPostsFirstRun` 0: the account is now watched |
| `not-found` | Truth Social has no account with this username (HTTP 404). No start fee |
| `blocked` | Truth Social refused every attempt, also from other IP addresses. No start fee; the run exits with an error so your schedule or webhook sees it |
| `unreadable` | Truth Social's answer could not be read, or more than 200 posts arrived since the last run |
| `bad-input` | The input could not be used; nothing was requested |
| `budget-reached` | The run hit the maximum total charge you set; the rows not returned are not remembered, so the next run returns them |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `username` | string | `realDonaldTrump` | One account: `realDonaldTrump`, `@realDonaldTrump` or `https://truthsocial.com/@realDonaldTrump` |
| `maxPostsFirstRun` | integer 0-100 | 10 | On the first run of a watch, return this many newest posts and only remember the rest. 0 = start watching from now |
| `onlyReplies` | boolean | false | Watch the account's replies instead of its posts. Truth Social lists replies separately from the profile's Truths |
| `includeReposts` | boolean | true | Also return ReTruths |
| `trackEditsAndDeletions` | boolean | true | Also return `edited` and `deleted` rows for the account's recent posts |
| `watchName` | string | (none) | Keeps separate memories for two schedules watching the same account for different purposes |
| `resetMonitoringState` | boolean | false | Forget this watch's memory at the start of the run (the run becomes a first check). Turn it off for scheduled runs |

Example:

```json
{ "username": "realDonaldTrump", "maxPostsFirstRun": 5 }
```

### How to use it for monitoring

1. Run it once with your account and `maxPostsFirstRun` (for example 5) to see the latest posts.
2. Create a **Schedule** (every 5, 15 or 60 minutes) with the same input.
3. Connect a webhook or an integration (Slack, email, Zapier, Make, Google Sheets) to the dataset. Every run returns only the changes; runs with no change return one free `no-new-posts` row, so filter on `status = "ok"`.

To watch several accounts, create one schedule (or task) per account. Each run stays small and fast, and each account keeps its own memory.

### Pricing

Pay per event:

- **Run start** - charged once per run, only when the account's post list was actually read. Not charged when the username does not exist, when Truth Social refuses the request, or when the run's maximum total charge has no room for the start fee plus one post row (then nothing is requested at all).
- **Post returned** - one per `new`, `edited` or `deleted` row. Free rows are never charged.

A scheduled check that finds nothing costs one run start. The exact prices are shown on the Pricing tab.

### Measured in production (2026-09-24, build 0.1)

| Run | Input | Result | Run time |
|---|---|---|---|
| First check | `{}` (realDonaldTrump), `maxPostsFirstRun` 5 | 5 new posts | 6.2 s |
| Second check | same | 1 free `no-new-posts` row | 5.3 s |
| Unknown user | `zq7neverempty_nope9` | 1 free `not-found` row | 3.5 s |
| Another account | `@DevinNunes`, 8 posts | 8 new posts (ReTruths included) | 5.8 s |
| Replies | DevinNunes profile URL, `onlyReplies` | 3 replies | 3.5 s |

Truth Social refuses most requests from cloud servers, so the Actor sends each request through Apify's US residential proxy and, if a request is refused, asks again from another IP address (up to 6 times per request). It never solves check pages or CAPTCHAs.

### Limits

- One account per run. Truth Social returns 20 posts per page; a later run reads back up to 200 new posts since the previous run and says so in a free row if more arrived.
- Edits and deletions are only seen among the account's 20 newest posts at the time of each run; an older post that is edited or deleted is not reported. At most 5 possibly deleted posts are confirmed per run (the rest on the next run).
- If Truth Social suddenly returns an empty list for an account that had posts (for example a suspended account), nothing is reported as deleted; a free row says so.
- If a later page of posts cannot be read in a run with more than 20 new posts, that run returns nothing, charges nothing and exits with an error, so no new post is skipped; the next run returns them all.
- Two overlapping schedules for the same account and `watchName` can overwrite each other's memory; use different `watchName`s.
- Counts (`likesCount` etc.) are a snapshot at the time of the check; the Actor does not return a post again only because its counts changed.
- Posts that Truth Social does not show to logged-out visitors are not returned.

### Support

Found a problem or need a field? Open an issue in the **Issues** tab of this Actor. Include the run ID and the input you used.

# Actor input Schema

## `username` (type: `string`):

One Truth Social account per run: a username (realDonaldTrump), @realDonaldTrump or a profile URL (https://truthsocial.com/@realDonaldTrump). Each run returns only the posts that are new, edited or deleted since the last run for this account. Empty = realDonaldTrump.

## `maxPostsFirstRun` (type: `integer`):

The first time an account is checked, return this many of its newest posts and only remember the rest. 0 = return none and start watching from now. Empty = 10. Later runs return every new post (up to 200 since the previous run).

## `onlyReplies` (type: `boolean`):

On = watch the account's replies to other posts instead of its posts (Truth Social lists replies separately from the profile's Truths). Off (or empty) = its posts and ReTruths, like the profile's Truths tab. Switching it starts a separate watch.

## `includeReposts` (type: `boolean`):

On (or empty) = also return ReTruths, with the original author, post ID, URL and text. Off = only posts the account wrote itself.

## `trackEditsAndDeletions` (type: `boolean`):

On (or empty) = also return a row when one of the account's 20 newest posts that was seen before is edited (changeType edited, with previousText) or deleted (changeType deleted, with previousText). A post is reported as deleted only when Truth Social answers HTTP 404 for it. Off = only new posts.

## `watchName` (type: `string`):

Optional. Runs with the same watch name share what has already been returned. Give different names to two schedules that watch the same account for different purposes, so each gets every new post. Letters, digits, dot, dash and underscore.

## `resetMonitoringState` (type: `boolean`):

Forget what this watch remembered for this account at the start of this run, so this run is a first check again. Turn it off again for scheduled runs, or every run starts over and returns the same posts again.

## Actor input object example

```json
{
  "username": "realDonaldTrump"
}
```

# Actor output Schema

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

One row per new, edited or deleted post: changeType, post ID and URL, created and edited time, plain text and HTML, ReTruth and quote details, links, media, hashtags, mentions, reply/ReTruth/like counts, minutes after posted, and the previous text for edits and deletions. A run with no new post, a username that does not exist, a refused request or a run that hit its maximum charge comes back as a free row that says why.

# 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 = {
    "username": "realDonaldTrump"
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/truth-social-posts-monitor").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 = { "username": "realDonaldTrump" }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/truth-social-posts-monitor").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 '{
  "username": "realDonaldTrump"
}' |
apify call neverempty/truth-social-posts-monitor --silent --output-dataset

```

## MCP server setup

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

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/de2V0SQ0oCD3xYGGk/builds/EuzgACAZMn0cNjix9/openapi.json
