# Threads Search Post Scraper (`maximedupre/threads-search-post-scraper`) Actor

Search public Threads posts by keyword or hashtag, or look up posts by URL or numeric ID. Get structured text, author, date, engagement, links, conversation data, and optional detailed source fields in an Apify dataset.

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

## Pricing

$2.65 / 1,000 posts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

### 🧵 Search public Threads posts with focused filters

Researchers, marketers, and developers can search public Threads posts by keyword or hashtag, or look up known posts by URL or numeric ID. The Actor saves structured rows with post text, public author details, publication time, available engagement counts, source links, and related public data, so you can review Threads search results in an Apify dataset.

- Collect a public Threads post with the **[Threads Post Scraper](https://apify.com/maximedupre/threads-search-post-scraper/examples/threads-post-scraper)** example.
- Find public posts under a tag with the **[Threads Hashtag Search](https://apify.com/maximedupre/threads-search-post-scraper/examples/threads-hashtag-search)** example.
- Search public Threads posts for a phrase with the **[Threads Post Search](https://apify.com/maximedupre/threads-search-post-scraper/examples/threads-post-search)** example.
- Look up a public Threads post by URL or ID with the **[Threads Post Lookup](https://apify.com/maximedupre/threads-search-post-scraper/examples/threads-post-lookup)** example.
- Review public Threads search matches with the **[Threads Search](https://apify.com/maximedupre/threads-search-post-scraper/examples/threads-search)** example.

#### 📊 Structured Threads post data

**What you get**

The default output is one normalized row for each saved public post. It includes the post text, author, publication time, available engagement counts, media, mentions, hashtags, outbound links, quote or repost links, conversation links, and public replies when Threads embeds them on a targeted post page. Turn on detailed source data to add selected source-level fields from Threads to the same row.

Fields that Threads does not show are omitted. The Actor handles public posts only. It does not promise a historical archive or a complete reply tree when replies are not present on the public post page.

#### ▶️ Run a public Threads search or lookup

**How it works**

1. Choose `Keyword`, `Hashtag`, or `Post URL or ID`.
2. Enter one or more keywords, hashtags, public post URLs, or numeric post IDs in the matching field.
3. For keyword and hashtag searches, choose `Recent first` or `Relevance or top`. You can also set a UTC date range, a recent-days window, or a public author.
4. Set `Maximum posts` when you want a smaller run. Leave it empty to return all available results until the source is exhausted.
5. Turn on `Include detailed source data` when you need the selected source-level fields alongside normalized data.

**Focused runs**

Keyword and hashtag lists use one shared sort, date, author, and post limit setting. Use separate runs when searches need independent settings. A direct post lookup accepts public URLs or numeric IDs and ignores search sorting, date, and author filters. You do not need to provide a source credential for public data, but private content is not covered.

**Where results go**

The Actor saves successful public post rows to the standard Apify dataset and exposes that dataset through the run output and API. A post ID and source URL help you trace each row back to its public Threads post.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `findPostsBy` | string | Select `keyword`, `hashtag`, or `post` to choose the target field. |
| `keywords` | array of strings | For `keyword`, enter one or more words or phrases. The same sort and post limit apply to every submitted keyword. |
| `hashtags` | array of strings | For `hashtag`, enter one or more hashtags with or without `#`. The same sort and post limit apply to every submitted hashtag. |
| `postTargets` | array of strings | For `post`, enter one or more public Threads post URLs or numeric post IDs. The same post limit and output setting apply to every submitted post. |
| `sortOrder` | string | For keyword and hashtag searches, choose `recent` or `top`. Direct post lookups ignore this field. |
| `publicationDate` | object | For keyword and hashtag searches, use a UTC date range or a recent-days window. Direct post lookups ignore this field. |
| `publicationDate.fromDate` | UTC date string | First publication date to include in a date range. |
| `publicationDate.toDate` | UTC date string | Last publication date to include in a date range. |
| `publicationDate.recentDays` | positive integer | Include posts published in this many days before the run. |
| `author` | string | For keyword and hashtag searches, enter a public Threads username with or without `@`. Direct post lookups ignore this field. |
| `maxItems` | positive integer | Optional run limit. Leave it empty to return all available results until the source is exhausted. |
| `includeSourceData` | boolean | Add selected detailed source-level fields alongside the normalized post data. |

**Example input**

The following small input uses a keyword search, recent ordering, one-post limit, and normalized output.

```json
{
  "findPostsBy": "keyword",
  "keywords": [
    "OpenAI"
  ],
  "sortOrder": "recent",
  "maxItems": 1,
  "includeSourceData": false
}
```

#### 🧾 Output

**Run output**

| Field | Type | What it does |
| --- | --- | --- |
| `dataset` | URL string | Links to the dataset containing successful public Threads post rows. |

The dataset contains normalized post rows by default. When `includeSourceData` is true, the same normalized fields remain and a `source` object is added.

**Normalized public post row**

The table below is complete for a row without detailed source data. Optional fields appear only when Threads provides them.

| Field | Type | What it does |
| --- | --- | --- |
| `postId` | string | Stable public ID of the Threads post. |
| `postUrl` | string (URI) | Public Threads URL for the post. |
| `text` | string, optional | Text shown in the post. Omitted when the post has no text. |
| `author` | object | Public author details. |
| `author.id` | string | Stable public ID of the author. |
| `author.username` | string | Public Threads username of the author. |
| `author.displayName` | string, optional | Public display name when shown. |
| `author.isVerified` | boolean, optional | Whether Threads marks the author as verified. |
| `publishedAt` | date-time string | Time when Threads published the post. |
| `engagement` | object, optional | Public engagement counts shown for the post. |
| `engagement.likeCount` | integer, optional | Public number of likes. |
| `engagement.replyCount` | integer, optional | Public number of replies. |
| `engagement.repostCount` | integer, optional | Public number of reposts. |
| `engagement.quoteCount` | integer, optional | Public number of quote posts. |
| `engagement.viewCount` | integer, optional | Public number of views when Threads shows it. |
| `media` | array of objects, optional | Image or video attachments shown in the post. A carousel uses multiple media items. |
| `media[].type` | string | Media type, either `image` or `video`. |
| `media[].url` | string (URI), optional | Direct source URL when Threads exposes one that users can open. |
| `media[].altText` | string, optional | Alternative text for the media item when available. |
| `media[].width` | integer, optional | Media width in pixels when available. |
| `media[].height` | integer, optional | Media height in pixels when available. |
| `media[].durationSeconds` | number, optional | Video duration in seconds when available. |
| `mentions` | array of objects, optional | Accounts mentioned in the post text. |
| `mentions[].username` | string | Mentioned public username. |
| `mentions[].id` | string, optional | Mentioned public account ID when available. |
| `hashtags` | array of strings, optional | Hashtags found in the post text. |
| `outboundLinks` | array of strings, optional | Links to other sites found in the post text. |
| `quotedPost` | object, optional | Public post quoted by this post when Threads provides the link. |
| `quotedPost.postId` | string | Stable ID of the quoted post. |
| `quotedPost.postUrl` | string (URI) | Public URL of the quoted post. |
| `repostedPost` | object, optional | Public post reposted by this post when Threads provides the link. |
| `repostedPost.postId` | string | Stable ID of the reposted post. |
| `repostedPost.postUrl` | string (URI) | Public URL of the reposted post. |
| `conversation` | object, optional | Source and parent links when this row is a reply. |
| `conversation.rootPostId` | string | Stable ID of the first post in the conversation. |
| `conversation.rootPostUrl` | string (URI) | Public URL of the first post in the conversation. |
| `conversation.parentPostId` | string | Stable ID of the post this reply directly answers. |
| `conversation.parentPostUrl` | string (URI) | Public URL of the post this reply directly answers. |
| `replies` | array of objects, optional | Public replies embedded on a targeted post page. |
| `replies[].postId` | string | Stable public ID of the reply. |
| `replies[].postUrl` | string (URI) | Public URL for the reply. |
| `replies[].text` | string, optional | Text shown in the reply. Omitted when the reply has no text. |
| `replies[].author` | object | Public author details for the reply. |
| `replies[].author.id` | string | Stable public ID of the reply author. |
| `replies[].author.username` | string | Public Threads username of the reply author. |
| `replies[].author.displayName` | string, optional | Public display name when shown. |
| `replies[].author.isVerified` | boolean, optional | Whether Threads marks the reply author as verified. |
| `replies[].publishedAt` | date-time string | Time when Threads published the reply. |
| `replies[].engagement` | object, optional | Public engagement counts shown for the reply. |
| `replies[].engagement.likeCount` | integer, optional | Public number of likes on the reply. |
| `replies[].engagement.replyCount` | integer, optional | Public number of replies to the reply. |
| `replies[].engagement.repostCount` | integer, optional | Public number of reposts of the reply. |
| `replies[].engagement.quoteCount` | integer, optional | Public number of quote posts for the reply. |
| `replies[].engagement.viewCount` | integer, optional | Public number of views for the reply when Threads shows it. |
| `replies[].media` | array of objects, optional | Image or video attachments shown in the reply. |
| `replies[].media[].type` | string | Reply media type, either `image` or `video`. |
| `replies[].media[].url` | string (URI), optional | Direct reply media URL when Threads exposes one that users can open. |
| `replies[].media[].altText` | string, optional | Alternative text for the reply media when available. |
| `replies[].media[].width` | integer, optional | Reply media width in pixels when available. |
| `replies[].media[].height` | integer, optional | Reply media height in pixels when available. |
| `replies[].media[].durationSeconds` | number, optional | Reply video duration in seconds when available. |
| `replies[].mentions` | array of objects, optional | Accounts mentioned in the reply text. |
| `replies[].mentions[].username` | string | Mentioned username in the reply. |
| `replies[].mentions[].id` | string, optional | Mentioned public account ID when available. |
| `replies[].hashtags` | array of strings, optional | Hashtags found in the reply text. |
| `replies[].outboundLinks` | array of strings, optional | Links to other sites found in the reply text. |
| `replies[].conversation` | object | Source and parent links for the reply. |
| `replies[].conversation.rootPostId` | string | Stable ID of the first post in the reply conversation. |
| `replies[].conversation.rootPostUrl` | string (URI) | Public URL of the first post in the reply conversation. |
| `replies[].conversation.parentPostId` | string | Stable ID of the post this reply directly answers. |
| `replies[].conversation.parentPostUrl` | string (URI) | Public URL of the post this reply directly answers. |
| `replies[].quotedPost` | object, optional | Public post quoted by the reply when Threads provides the link. |
| `replies[].quotedPost.postId` | string | Stable ID of the post quoted by the reply. |
| `replies[].quotedPost.postUrl` | string (URI) | Public URL of the post quoted by the reply. |
| `replies[].repostedPost` | object, optional | Public post reposted by the reply when Threads provides the link. |
| `replies[].repostedPost.postId` | string | Stable ID of the post reposted by the reply. |
| `replies[].repostedPost.postUrl` | string (URI) | Public URL of the post reposted by the reply. |

**Example normalized row**

This is a genuine row from a successful run with detailed source data turned off.

```json
{
  "postId": "3966878386803679869_63477724337",
  "postUrl": "https://www.threads.com/@legalmiga/post/DcNLuAYm6J9",
  "author": {
    "id": "63477724337",
    "username": "legalmiga",
    "displayName": "Taylor M. Tieman, Esq. | Business + Trademark Lawyer",
    "isVerified": true
  },
  "publishedAt": "2026-08-19T03:06:15.000Z",
  "text": "today, @openai launched a teen mode for chatGPT\n\non this episode of \"what could go wrong?!\"\n\n...",
  "engagement": {
    "likeCount": 123,
    "replyCount": 13,
    "repostCount": 7,
    "quoteCount": 0
  },
  "mentions": [
    {
      "username": "openai",
      "id": "63299409527"
    }
  ]
}
```

**Detailed public post row**

When `includeSourceData` is true, the row keeps every normalized field above and adds the `source` branch below. The table repeats the shared fields so this shape is complete.

| Field | Type | What it does |
| --- | --- | --- |
| `postId` | string | Stable public ID of the Threads post. |
| `postUrl` | string (URI) | Public Threads URL for the post. |
| `text` | string, optional | Text shown in the post. Omitted when the post has no text. |
| `author` | object | Public author details. |
| `author.id` | string | Stable public ID of the author. |
| `author.username` | string | Public Threads username of the author. |
| `author.displayName` | string, optional | Public display name when shown. |
| `author.isVerified` | boolean, optional | Whether Threads marks the author as verified. |
| `publishedAt` | date-time string | Time when Threads published the post. |
| `engagement` | object, optional | Public engagement counts shown for the post. |
| `engagement.likeCount` | integer, optional | Public number of likes. |
| `engagement.replyCount` | integer, optional | Public number of replies. |
| `engagement.repostCount` | integer, optional | Public number of reposts. |
| `engagement.quoteCount` | integer, optional | Public number of quote posts. |
| `engagement.viewCount` | integer, optional | Public number of views when Threads shows it. |
| `media` | array of objects, optional | Image or video attachments shown in the post. |
| `media[].type` | string | Media type, either `image` or `video`. |
| `media[].url` | string (URI), optional | Direct source URL when Threads exposes one that users can open. |
| `media[].altText` | string, optional | Alternative text for the media item when available. |
| `media[].width` | integer, optional | Media width in pixels when available. |
| `media[].height` | integer, optional | Media height in pixels when available. |
| `media[].durationSeconds` | number, optional | Video duration in seconds when available. |
| `mentions` | array of objects, optional | Accounts mentioned in the post text. |
| `mentions[].username` | string | Mentioned public username. |
| `mentions[].id` | string, optional | Mentioned public account ID when available. |
| `hashtags` | array of strings, optional | Hashtags found in the post text. |
| `outboundLinks` | array of strings, optional | Links to other sites found in the post text. |
| `quotedPost` | object, optional | Public post quoted by this post when Threads provides the link. |
| `quotedPost.postId` | string | Stable ID of the quoted post. |
| `quotedPost.postUrl` | string (URI) | Public URL of the quoted post. |
| `repostedPost` | object, optional | Public post reposted by this post when Threads provides the link. |
| `repostedPost.postId` | string | Stable ID of the reposted post. |
| `repostedPost.postUrl` | string (URI) | Public URL of the reposted post. |
| `conversation` | object, optional | Source and parent links when this row is a reply. |
| `conversation.rootPostId` | string | Stable ID of the first post in the conversation. |
| `conversation.rootPostUrl` | string (URI) | Public URL of the first post in the conversation. |
| `conversation.parentPostId` | string | Stable ID of the post this reply directly answers. |
| `conversation.parentPostUrl` | string (URI) | Public URL of the post this reply directly answers. |
| `replies` | array of objects, optional | Public replies embedded on a targeted post page. |
| `replies[].postId` | string | Stable public ID of the reply. |
| `replies[].postUrl` | string (URI) | Public URL for the reply. |
| `replies[].text` | string, optional | Text shown in the reply. Omitted when the reply has no text. |
| `replies[].author` | object | Public author details for the reply. |
| `replies[].author.id` | string | Stable public ID of the reply author. |
| `replies[].author.username` | string | Public Threads username of the reply author. |
| `replies[].author.displayName` | string, optional | Public display name when shown. |
| `replies[].author.isVerified` | boolean, optional | Whether Threads marks the reply author as verified. |
| `replies[].publishedAt` | date-time string | Time when Threads published the reply. |
| `replies[].engagement` | object, optional | Public engagement counts shown for the reply. |
| `replies[].engagement.likeCount` | integer, optional | Public number of likes on the reply. |
| `replies[].engagement.replyCount` | integer, optional | Public number of replies to the reply. |
| `replies[].engagement.repostCount` | integer, optional | Public number of reposts of the reply. |
| `replies[].engagement.quoteCount` | integer, optional | Public number of quote posts for the reply. |
| `replies[].engagement.viewCount` | integer, optional | Public number of views for the reply when Threads shows it. |
| `replies[].media` | array of objects, optional | Image or video attachments shown in the reply. |
| `replies[].media[].type` | string | Reply media type, either `image` or `video`. |
| `replies[].media[].url` | string (URI), optional | Direct reply media URL when Threads exposes one that users can open. |
| `replies[].media[].altText` | string, optional | Alternative text for the reply media when available. |
| `replies[].media[].width` | integer, optional | Reply media width in pixels when available. |
| `replies[].media[].height` | integer, optional | Reply media height in pixels when available. |
| `replies[].media[].durationSeconds` | number, optional | Reply video duration in seconds when available. |
| `replies[].mentions` | array of objects, optional | Accounts mentioned in the reply text. |
| `replies[].mentions[].username` | string | Mentioned username in the reply. |
| `replies[].mentions[].id` | string, optional | Mentioned public account ID when available. |
| `replies[].hashtags` | array of strings, optional | Hashtags found in the reply text. |
| `replies[].outboundLinks` | array of strings, optional | Links to other sites found in the reply text. |
| `replies[].conversation` | object | Source and parent links for the reply. |
| `replies[].conversation.rootPostId` | string | Stable ID of the first post in the reply conversation. |
| `replies[].conversation.rootPostUrl` | string (URI) | Public URL of the first post in the reply conversation. |
| `replies[].conversation.parentPostId` | string | Stable ID of the post this reply directly answers. |
| `replies[].conversation.parentPostUrl` | string (URI) | Public URL of the post this reply directly answers. |
| `replies[].quotedPost` | object, optional | Public post quoted by the reply when Threads provides the link. |
| `replies[].quotedPost.postId` | string | Stable ID of the post quoted by the reply. |
| `replies[].quotedPost.postUrl` | string (URI) | Public URL of the post quoted by the reply. |
| `replies[].repostedPost` | object, optional | Public post reposted by the reply when Threads provides the link. |
| `replies[].repostedPost.postId` | string | Stable ID of the post reposted by the reply. |
| `replies[].repostedPost.postUrl` | string (URI) | Public URL of the post reposted by the reply. |
| `source` | object | Selected public fields returned by Threads when detailed source data is requested. |
| `source.id` | string | Source identifier for the post. |
| `source.code` | string, optional | Short code Threads uses for the post when available. |
| `source.canonicalUrl` | string (URI), optional | Canonical post URL supplied by Threads when available. |
| `source.caption` | string, optional | Post text supplied by Threads when available. |
| `source.takenAt` | number | Publication time as a Unix timestamp in seconds. |
| `source.user` | object | Author object supplied by Threads. |
| `source.user.id` | string | Source identifier for the author. |
| `source.user.username` | string | Source username for the author. |
| `source.user.fullName` | string, optional | Full name supplied by Threads when shown. |
| `source.user.isVerified` | boolean, optional | Whether Threads marks the source author as verified. |
| `source.likeCount` | integer, optional | Public like count supplied by Threads when available. |
| `source.replyCount` | integer, optional | Public reply count supplied by Threads when available. |
| `source.repostCount` | integer, optional | Public repost count supplied by Threads when available. |
| `source.quoteCount` | integer, optional | Public quote count supplied by Threads when available. |
| `source.viewCount` | integer, optional | Public view count supplied by Threads when available. |
| `source.media` | array of objects, optional | Selected media fields supplied by Threads for the post. |
| `source.media[].type` | string | Source media type, either `image` or `video`. |
| `source.media[].url` | string (URI), optional | Direct source media URL when available. |
| `source.media[].altText` | string, optional | Alternative text supplied by Threads when available. |
| `source.media[].width` | integer, optional | Source media width in pixels when available. |
| `source.media[].height` | integer, optional | Source media height in pixels when available. |
| `source.media[].durationSeconds` | number, optional | Source video duration in seconds when available. |

**Example detailed row**

This is a genuine row from a successful run with detailed source data turned on.

```json
{
  "postId": "3954859909900432925_40976579231",
  "postUrl": "https://www.threads.com/@anilbhawsar2963/post/DbifCJiDHYd",
  "author": {
    "id": "40976579231",
    "username": "anilbhawsar2963",
    "displayName": "Anil Bhawsar Jirafe",
    "isVerified": false
  },
  "publishedAt": "2026-08-02T13:07:41.000Z",
  "engagement": {
    "likeCount": 0,
    "replyCount": 0,
    "repostCount": 0,
    "quoteCount": 0
  },
  "media": [
    {
      "type": "video",
      "url": "https://media4.giphy.com/media/v1.Y2lkPWFlZWNjYzExdm8zcjFodzJrOWYyNjg0Y3M0bTNhNWlmNWNmanI2MTFnNHVmMTQ5NiZlcD12MV9naWZzX2dpZklkJmN0PWc/9nUtl7JLuXeg/200.gif",
      "altText": "Lady GIF",
      "width": 266,
      "height": 200
    }
  ],
  "conversation": {
    "rootPostId": "3932980370346228618_39283617667",
    "rootPostUrl": "https://www.threads.com/@snjuuu_p79/post/DaUwM8bEjuK",
    "parentPostId": "3932980370346228618_39283617667",
    "parentPostUrl": "https://www.threads.com/@snjuuu_p79/post/DaUwM8bEjuK"
  },
  "source": {
    "id": "3954859909900432925_40976579231",
    "takenAt": 1785676061,
    "user": {
      "id": "40976579231",
      "username": "anilbhawsar2963",
      "fullName": "Anil Bhawsar Jirafe",
      "isVerified": false
    },
    "code": "DbifCJiDHYd",
    "canonicalUrl": "https://www.threads.com/@anilbhawsar2963/post/DbifCJiDHYd",
    "likeCount": 0,
    "replyCount": 0,
    "repostCount": 0,
    "quoteCount": 0,
    "media": [
      {
        "type": "video",
        "url": "https://media4.giphy.com/media/v1.Y2lkPWFlZWNjYzExdm8zcjFodzJrOWYyNjg0Y3M0bTNhNWlmNWNmanI2MTFnNHVmMTQ5NiZlcD12MV9naWZzX2dpZklkJmN0PWc/9nUtl7JLuXeg/200.gif",
        "altText": "Lady GIF",
        "width": 266,
        "height": 200
      }
    ]
  }
}
```

#### 💳 Pricing

**Charged event**

`Post` charges for one public Threads post saved to the dataset. The event applies to a successful post returned by the Actor.

**How charging works**

The Actor charges once for each public post it returns. A run that returns no post does not trigger this post event. Set `Maximum posts` to keep a run and its charge count focused, or leave it empty to collect all available results until the source is exhausted.

#### 🔌 Integrations

**Dataset and API**

Read the results through the standard Apify dataset and API output. You can export the saved rows or connect them to a workflow from the run output.

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

#### ❓ FAQ

##### What happens when I submit several keywords or hashtags?

The Actor searches every submitted value with one shared sort, date, author, and maximum-post setting. Use separate runs when each search needs different filters or limits.

##### Can I look up a post by URL or numeric ID?

Yes. Choose `Post URL or ID` and enter one or more public Threads URLs or numeric post IDs. Search sorting, date, and author filters do not apply to direct lookups.

##### Can I search private Threads posts?

No. The Actor covers the public search and public post-page surface only. It does not require a buyer-supplied Threads credential for that public data.

##### Will it collect every reply in a conversation?

It can include public replies embedded on a targeted post page. It does not promise a full reply tree or nested replies that the public page does not show.

##### What if Threads does not show a field?

That field is omitted from the row when it is optional and unavailable. For example, post text, media details, view counts, and engagement counts depend on what Threads exposes.

##### What does detailed source data add?

Set `includeSourceData` to `true` to add selected source-level fields such as the source ID, short code, canonical URL, caption, Unix publication time, source author, counts, and media data alongside the normalized fields.

##### How can I keep a run smaller?

Set `Maximum posts` to a positive number. For keyword and hashtag searches, you can also use a date range, a recent-days window, or an author filter. Leaving the limit empty returns all available results until the source is exhausted.

### 📝 Changelog

**v0.0**

- Initial release

### 🆘 Support

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

### 🔗 Related Actors

- **[Threads Replies Scraper](https://apify.com/maximedupre/scrape-threads-replies)**: Collect public replies from Threads post or profile URLs with conversation context.
- **[Threads Video Downloader](https://apify.com/maximedupre/threads-video-downloader)**: Get direct source video links and available details from public Threads post URLs.
- **[Social Media Stats Checker](https://apify.com/maximedupre/social-media-stats-checker)**: Check public Threads profile stats alongside other supported social profiles.
- **[Threads Search Post Scraper](https://apify.com/trantus/threads-search-post-scraper)**: Search public Threads results with text, dates, authors, and engagement data for research and monitoring.
- **[🧵 Threads Search Post Scraper: Posts, Quotes & Replies](https://apify.com/scraper-engine/threads-search-post-scraper)**: Review public Threads posts with quote and reply context for conversation research.

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

# Actor input Schema

## `findPostsBy` (type: `string`):

Choose how to find public Threads posts. Keyword and Hashtag searches accept lists. Post URL or ID looks up the submitted posts.

## `keywords` (type: `array`):

Use this field when Find posts by is Keyword. Enter one or more words or phrases to search. The same sort and post limit apply to all submitted keywords. Values in the other choice sections are ignored.

## `hashtags` (type: `array`):

Use this field when Find posts by is Hashtag. Enter one or more hashtags with or without the # sign. The same sort and post limit apply to all submitted hashtags. Values in the other choice sections are ignored.

## `postTargets` (type: `array`):

Use this field when Find posts by is Post URL or ID. Enter one or more public Threads post URLs or numeric post IDs. All submitted posts use the same post limit and output setting. Values in the other choice sections are ignored.

## `sortOrder` (type: `string`):

For Keyword and Hashtag, choose Recent first or Relevance or top. Post URL or ID ignores this field.

## `publicationDate` (type: `object`):

For Keyword and Hashtag, narrow returned posts by publication time. Use From and To for a UTC calendar date range, or use Recent days for a recent window. Post URL or ID ignores this field.

## `author` (type: `string`):

For Keyword and Hashtag, narrow returned posts to a public Threads author. Enter the username with or without @. Post URL or ID ignores this field.

## `maxItems` (type: `integer`):

Optional limit for the run. Stop after this many returned posts. Leave it empty to return all available results until the source is exhausted.

## `includeSourceData` (type: `boolean`):

Add the detailed source-level fields alongside the normalized post data. Normalized public post data is always returned.

## Actor input object example

```json
{
  "findPostsBy": "keyword",
  "keywords": [
    "OpenAI"
  ],
  "sortOrder": "recent",
  "maxItems": 1,
  "includeSourceData": false
}
```

# Actor output Schema

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

A dataset of successful public Threads post rows.

# 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 = {
    "findPostsBy": "keyword",
    "maxItems": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/threads-search-post-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 = {
    "findPostsBy": "keyword",
    "maxItems": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/threads-search-post-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 '{
  "findPostsBy": "keyword",
  "maxItems": 1
}' |
apify call maximedupre/threads-search-post-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/threads-search-post-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/IPDYJUCQgKtfJ80L9/builds/70i19YnsgqbEBNWwQ/openapi.json
