Mastodon Scraper · Posts, Accounts, Hashtags & Instances
Pricing
from $0.70 / 1,000 post returneds
Mastodon Scraper · Posts, Accounts, Hashtags & Instances
Mastodon scraper for fediverse posts, profiles, hashtags, and instance timelines. Extract public Mastodon statuses, user accounts, engagement metrics, media, and outbound links with no login required.
Pricing
from $0.70 / 1,000 post returneds
Rating
0.0
(0)
Developer
Tarek Etman
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
9 hours ago
Last modified
Categories
Share

Mastodon Scraper · Posts, Accounts, Hashtags & Instances
Mastodon scraper to scrape public posts, profiles, hashtags, and account feeds from any Mastodon fediverse instance (such as mastodon.social). Returns clean structured data per post: author details, follower counts, post text, engagement metrics, media, and outbound links.
Maintained by reapX. Every row cites the Apify run that produced it — nothing is inferred, modelled or filled in, and a field absent from the source is absent from the row. The extracted archive for this source is browsable at reapx.dev/data/mastodon-scraper/ and mirrored as an open dataset on Hugging Face and Kaggle. Questions: reapxdev@proton.me
No API key, token, app registration, or login required. This Mastodon scraper reads Mastodon's public REST API across any instance.
What you get per post
| Field | |
|---|---|
handle | the author as instance/username - unique across the whole fediverse |
accountAcct | the same author in Mastodon's native user@instance form |
accountDisplayName · accountFollowers · accountStatusCount · accountIsBot | who posted it |
content · spoilerText · language · visibility · isSensitive | the post |
favouritesCount · reblogsCount · repliesCount | engagement as the reading instance sees it |
hashtags · mentionCount · mediaCount · mediaTypes | what is in it |
linkUrl · linkTitle | where it points |
instanceDomain · sourceInstance · statusUrl · createdAt · retrievedAt |
A hashtag timeline is federated
Reading #rustlang on one instance returns posts from across the fediverse, not only from
that instance - a hashtag timeline is the cheapest wide view Mastodon offers. Set Only
posts from this instance if you want the narrow one instead.
Track a hashtag over time
Put your hashtags in, set Maximum posts high, and schedule the run. Every row carries
statusUrl and createdAt, so consecutive runs append cleanly and handle groups the
whole set by author.
Watch an instance's own community
Turn on Include the instance's public timeline with Only posts from this instance
and point it at fosstodon.org, hachyderm.io or any instance you care about. Note that
some instances - mastodon.social among them - require a logged-in user for their public
timeline; those are skipped with a note in the run status rather than failing the run, and
their hashtag and trending timelines still work.
Follow specific accounts
Put user@instance addresses in Accounts. Each is resolved on the instance you are
reading from and its public posts returned, with replies and boosts filtered out if you
want only original material.
Input configuration
Every field is optional. The prefilled values below are what runs if you press Start without changing anything.
Where to read
An instance's hashtag timeline is federated, so one instance sees posts from across the fediverse.
| Field | Type | Accepts | What it does |
|---|---|---|---|
instances | list | one value per line | Mastodon instance domains to read, one per line - mastodon.social, fosstodon.org, hachyderm.io, mstdn.social. Every source below is read on each instance and the results merged. Prefilled with ["mastodon.social"]. |
What to read
Give hashtags, accounts, the instance timeline, trending - or any combination.
| Field | Type | Accepts | What it does |
|---|---|---|---|
hashtags | list | one value per line | Hashtags to read, one per line, with or without the #. Each is fetched as its own timeline. Prefilled with ["photography"]. |
accounts | list | one value per line | Accounts whose public posts to read, one per line, as user@instance or a bare username for a local account. |
includePublicTimeline | true/false | checkbox | Read each instance's public timeline. Some instances, mastodon.social among them, require a logged-in user for this and are skipped with a note rather than failing the run. |
includeTrending | true/false | checkbox | Read what each instance is currently amplifying through its trends endpoint. |
Filters
All optional.
| Field | Type | Accepts | What it does |
|---|---|---|---|
localOnly | true/false | checkbox | Restrict hashtag and public timelines to posts written on the instance itself, excluding federated posts from elsewhere. |
onlyWithMedia | true/false | checkbox | Keep only posts carrying at least one image, video or audio attachment. |
excludeReplies | true/false | checkbox | Drop posts that reply to another post. |
excludeReblogs | true/false | checkbox | Drop boosts (reblogs) and keep only original posts. |
language | string | free text | Keep only posts the author tagged with this two-letter language code. |
minFavourites | integer | 0 to 1000000 | Keep only posts with at least this many favourites - the simplest way to skim the top of a busy hashtag. |
Output
How many rows you get and how politely they are fetched.
| Field | Type | Accepts | What it does |
|---|---|---|---|
maxPosts | integer | 1 to 5000 | Hard ceiling on the rows this run produces, and therefore on what it costs. You are charged per post returned. Prefilled with 100. |
requestsPerSecond | integer | 1 to 5 | Politeness against each instance. Mastodon instances are volunteer-run; keep this low. Prefilled with 2. |
Pricing
Pay per event. The primary event is Post returned (post-returned), charged at $0.001 per event on the free plan, falling to $0.0005 on the highest tier.
One public Mastodon post delivered as a complete row, including its author, engagement counts, hashtags and media. Blocked instances and empty result sets are never charged.
Other charged events: apify-actor-start (Actor Start).
Minimum charge cap per run: $0.05.
Tiered discounts apply automatically on every paid Apify plan. Platform usage is absorbed by the Actor, so the per-event price is the whole price.
Usage examples
The prefilled run, which is what Start does with nothing changed
{"instances": ["mastodon.social"],"hashtags": ["photography"],"maxPosts": 100,"requestsPerSecond": 2}
Filter by instances
{"instances": ["mastodon.social","fosstodon.org"],"hashtags": ["photography"],"maxPosts": 100,"requestsPerSecond": 2}
Filter by hashtags
{"instances": ["mastodon.social"],"hashtags": ["opensource","rustlang"],"maxPosts": 100,"requestsPerSecond": 2}
Filter by accounts
{"instances": ["mastodon.social"],"hashtags": ["photography"],"maxPosts": 100,"requestsPerSecond": 2,"accounts": ["Gargron@mastodon.social","torproject@mastodon.social"]}
Filter by include the instance's public timeline
{"instances": ["mastodon.social"],"hashtags": ["photography"],"maxPosts": 100,"requestsPerSecond": 2,"includePublicTimeline": true}
Output example
One row, exactly as the actor wrote it to the dataset:
{"handle": "mastodon.social/QasimRashid","accountAcct": "QasimRashid@mastodon.social","accountDisplayName": "Qasim Rashid, Esq.","accountUrl": "https://mastodon.social/@QasimRashid","accountFollowers": 92218,"accountFollowing": 106,"accountStatusCount": 4537,"accountIsBot": false,"accountCreatedAt": "2022-10-30T00:00:00.000Z","instanceDomain": "mastodon.social","sourceInstance": "fosstodon.org","statusId": "117029450607940916","statusUrl": "https://mastodon.social/@QasimRashid/117029450548542124","content": "Hey so the Trump regime unilaterally forced Haitian Americans into undocumented status, and is now using that undocumented status as an excuse to force them to wear ankle monitors. A reminder that the \"just follow the...","spoilerText": null,"createdAt": "2026-08-03T03:28:20.000Z","editedAt": null,"language": "en"}
That row carries 32 fields in total; 18 are shown.
Fields on every row
| Field | Type | What it is |
|---|---|---|
handle | string | The author's globally unique handle as instance/username. Unique across the whole fediverse, where a bare username is not, and stable across runs. |
accountAcct | string | The author in Mastodon's native user@instance form. |
accountDisplayName | string | The name the author shows on their profile. |
accountUrl | string | The author's public profile page. |
accountFollowers | integer | How many accounts follow the author, as their home instance reports it. |
accountFollowing | integer | How many accounts the author follows. |
accountStatusCount | integer | How many posts the author has published in total. |
accountIsBot | true/false | True when the account declares itself automated. |
accountCreatedAt | string | When the author's account was created. |
instanceDomain | string | The instance the author's account lives on. |
sourceInstance | string | The instance this run read the post through. Differs from the author's instance whenever a post arrived by federation. |
statusId | string | The post's id on the instance it was read from. |
statusUrl | string | The post's canonical public address on its author's instance. |
content | string | The post body reduced from HTML to readable text. |
spoilerText | string | The content warning the author put in front of the post, if any. |
createdAt | string | When the post was published, in UTC. |
editedAt | string | When the post was last edited, if it was. |
language | string | The two-letter language code the author tagged the post with. |
visibility | string | How widely the author published the post. |
isSensitive | true/false | True when the author flagged the post or its media as sensitive. |
isReply | true/false | True when the post replies to another post. |
isReblog | true/false | True when the post is a boost of someone else's post rather than original. |
repliesCount | integer | Replies the post has received, as the reading instance sees them. |
reblogsCount | integer | Boosts the post has received, as the reading instance sees them. |
favouritesCount | integer | Favourites the post has received, as the reading instance sees them. |
hashtags | list | Every hashtag the post carries. |
mentionCount | integer | How many accounts the post mentions. |
mediaCount | integer | How many images, videos or audio files the post carries. |
mediaTypes | list | The distinct kinds of media attached to the post. |
linkUrl | string | The URL of the link preview card the post generated, if it linked out. |
linkTitle | string | The title of the link preview card. |
retrievedAt | string | When this row was read, in UTC. |
3 named dataset views ship with it: Posts, Accounts, Engagement. They drive the Output tab in Console and the Output block on the Actor's .md page.
FAQ
Does it need a Mastodon account or an access token? No. Every endpoint it uses is public and unauthenticated.
Does it read private or followers-only posts? No. Only what the instance serves
publicly; visibility on every row says which it was.
Why does sourceInstance differ from instanceDomain? Because the post arrived by
federation: instanceDomain is where the author lives, sourceInstance is where this run
read it.
Are engagement counts exact? They are what the reading instance knows. Mastodon is federated, so a post's favourite count can differ slightly between instances. Reading the author's own instance gives the authoritative figure.
What is the stable identifier? handle. Instance and username together address one
account across the whole network, and it is the right key to join runs together over time.
Unofficial - not affiliated with Mastodon gGmbH or any instance operator. Collects public data only. reapx. Contact reapxdev@proton.me.
The full published archive
- mastodon scraper archive — every entity this Actor has observed
- All reapx datasets — 20 sources, tens of thousands of pages
- llms.txt · feed.json · feed.xml — the machine-readable index, for agents
Each archive page carries Dataset JSON-LD, a canonical URL and the identifiers used, so an agent can resolve an entity without running anything. Nothing on those pages is estimated or modelled.
🧪 Example input
A real, runnable configuration — this is an actual input this Actor has run with.
{"instances": ["chaos.social"],"includePublicTimeline": true,"localOnly": true,"maxPosts": 500,"requestsPerSecond": 2}
📄 Sample output
One real row from a real run of this Actor, unedited.
{"handle": "chaos.social/weizenspreu","accountAcct": "weizenspreu@chaos.social","accountDisplayName": "Kenny","accountUrl": "https://chaos.social/@weizenspreu","accountFollowers": 408,"accountFollowing": 232,"accountStatusCount": 926,"accountIsBot": false,"accountCreatedAt": "2025-10-13T00:00:00.000Z","instanceDomain": "chaos.social","sourceInstance": "chaos.social","statusId": "117031265960004228","statusUrl": "https://chaos.social/@weizenspreu/117031265960004228","content": "✅ Studienarbeit eingereicht","spoilerText": null,"createdAt": "2026-08-03T11:10:01.001Z","editedAt": null,"language": "de","visibility": "public","isSensitive": false,"isReply": false,"isReblog": false,"repliesCount": 0,"reblogsCount": 0,"favouritesCount": 0,"hashtags": [],"mentionCount": 0,"mediaCount": 0,"mediaTypes": [],"linkUrl": null,"linkTitle": null,"retrievedAt": "2026-08-03T11:11:02Z"}
How it works
- You set the filters below, or none at all - every field is optional.
- The Actor calls the public mastodon.social API directly over HTTP. There is no key to obtain, no login and no headless browser, so a run is fast and cannot break on a UI change.
- It pages through the results until your maximum is reached or the source runs out of matches.
- Every row is pushed to the dataset as it is built - never buffered to the end. A run that hits its time limit still returns everything it collected.
- You are charged
post-returnedat $0.001 per row, and nothing for Apify platform usage. The maximum-results field is therefore your cost cap, and Apify Store discounts apply on top.
💬 Your feedback
Found a bug, or need a field this does not return yet? Open an issue on the Actor's Issues tab, or write to reapxdev@proton.me. Bugs get fixed and reasonable field requests get added.
⚠️ Run outcomes and error handling
This Actor reports what happened in the run's status message, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.
| Outcome | What it means |
|---|---|
| Success | Rows were returned and you were charged post-returned at $0.001 per row. |
| No matches | The source returned nothing for your filters. Nothing is charged. Widen the date window or drop a filter. |
| Partial - source refused | The source rate-limited or refused some requests. The affected items are skipped and named in the log, and everything already collected is still pushed. A block never discards a run's work. |
| Private or login-walled | The requested item is not publicly readable. It is skipped and named; the rest of the run continues. |
What is guaranteed either way
- Every row is pushed as it is built, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- A field absent from the source is absent from the row. Nothing is inferred, modelled or filled in to make a row look complete.
🧭 Ready-made configurations
These are saved, published configurations of this exact Actor. Open one and run it as it is, or copy its input as a starting point - each link is a live page with the full input and its output schema.
| Configuration | Input |
|---|---|
| #photography Posts on Mastodon | instances: mastodon.social; hashtags: photography; maxPosts: 500 |
| #opensource Posts on Mastodon | instances: mastodon.social; hashtags: opensource; maxPosts: 500 |
| #linux Posts on Mastodon | instances: mastodon.social; hashtags: linux; maxPosts: 500 |
| #rustlang Posts on Mastodon | instances: mastodon.social; hashtags: rustlang; maxPosts: 500 |
| #python Posts on Mastodon | instances: mastodon.social; hashtags: python; maxPosts: 500 |
| #javascript Posts on Mastodon | instances: mastodon.social; hashtags: javascript; maxPosts: 500 |
| #golang Posts on Mastodon | instances: mastodon.social; hashtags: golang; maxPosts: 500 |
| #webdev Posts on Mastodon | instances: mastodon.social; hashtags: webdev; maxPosts: 500 |
| #devops Posts on Mastodon | instances: mastodon.social; hashtags: devops; maxPosts: 500 |
| #infosec Posts on Mastodon | instances: mastodon.social; hashtags: infosec; maxPosts: 500 |
| #privacy Posts on Mastodon | - |
| #selfhosted Posts on Mastodon | - |
| #fediverse Posts on Mastodon | - |
| #ai Posts on Mastodon | - |
There are 49 of these in total, all listed on the Actor's Examples tab.