# Mastodon Posts & Profiles Scraper (`fetch_cat/mastodon-posts-profiles-scraper`) Actor

Scrape public Mastodon posts, profiles, hashtags, timelines, and status details from Fediverse instances.

- **URL**: https://apify.com/fetch\_cat/mastodon-posts-profiles-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (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.03 / 1,000 status extracteds

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/platform/actors/running/actors-in-store#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

## Mastodon Posts & Profiles Scraper

Scrape public Mastodon posts, hashtags, account timelines, public timelines, and status details from Fediverse instances.

Use this Actor when you need repeatable Mastodon data for social listening, open-web research, community monitoring, news tracking, creator research, or AI analysis. Results can be downloaded as CSV, JSON, Excel, XML, RSS, or used through the Apify Dataset API.

### At a glance

- **Instance-based scraping**: choose a Mastodon instance such as `https://mastodon.social` or `https://fosstodon.org`.
- **Multiple scrape modes**: collect hashtag timelines, public timelines, account posts, or one status.
- **Post metadata**: save URLs, content, language, visibility, reply/reblog/favorite counts, tags, mentions, media attachments, and account data.
- **Monitoring controls**: use `sinceId`, `minId`, and `maxId` for incremental collection where supported.
- **Fediverse workflow ready**: export rows to alerts, dashboards, social listening systems, or AI agents.

### Ready-to-run examples

Use these saved Store examples as starting points. Open any example to prefill the Actor input, then adjust URLs, keywords, limits, or filters for your own run.

