# Truth Social Posts Scraper (`maximedupre/truth-social-posts`) Actor

Collect public Truth Social posts from one or more profile URLs. Get readable text, post links, timestamps, author details, engagement counts, media, and related post data in structured rows. Set per-profile limits and filters for replies, media, pinned posts, or post IDs.

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

## Pricing

from $0.30 / 1,000 public posts

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?

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

### 📰 Turn Truth Social profiles into post data

Researchers, journalists, and social media teams can collect public Truth Social posts from one or more profile URLs. Each saved row can include readable text, source links, publication and collection times, author details, engagement counts, and other public post data. This gives you a structured way to review profile activity without copying posts by hand.

- Collect reply posts from a public profile with [**Truth Social Replies Scraper**](https://apify.com/maximedupre/truth-social-posts/examples/truth-social-replies-scraper).
- Collect posts that include media with [**Truth Social Media Scraper**](https://apify.com/maximedupre/truth-social-posts/examples/truth-social-media-scraper).
- Review public profile activity with [**Truth Social Profile Scraper**](https://apify.com/maximedupre/truth-social-posts/examples/truth-social-profile-scraper).
- Collect a public post with [**Truth Social Post Scraper**](https://apify.com/maximedupre/truth-social-posts/examples/truth-social-post-scraper).
- Save public Truth Social posts in a dataset with [**Truth Social Posts**](https://apify.com/maximedupre/truth-social-posts/examples/truth-social-posts).

#### 📄 See each Truth Social post in a structured row

Each eligible post is saved as one dataset row. A row keeps the post URL and source profile URL with its text, time, author details, and other available post context. Fields that the source does not provide may be left out.

#### ▶️ Collect public posts from profile URLs

1. Add one or more public Truth Social profile URLs.
2. Set a post limit for each profile, or leave it empty to return all available posts until the source is exhausted.
3. Choose whether to collect replies, posts with media, or pinned posts.
4. Add a post ID boundary when you want to continue a collection or reach older posts.
5. Run the Actor and open the dataset.

Private or login-only profiles are not supported. The limit and filters use one shared set of choices for every profile in the run.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
|---|---|---|
| `profileUrls` | array of objects | Lists one or more public Truth Social profile URLs to collect. |
| `profileUrls[].url` | string | Gives the public profile URL. Private or login-only profiles are not supported. |
| `maxPostsPerProfile` | integer | Sets a post limit for each profile. Leave it empty to return all available posts until the source is exhausted. |
| `postIdBoundary` | string | Sets an optional numeric post ID. Use it to continue a collection or reach older posts. Leave it empty to start with the newest available posts. |
| `onlyReplies` | boolean | Set to true to collect only posts that are replies. Set to false to include all posts. |
| `onlyMedia` | boolean | Set to true to collect only posts with media attachments. Set to false to include posts with and without media. |
| `excludePinned` | boolean | Set to true to skip pinned posts. Set to false to include pinned posts. |

**Example input**

This example is copied from the public input of a successful current-beta default-input run:

```json
{
  "profileUrls": [
    {
      "url": "https://truthsocial.com/@realDonaldTrump"
    }
  ],
  "maxPostsPerProfile": 20
}
```

#### 🧾 Output

**Post row**

| Field | Type | What it does |
|---|---|---|
| `id` | string | Stable ID of the Truth Social post. |
| `publishedAt` | string (date-time) | Time when the post was published. |
| `url` | string (URI) | Public URL of the post. |
| `content` | string | Readable plain-text content of the post. |
| `contentHtml` | string | Original formatted content, with embedded links when available. |
| `sourceProfileUrl` | string (URI) | Public profile URL that supplied this post. |
| `collectedAt` | string (date-time) | Time when this post was collected. |
| `author` | object | Available public profile details for the post author. |
| `author.id` | string | Stable ID of the post author. |
| `author.username` | string | Username of the post author. |
| `author.displayName` | string | Display name of the post author. |
| `author.url` | string (URI) | Public profile URL of the post author. |
| `author.verified` | boolean | Says whether the source marks the author as verified. |
| `author.bio` | string | Bio text shown on the author profile. |
| `author.followersCount` | integer | Number of followers shown for the author. |
| `author.followingCount` | integer | Number of accounts followed by the author. |
| `engagement` | object | Available counts for replies, reblogs, and likes. |
| `engagement.replyCount` | integer | Number of replies to the post. |
| `engagement.reblogCount` | integer | Number of reblogs or reposts of the post. |
| `engagement.likeCount` | integer | Number of likes or favorites for the post. |
| `votes` | object | Available upvote and downvote counts for the post. |
| `votes.upvoteCount` | integer | Number of upvotes for the post. |
| `votes.downvoteCount` | integer | Number of downvotes for the post. |
| `media` | array of objects | Lists images, videos, and other media attached to the post. |
| `media[].type` | string | Kind of attached media, such as image or video. |
| `media[].url` | string (URI) | URL of the attached media file. |
| `media[].altText` | string | Alternative text for the media when available. |
| `media[].width` | integer | Width of the media in pixels when available. |
| `media[].height` | integer | Height of the media in pixels when available. |
| `media[].durationSeconds` | number | Length of the media in seconds when available. |
| `language` | string | Language marked on the post when available. |
| `visibility` | string | Visibility setting marked on the post. |
| `sensitive` | boolean | Says whether the source marks the post as sensitive. |
| `editedAt` | string (date-time) | Time when the post was last edited, when available. |
| `isPinned` | boolean | Says whether the post is pinned on the source profile. |
| `isSponsored` | boolean | Says whether the source marks the post as sponsored. |
| `hashtags` | array of strings | Lists hashtags included in the post. |
| `tags` | array of strings | Lists other tags included in the post. |
| `mentions` | array of objects | Lists accounts mentioned in the post. |
| `mentions[].id` | string | Stable ID of the mentioned account. |
| `mentions[].username` | string | Username of the mentioned account. |
| `mentions[].displayName` | string | Display name of the mentioned account. |
| `mentions[].url` | string (URI) | Public profile URL of the mentioned account. |
| `replyTo` | object | Gives the post that this post replies to, when available. |
| `replyTo.id` | string | Stable ID of the post being answered. |
| `replyTo.url` | string (URI) | Public URL of the post being answered. |
| `replyTo.authorUsername` | string | Username of the author of the post being answered. |
| `quotedPost` | object | Gives available context for the post quoted by this post. |
| `quotedPost.id` | string | Stable ID of the quoted post. |
| `quotedPost.url` | string (URI) | Public URL of the quoted post. |
| `quotedPost.authorUsername` | string | Username of the quoted post author. |
| `quotedPost.content` | string | Plain-text content of the quoted post. |
| `rebloggedPost` | object | Gives available context for the post reblogged or retruthed by this post. |
| `rebloggedPost.id` | string | Stable ID of the reblogged post. |
| `rebloggedPost.url` | string (URI) | Public URL of the reblogged post. |
| `rebloggedPost.authorUsername` | string | Username of the reblogged post author. |
| `rebloggedPost.content` | string | Plain-text content of the reblogged post. |
| `poll` | object | Gives available poll information attached to the post. |
| `poll.id` | string | Stable ID of the poll. |
| `poll.expiresAt` | string (date-time) | Time when the poll expires, when available. |
| `poll.expired` | boolean | Says whether the poll has expired. |
| `poll.multipleChoice` | boolean | Says whether the poll allows more than one choice. |
| `poll.votesCount` | integer | Total votes recorded for the poll. |
| `poll.options` | array of objects | Lists choices offered by the poll. |
| `poll.options[].title` | string | Text of the poll choice. |
| `poll.options[].votesCount` | integer | Votes recorded for this choice. |
| `linkPreview` | object | Gives available preview or link-card details for a link in the post. |
| `linkPreview.url` | string (URI) | Page URL shown by the link preview. |
| `linkPreview.title` | string | Title shown by the link preview. |
| `linkPreview.description` | string | Description shown by the link preview. |
| `linkPreview.domain` | string | Domain shown by the link preview. |
| `linkPreview.imageUrl` | string (URI) | URL of the image used by the link preview. |

**Example post row**

This is one genuine row from a successful current-beta default-input run. It is unshortened.

```json
{
  "id": "117156926105160416",
  "publishedAt": "2026-08-25T15:47:02.651Z",
  "url": "https://truthsocial.com/@realDonaldTrump/117156926105160416",
  "content": "RT: https://truthsocial.com/users/realDonaldTrump/statuses/117156925333799291",
  "contentHtml": "<p><span class=\"quote-inline\"><br/>RT: https://truthsocial.com/users/realDonaldTrump/statuses/117156925333799291</span></p>",
  "sourceProfileUrl": "https://truthsocial.com/@realDonaldTrump",
  "collectedAt": "2026-08-25T16:42:38.066Z",
  "author": {
    "id": "107780257626128497",
    "username": "realDonaldTrump",
    "displayName": "Donald J. Trump",
    "url": "https://truthsocial.com/@realDonaldTrump",
    "verified": true,
    "bio": "<p></p>",
    "followersCount": 13006458,
    "followingCount": 69
  },
  "engagement": {
    "replyCount": 333,
    "reblogCount": 1009,
    "likeCount": 3508
  },
  "votes": {
    "upvoteCount": 3508,
    "downvoteCount": 0
  },
  "media": [
    {
      "url": "https://static-assets-1.truthsocial.com/tmtg:prime-ts-assets/media_attachments/files/117/156/925/919/981/035/original/8b429cf93eaa56fb.jpg",
      "type": "image",
      "width": 953,
      "height": 1078
    }
  ],
  "hashtags": [],
  "tags": [],
  "mentions": [
    {
      "id": "107780257626128497",
      "username": "realDonaldTrump",
      "url": "https://truthsocial.com/@realDonaldTrump"
    }
  ],
  "visibility": "public",
  "sensitive": false,
  "isPinned": false,
  "isSponsored": false,
  "quotedPost": {
    "id": "117156925333799291",
    "url": "https://truthsocial.com/@realDonaldTrump/117156925333799291",
    "authorUsername": "realDonaldTrump",
    "content": ""
  }
}
```

#### 💳 Pricing

Pricing is based on each successfully collected public post saved to the dataset. The current tiered rate is shown in the Apify run panel. Use the per-profile limit and filters to control how many posts you request.

#### 🔌 Integrations

Read saved post rows in the Apify dataset after a run. For a walkthrough, watch:

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### How do I collect only reply posts?

Set `onlyReplies` to true. The dataset then contains posts that are replies when the source provides them.

##### How do I collect posts with media?

Set `onlyMedia` to true. This keeps posts that have one or more media attachments.

##### Can I skip pinned posts?

Yes. Set `excludePinned` to true to leave pinned posts out.

##### Can I leave the post limit empty?

Yes. Leave `maxPostsPerProfile` empty to return all available posts until the source is exhausted.

##### Can I collect older posts or continue a past collection?

Use a known numeric post ID in `postIdBoundary` to continue a collection or reach older posts. Leave it empty when you want to start with the newest available posts.

##### Can one run collect more than one profile?

Yes. Add more than one profile URL. The same post limit and filter choices apply to every profile in that run.

##### Can I use private or login-only profiles?

No. This Actor collects public profile URLs. It does not support private or login-only profiles.

##### Does this search Truth Social by keyword?

No. It collects posts from the profile URLs you submit. It does not search site-wide timelines, keywords, or hashtags.

##### Do I need to provide a Truth Social login?

No. The Actor retrieves public profile and post data without buyer-supplied source login information.

### 📝 Changelog

**0.0: Initial release**

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~truth-social-posts/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Twitter (X) Scraper](https://apify.com/maximedupre/twitter-scraper) for collecting public X posts, profiles, and engagement data.
- [Facebook User Posts Scraper](https://apify.com/maximedupre/facebook-user-posts-scraper) for collecting public Facebook profile and Page posts with media and engagement data.
- [VK Posts Scraper](https://apify.com/maximedupre/vk-posts-scraper) for collecting public VK wall posts, repost data, and media details.
- [Truth Social Profile Posts Scraper](https://apify.com/louisdeconinck/truth-social-profile-posts-scraper) for collecting posts from a specified Truth Social profile.
- [Truth Social Post Extractor](https://apify.com/sandaliaapps/truthsocial-post-extractor) for extracting public Truth Social post fields for a separate workflow.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `profileUrls` (type: `array`):

Add one or more public Truth Social profile URLs. Private or login-only profiles are not supported.

## `maxPostsPerProfile` (type: `integer`):

Set a post limit for each profile. Leave it empty to return all available posts until the source is exhausted.

## `postIdBoundary` (type: `string`):

Optional numeric post ID. Use it to continue a collection or reach older posts. Leave it empty to start with the newest available posts.

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

Turn on to collect only posts that are replies. Leave it off to include all posts.

## `onlyMedia` (type: `boolean`):

Turn on to collect only posts with media attachments. Leave it off to include posts with and without media.

## `excludePinned` (type: `boolean`):

Turn on to skip pinned posts. Leave it off to include pinned posts.

## Actor input object example

```json
{
  "profileUrls": [
    {
      "url": "https://truthsocial.com/@realDonaldTrump"
    }
  ],
  "maxPostsPerProfile": 20,
  "postIdBoundary": "123456789012345678"
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with one row for each successful public Truth Social post.

# 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 = {
    "profileUrls": [
        {
            "url": "https://truthsocial.com/@realDonaldTrump"
        }
    ],
    "maxPostsPerProfile": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/truth-social-posts").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 = {
    "profileUrls": [{ "url": "https://truthsocial.com/@realDonaldTrump" }],
    "maxPostsPerProfile": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/truth-social-posts").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 '{
  "profileUrls": [
    {
      "url": "https://truthsocial.com/@realDonaldTrump"
    }
  ],
  "maxPostsPerProfile": 20
}' |
apify call maximedupre/truth-social-posts --silent --output-dataset

```

## MCP server setup

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

```

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/g5tLTF3Nv5fauT3eo/builds/T1uJtaSLdkhHuZelU/openapi.json
