# 🐘 Mastodon Scraper — Any Instance: Profiles, Toots, Followers (`nominated_tupelo/mastodon-fediverse-scraper`) Actor

🐘 Scrape public Mastodon data across any instance via the official REST API — profiles, toots, boosts, followers, and search. No auth required. For researchers and data teams.

- **URL**: https://apify.com/nominated\_tupelo/mastodon-fediverse-scraper.md
- **Developed by:** [kade](https://apify.com/nominated_tupelo) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

### What does Mastodon Scraper do?

**Mastodon Scraper** extracts public data from [Mastodon](https://joinmastodon.org/) and any Fediverse instance compatible with the Mastodon API. Give it a list of handles, a search query, or a specific account, and it returns structured profile data, posts (toots), followers, and following lists — **no authentication or API key required**.

Works with mastodon.social, fosstodon.org, hachyderm.io, infosec.exchange, and any of the 10,000+ Mastodon instances in the Fediverse.

### Why use Mastodon Scraper?

- **No auth needed** — Mastodon's public REST API is open for public content by design
- **Federated coverage** — scrape any instance, not just mastodon.social. Track niche communities like tech, science, or activism instances
- **Multi-handle batch scraping** — pass hundreds of handles at once, paginated automatically
- **Cross-instance followers** — fetch follower graphs that span multiple servers
- **Clean structured output** — profiles with engagement stats, posts with boost/favourite counts, tags, and language detection
- **Scheduling** — run weekly to track follower growth, post frequency, and engagement trends over time
- **Use cases**: influencer research, academic analysis, brand monitoring, developer community tracking, community mapping

### How to use Mastodon Scraper

1. Open the **Input** tab and choose what you want to scrape:
   - **Handles**: paste Mastodon handles like `gargron@mastodon.social` or `user@fosstodon.org`
   - **Search query**: find accounts by keyword on any instance
2. Choose a **Scrape mode**: Profile only, Posts only, Profile + Posts, Followers, or Following
3. Set **Instance** (default: `mastodon.social`) for handles without an explicit `@instance`
4. Set **Max posts** and **Max followers** limits to control run time and cost
5. Click **Start** and download results from the **Output** tab as JSON, CSV, or Excel

### Input

| Field | Type | Description |
|---|---|---|
| handles | string[] | Mastodon handles, e.g. `["gargron@mastodon.social", "user@fosstodon.org"]` |
| instance | string | Default instance for handles without @instance (default: `mastodon.social`) |
| searchQuery | string | Search for accounts by keyword on the default instance |
| scrapeMode | string | `profile`, `posts`, `profile_and_posts`, `followers`, `following` |
| maxPostsPerProfile | integer | Max posts per account (default: 100) |
| maxFollowers | integer | Max followers/following per handle (default: 500) |
| maxItems | integer | Hard cap on total output items. 0 = no limit |

### Output

Each item is a **profile**, **post**, **follower**, or **following** record.

#### Profile example
```json
{
  "type": "profile",
  "username": "Mastodon",
  "acct": "Mastodon@mastodon.social",
  "instance": "mastodon.social",
  "display_name": "Mastodon",
  "note": "Free, open-source decentralized social media platform.",
  "followers_count": 873588,
  "following_count": 3,
  "statuses_count": 2847,
  "bot": false,
  "created_at": "2016-11-23T00:00:00.000Z",
  "url": "https://mastodon.social/@Mastodon"
}
````

#### Post example

```json
{
  "type": "post",
  "author_acct": "gargron@mastodon.social",
  "content": "Just released Mastodon 4.3 with major performance improvements...",
  "created_at": "2024-11-15T09:30:00.000Z",
  "language": "en",
  "replies_count": 42,
  "reblogs_count": 218,
  "favourites_count": 891,
  "tags": ["mastodon", "fediverse"],
  "url": "https://mastodon.social/@Gargron/123456789"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

### Data fields

| Field | Type | Description |
|---|---|---|
| type | string | `profile`, `post`, `follower`, or `following` |
| username | string | Local username (no instance suffix) |
| acct | string | Full federated handle (user@instance) |
| instance | string | Mastodon instance hostname |
| display\_name | string | Display name |
| note | string | Bio / profile description (HTML stripped) |
| followers\_count | number | Follower count |
| statuses\_count | number | Total posts (toots) |
| content | string | Post text content (HTML stripped) |
| reblogs\_count | number | Number of boosts |
| favourites\_count | number | Number of favourites/likes |
| replies\_count | number | Number of replies |
| tags | string\[] | Hashtags in the post |
| language | string | Detected language code |
| created\_at | string | Timestamp (ISO 8601) |
| url | string | Direct link to profile or post |

### Pricing / Cost estimation

This Actor uses **pay-per-event** pricing — you only pay for what you scrape.

- Scraping 100 profiles: ~$0.05
- Scraping 1,000 posts from 10 accounts: ~$0.10
- Fetching 5,000 followers: ~$0.25

The free tier includes enough compute units to evaluate the Actor before committing.

### Tips

- Use `user@instance` format in handles to scrape accounts from any Fediverse server
- Set `maxItems` to control total cost on large accounts or broad searches
- For follower graph analysis, combine `scrapeMode: followers` with multiple handles
- The `fields` output contains pinned profile links and custom metadata set by the account owner
- Mastodon rate limits are generous on public endpoints; the Actor includes automatic delays

### FAQ and support

**Is this legal?** This Actor only accesses publicly available data via Mastodon's official public REST API. No authentication is bypassed. Always comply with individual instance rules and applicable data protection laws (GDPR, etc.).

**Does it work on non-Mastodon Fediverse instances?** It works on any instance running Mastodon-compatible API (Pleroma, Akkoma, Glitch-soc, etc.). Misskey/Calckey use a different API and are not supported.

**Some accounts have fewer followers than expected.** Some instances hide follower lists. In that case, the API returns an empty list, which is expected behavior.

Found a bug or need a feature? Open an issue in the **Issues** tab. Custom data extraction across specific Fediverse networks is available on request.

# Actor input Schema

## `handles` (type: `array`):

List of Mastodon handles. Format: 'user@instance.social' or just 'user' (uses the instance field). E.g. 'Mastodon@mastodon.social'.

## `instance` (type: `string`):

Default instance URL for handles that don't include @instance. E.g. 'mastodon.social' or 'fosstodon.org'.

## `searchQuery` (type: `string`):

Search for Mastodon accounts matching this keyword. Results come from the default instance.

## `scrapeMode` (type: `string`):

What data to collect per handle.

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

Maximum posts to fetch per account (scrapeMode: posts or profile\_and\_posts).

## `maxFollowers` (type: `integer`):

Maximum followers or following accounts to fetch per handle.

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

Hard cap on total dataset output. 0 = no limit.

## Actor input object example

```json
{
  "handles": [
    "Mastodon@mastodon.social",
    "gargron@mastodon.social"
  ],
  "instance": "mastodon.social",
  "scrapeMode": "profile_and_posts",
  "maxPostsPerProfile": 100,
  "maxFollowers": 500,
  "maxItems": 0
}
```

# Actor output Schema

## `dataset` (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 = {
    "handles": [
        "Mastodon@mastodon.social",
        "gargron@mastodon.social"
    ],
    "instance": "mastodon.social"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nominated_tupelo/mastodon-fediverse-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 = {
    "handles": [
        "Mastodon@mastodon.social",
        "gargron@mastodon.social",
    ],
    "instance": "mastodon.social",
}

# Run the Actor and wait for it to finish
run = client.actor("nominated_tupelo/mastodon-fediverse-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 '{
  "handles": [
    "Mastodon@mastodon.social",
    "gargron@mastodon.social"
  ],
  "instance": "mastodon.social"
}' |
apify call nominated_tupelo/mastodon-fediverse-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "🐘 Mastodon Scraper — Any Instance: Profiles, Toots, Followers",
        "description": "🐘 Scrape public Mastodon data across any instance via the official REST API — profiles, toots, boosts, followers, and search. No auth required. For researchers and data teams.",
        "version": "0.1",
        "x-build-id": "MSwwNRsqZyzqoL1Yb"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/nominated_tupelo~mastodon-fediverse-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-nominated_tupelo-mastodon-fediverse-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/nominated_tupelo~mastodon-fediverse-scraper/runs": {
            "post": {
                "operationId": "runs-sync-nominated_tupelo-mastodon-fediverse-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/nominated_tupelo~mastodon-fediverse-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-nominated_tupelo-mastodon-fediverse-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "handles": {
                        "title": "Mastodon handles to scrape",
                        "type": "array",
                        "description": "List of Mastodon handles. Format: 'user@instance.social' or just 'user' (uses the instance field). E.g. 'Mastodon@mastodon.social'.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "instance": {
                        "title": "Default Mastodon instance",
                        "type": "string",
                        "description": "Default instance URL for handles that don't include @instance. E.g. 'mastodon.social' or 'fosstodon.org'.",
                        "default": "mastodon.social"
                    },
                    "searchQuery": {
                        "title": "Search query",
                        "type": "string",
                        "description": "Search for Mastodon accounts matching this keyword. Results come from the default instance."
                    },
                    "scrapeMode": {
                        "title": "What to scrape",
                        "enum": [
                            "profile",
                            "posts",
                            "profile_and_posts",
                            "followers",
                            "following"
                        ],
                        "type": "string",
                        "description": "What data to collect per handle.",
                        "default": "profile_and_posts"
                    },
                    "maxPostsPerProfile": {
                        "title": "Max posts per profile",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum posts to fetch per account (scrapeMode: posts or profile_and_posts).",
                        "default": 100
                    },
                    "maxFollowers": {
                        "title": "Max followers/following",
                        "minimum": 1,
                        "maximum": 50000,
                        "type": "integer",
                        "description": "Maximum followers or following accounts to fetch per handle.",
                        "default": 500
                    },
                    "maxItems": {
                        "title": "Max total items",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Hard cap on total dataset output. 0 = no limit.",
                        "default": 0
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