- **[Extract one public Mastodon status by URL or ID](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-single-status-lookup)**
- **[Monitor tech posts on Mastodon](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-tech-community-monitoring)**
- **[Scrape Mastodon climate hashtag posts](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-climate-hashtag-research)**
- **[Scrape a Mastodon federated public timeline](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-federated-public-timeline)**
- **[Scrape a Mastodon local public timeline](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-local-public-timeline)**
- **[Scrape media posts from a Mastodon profile](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples/mastodon-account-media-posts)**
- **[View all ready-to-run examples](https://apify.com/fetch_cat/mastodon-posts-profiles-scraper/examples)** (10 examples)

### What can it do?

Mastodon Posts & Profiles Scraper turns public Mastodon timelines and statuses into structured social-media rows.

- **Export Mastodon posts and status data** from hashtags, public timelines, account timelines, and individual statuses.
- **Collect engagement and account context** such as replies, reblogs, favorites, account fields, tags, mentions, media, cards, and visibility.
- **Monitor Fediverse conversations** by scheduling hashtag or account runs and using ID-based continuation fields.
- **Research communities and topics** across public Mastodon instances without a login.
- **Use it as a Mastodon data API workflow** for CSV, JSON, Excel, API, or AI-agent exports.

### Common workflows

- **Social listening**: monitor public Mastodon hashtags and accounts for brands, events, topics, or issues.
- **News and community tracking**: watch public timelines on relevant instances.
- **Creator research**: collect public account posts and engagement signals.
- **Open-web research**: export public Fediverse discussion data for analysis.
- **AI summaries**: pass status rows into classification, sentiment, clustering, or alerting workflows.

### What data can you collect?

Each dataset row represents one public Mastodon status.

| Field | Description |
| --- | --- |
| `statusId` | Mastodon status ID |
| `url` | Public status URL |
| `uri` | Fediverse URI |
| `instanceBaseUrl` | Instance used for the request |
| `scrapeMode` | Mode used for the row |
| `createdAt` | Public creation timestamp |
| `editedAt` | Edit timestamp when available |
| `contentText` | Cleaned post text |
| `contentHtml` | Public HTML content |
| `language` | Language code when returned |
| `visibility` | Status visibility value |
| `sensitive` | Whether the status is marked sensitive |
| `spoilerText` | Content warning text when present |
| `repliesCount` | Reply count |
| `reblogsCount` | Reblog/boost count |
| `favouritesCount` | Favorite count |
| `account` | Public account object |
| `tags` | Public hashtag objects |
| `mentions` | Mentioned accounts |
| `mediaAttachments` | Public media attachment metadata |
| `card` | Link preview card when available |
| `poll` | Poll data when available |
| `scrapedAt` | Timestamp when the row was saved |

### Pricing

This Actor uses Apify pay-per-event pricing. The prices below come from the current Actor pricing configuration. Apify public plans map to Store discount tiers, so the table shows both the user-facing plan context and the pricing tier name. The final price shown in Apify depends on the user account plan and any custom agreement.

| Event | What is charged | Price |
| --- | --- | ---: |
| `start` | One-time fee charged when a run starts. Covers fixed startup cost. | $0.005 |
| `item` | Charged for each saved status extracted. | $0.000032396 on Free; $0.000028170 on Starter / Bronze; $0.000021973 on Scale / Silver; $0.000016902 on Business / Gold; $0.000011268 on Platinum; $0.000007888 on Diamond |

Apify may also charge platform usage for compute, storage, proxies, or data transfer outside this Actor pricing. Check the Actor run and the Apify Pricing tab for the exact cost shown to your account.

### Input configuration

| Setting | JSON key | Use it for | Example |
| --- | --- | --- | --- |
| Instance base URL | `instanceBaseUrl` | Mastodon instance to query. | `https://mastodon.social` |
| Scrape mode | `mode` | Hashtag, account, public timeline, or status mode. | `hashtag` |
| Hashtag | `hashtag` | Hashtag for hashtag mode. | `news` |
| Account ID or handle | `accountIdOrHandle` | Account for account-post mode. | `Gargron@mastodon.social` |
| Status URL or ID | `statusUrlOrId` | Status for single-status mode. | `https://mastodon.social/@account/123` |
| Maximum statuses | `maxItems` | Maximum saved status rows. | `50` |
| Public timeline: local only | `local` | Only return statuses from selected instance. | `false` |
| Public timeline: remote only | `remote` | Only return remote federated statuses. | `false` |
| Account posts: only media | `onlyMedia` | Keep account statuses with media attachments only. | `false` |
| Account posts: exclude replies | `excludeReplies` | Skip replies in account mode. | `false` |
| Account posts: exclude boosts | `excludeReblogs` | Skip boosts/reblogs in account mode. | `false` |
| Since ID | `sinceId` | Return statuses newer than this ID where supported. | `116838156372364425` |
| Minimum ID | `minId` | Return statuses immediately newer than this ID. | `116838156372364425` |
| Maximum ID | `maxId` | Return statuses older than this ID. | `116838156372364425` |

### Example input

```json
{
  "instanceBaseUrl": "https://mastodon.social",
  "mode": "hashtag",
  "hashtag": "news",
  "maxItems": 50,
  "local": false,
  "excludeReplies": false,
  "excludeReblogs": false
}
```

### Example output

```json
{
  "statusId": "116838156372364425",
  "url": "https://example.social/@account/116838156372364425",
  "instanceBaseUrl": "https://mastodon.social",
  "scrapeMode": "hashtag",
  "createdAt": "2026-06-30T08:00:00.000Z",
  "contentText": "Example public Mastodon post text",
  "language": "en",
  "visibility": "public",
  "repliesCount": 2,
  "reblogsCount": 4,
  "favouritesCount": 10,
  "account": {
    "acct": "account@example.social",
    "displayName": "Example Account",
    "url": "https://example.social/@account"
  },
  "tags": [],
  "mentions": [],
  "mediaAttachments": []
}
```

### Tips for best results

- **Choose the right instance**: Mastodon data is instance-based, so the same account or hashtag may differ by instance.
- **Use hashtag mode for monitoring**: it is the easiest recurring social-listening setup.
- **Use account mode for creator research**: combine `excludeReplies` and `excludeReblogs` for original posts.
- **Use ID cursors for incremental runs**: store `statusId` values when you need continuation.
- **Keep first runs small**: test `maxItems=20` before scaling a new instance or mode.

### Limits and caveats

- The Actor extracts publicly visible Mastodon data only.
- It does not access private, followers-only, deleted, or login-gated content.
- Availability and fields vary by Fediverse instance and Mastodon-compatible server version.
- Some instances require a login for filtered public timelines such as `local` or `remote`; the Actor reports that restriction as a clear failed run rather than returning misleading empty data.
- Engagement counts can change after scraping.

### API usage

#### Node.js

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/mastodon-posts-profiles-scraper').call({
  instanceBaseUrl: 'https://mastodon.social', mode: 'hashtag', hashtag: 'news', maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_APIFY_TOKEN')
run = client.actor('fetch_cat/mastodon-posts-profiles-scraper').call(run_input={
    'instanceBaseUrl': 'https://mastodon.social', 'mode': 'hashtag', 'hashtag': 'news', 'maxItems': 50,
})
print(list(client.dataset(run['defaultDatasetId']).iterate_items()))
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/fetch_cat~mastodon-posts-profiles-scraper/runs?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"instanceBaseUrl":"https://mastodon.social","mode":"hashtag","hashtag":"news","maxItems":50}'
```

### MCP and AI agents

This Actor can be used through the official Apify MCP server at `https://mcp.apify.com`.

For a focused single-Actor tool setup, use:

```text
https://mcp.apify.com?tools=fetch_cat/mastodon-posts-profiles-scraper
```

Use the same JSON keys shown in the input configuration table, such as `instanceBaseUrl`, `mode`, `hashtag`, `accountIdOrHandle`, `statusUrlOrId`, `maxItems`, and `sinceId`.

For Claude Desktop or another MCP client, add this server configuration and replace the token value:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/mastodon-posts-profiles-scraper",
      "headers": { "Authorization": "Bearer YOUR_APIFY_TOKEN" }
    }
  }
}
```

For Claude Code, set `APIFY_TOKEN` in your shell and run:

```bash
claude mcp add --transport http apify 'https://mcp.apify.com?tools=fetch_cat/mastodon-posts-profiles-scraper' --header "Authorization: Bearer $APIFY_TOKEN"
```

Example prompt: “Collect the latest 25 public `opensource` posts from mastodon.social and return the post URL, account, timestamp, text, and engagement counts.”

### FAQ

#### Can this scrape any Mastodon instance?

It works with public Mastodon-compatible instances that expose the needed public endpoints.

#### Can it collect private or followers-only posts?

No. It only collects public data.

#### Can I export to CSV or Excel?

Yes. Apify datasets can be downloaded as CSV, JSON, Excel, XML, RSS, HTML, or accessed through the API.

### Related actors

- [Threads Profile & Posts Scraper](https://apify.com/fetch_cat/threads-profile-posts-scraper)
- [Bluesky Profile Feed Scraper](https://apify.com/fetch_cat/bluesky-profile-feed-scraper)
- [Reddit Scraper](https://apify.com/fetch_cat/reddit-scraper)
- [Telegram Channel Posts Scraper](https://apify.com/fetch_cat/telegram-channel-posts-scraper)
- [Google News Scraper](https://apify.com/fetch_cat/google-news-scraper)

### Support

If a run fails, returns no data, or a field looks wrong, open an issue from the Actor page.

Please include the Apify run ID or run URL, input JSON, one example public URL, query, or input item, what you expected, and what the dataset returned. Small reproducible inputs make parsing or site-layout issues much faster to fix.

### Privacy and data handling

This Actor runs with Apify limited permissions and only processes data needed for the documented run. It uses content lookup inputs and public posts, profiles, videos, comments, or channel metadata needed for the requested output to produce the output dataset and sends requests to public Mastodon Posts Profiles pages/endpoints; results are stored in Apify run storage for your account. FetchCat does not use your inputs or outputs for advertising, does not use them for model training, and does not retain them outside the Apify run except for transient support debugging when you explicitly share run details. You are responsible for using the Actor lawfully, respecting the target site's terms, and avoiding unnecessary personal or sensitive data in inputs.

# Actor input Schema

## `instanceBaseUrl` (type: `string`):

Mastodon instance to query, for example https://mastodon.social or https://fosstodon.org.

## `mode` (type: `string`):

What public Mastodon data should be collected.

## `hashtag` (type: `string`):

Hashtag to scrape in hashtag mode. Use news or #news format.

## `accountIdOrHandle` (type: `string`):

Numeric account ID or public acct handle for account post mode, for example Gargron or Gargron@mastodon.social.

## `statusUrlOrId` (type: `string`):

Local status ID or same-instance status URL for single status mode.

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

Maximum number of statuses to save. Keep low for first tests, then increase for monitoring jobs.

## `local` (type: `boolean`):

Only return statuses originating on the selected instance when using public timeline mode.

## `remote` (type: `boolean`):

Only return remote statuses federated into the selected instance when using public timeline mode.

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

Only include account statuses with media attachments.

## `excludeReplies` (type: `boolean`):

Skip replies when collecting public account statuses.

## `excludeReblogs` (type: `boolean`):

Skip boosts/reblogs when collecting public account statuses.

## `sinceId` (type: `string`):

Return results newer than this Mastodon status ID when supported by the endpoint.

## `minId` (type: `string`):

Return results immediately newer than this Mastodon status ID.

## `maxId` (type: `string`):

Return results older than this Mastodon status ID.

## Actor input object example

```json
{
  "instanceBaseUrl": "https://mastodon.social",
  "mode": "hashtag",
  "hashtag": "news",
  "maxItems": 20,
  "local": false,
  "remote": false,
  "onlyMedia": false,
  "excludeReplies": false,
  "excludeReblogs": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `runSummary` (type: `string`):

No description

## `pendingWork` (type: `string`):

No description

# 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 = {
    "instanceBaseUrl": "https://mastodon.social",
    "mode": "hashtag",
    "hashtag": "news",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/mastodon-posts-profiles-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 = {
    "instanceBaseUrl": "https://mastodon.social",
    "mode": "hashtag",
    "hashtag": "news",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/mastodon-posts-profiles-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "instanceBaseUrl": "https://mastodon.social",
  "mode": "hashtag",
  "hashtag": "news",
  "maxItems": 20
}' |
apify call fetch_cat/mastodon-posts-profiles-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fetch_cat/mastodon-posts-profiles-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/EGyFQ5wm1EhDIBEsv/builds/eC278jkdBYZsy6zh8/openapi.json
