# Lemmy Scraper: Posts, Comments & Communities (`steadyscrape/lemmy-scraper`) Actor

Scrape Lemmy posts, comments and communities from any instance: titles, text, links, scores, authors, reply trees, federated links, subscriber and activity counts. Communities, posts, instance feeds and keyword search, no login. Export to JSON, CSV or Excel, or via API.

- **URL**: https://apify.com/steadyscrape/lemmy-scraper.md
- **Developed by:** [Steady Scrape](https://apify.com/steadyscrape) (community)
- **Categories:** Social media, News, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.30 / 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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Lemmy Scraper: Posts, Comments & Communities

**Lemmy Scraper** collects **posts, comments and communities from any Lemmy instance** — lemmy.world, lemmy.ml,
sh.itjust.works, lemmy.ca, feddit.org or any other — through Lemmy's own public API. Paste a **community**, a **post**, an
**instance** or an instance's **community list**, or search by **keyword**, and get clean rows with **titles, text, links,
scores (upvotes and downvotes), comment counts, authors, reply trees, dates** and the **federated link** of every post and
comment, plus **subscriber and activity counts** for communities. No login, no browser, no API key. Pay only for the rows you
get.

Lemmy is the federated, open-source Reddit alternative: each community lives on one instance and is copied to the others. This
Lemmy scraper reads any of them and gives every post and comment its **federated link** (`apId`) — the same on every
instance — so copies read through two instances are recognised and delivered once.

### What you can do with this Lemmy scraper

- **Brand and topic monitoring**: schedule the newest posts and comments of the communities in your field, or a keyword
  search, and get what was said since the last run.
- **Research and datasets**: posts with their full comment threads (parent, depth and score of every reply) for discourse
  analysis, sentiment, NLP or AI training sets.
- **Community discovery**: every community of an instance with subscribers, posts, comments and daily, weekly, monthly and
  half-year active users — find the active communities of a topic before you post or advertise.
- **Fediverse analytics**: compare instances, follow how a story federates, measure engagement over time.
- **Reddit alternative tracking**: the same kind of data you would take from subreddits, from the communities that moved to
  Lemmy.

### What it reads

| You paste | You get |
|---|---|
| A community link or handle: `https://lemmy.world/c/technology`, `technology@lemmy.world`, `!asklemmy@lemmy.ml` | Its posts (and, if you ask, its comments) |
| A community of another instance, as one instance shows it: `https://sh.itjust.works/c/technology@lemmy.world` | That community read through that instance |
| A post link: `https://lemmy.world/post/53761662` | The post and, if you ask, all its comments |
| An instance: `lemmy.ml` | Its front-page feed (Local: its own communities; All: everything it federates) |
| A community list: `https://lemmy.world/communities` | Every community with its counts |
| A search term, with the instance to search | The posts (and comments) the instance's search finds |

**Comments** come two ways:

- **Latest comments**: the newest comments of a community, feed or search across all its posts, 50 per request — the fast way
  to collect comments — and all comments of each post link.
- **Comments of each post**: the full thread of every post scraped, with each reply's parent and depth.

### How it works, and how fast

The Actor calls each instance's public JSON API (`/api/v3/post/list`, `/api/v3/comment/list`, `/api/v3/community/list`,
`/api/v3/search`, `/api/v3/post`), up to 50 items a request. It reads each instance's `robots.txt` first and obeys it:
**most Lemmy instances ask crawlers to wait 60 seconds between requests**, and the Actor keeps that pace on each instance.
So:

- up to **50 posts, comments or communities a minute per instance** — about 3,000 an hour;
- **different instances are read at the same time**, each at its own pace;
- **comments of each post** take one request per post with comments (posts without comments cost none): 20 posts on
  lemmy.world take about 20 minutes. Use **Latest comments** when you need volume.

Raise the run timeout for large jobs. Deleted and removed posts and comments are never delivered or charged.

### Input example

```json
{
  "targets": [
    "https://lemmy.world/c/technology",
    "asklemmy@lemmy.ml",
    "https://lemmy.world/communities"
  ],
  "searchTerms": ["open source"],
  "searchInstance": "lemmy.world",
  "maxPostsPerTarget": 200,
  "comments": "latest",
  "maxComments": 500,
  "sort": "New"
}
```

### Output example

A post (comments and communities come in the same dataset, told apart by `rowType`):

```json
{
  "rowType": "post",
  "input": "https://lemmy.world/c/technology",
  "instance": "lemmy.world",
  "id": 53759599,
  "apId": "https://lemmy.ca/post/73104961",
  "url": "https://lemmy.world/post/53759599",
  "homeInstance": "lemmy.ca",
  "title": "Attacker gets away with up to $3 billion from Binance",
  "body": "Article is by Molly White, who you might recognize from Mastodon and web3isgoinggreat.com: ...",
  "link": "https://www.citationneeded.news/binance-theft/",
  "linkTitle": "Attacker gets away with up to $3 billion from Binance",
  "thumbnailUrl": "https://lemmy.world/pictrs/image/94eb8ca1-eb93-4f97-baef-55e5bd32397d.jpeg",
  "authorName": "otter",
  "authorHandle": "otter@lemmy.ca",
  "authorDisplayName": "Otter",
  "communityHandle": "technology@lemmy.world",
  "communityTitle": "Technology",
  "score": 101,
  "upvotes": 102,
  "downvotes": 1,
  "commentCount": 8,
  "publishedAt": "2026-10-30T02:35:30.691Z",
  "nsfw": false,
  "locked": false,
  "pinned": false,
  "position": 3
}
```

### Output fields

**Posts** (`rowType: "post"`)

| field | what it is |
|---|---|
| `id`, `url` | the post's number and page on the instance it was read from |
| `apId`, `homeInstance` | the post's federated link (the same on every instance) and the instance it was written on |
| `title`, `body` | title, and text in Markdown (`null` for a link or image post) |
| `link`, `linkTitle`, `linkDescription`, `thumbnailUrl` | the link or image shared, with its preview |
| `authorName`, `authorHandle`, `authorDisplayName`, `authorUrl`, `authorIsBot` | the author (`name@instance`) |
| `communityName`, `communityHandle`, `communityTitle`, `communityUrl` | the community |
| `score`, `upvotes`, `downvotes`, `commentCount` | votes and comments |
| `publishedAt`, `updatedAt`, `newestCommentAt` | ISO 8601 UTC |
| `nsfw`, `locked`, `pinned` | flags |
| `position` | the place in the list it was read from |

**Comments** (`rowType: "comment"`): `id`, `url`, `apId`, `homeInstance`, `content` (Markdown), `postId`, `postApId`,
`postTitle`, `postUrl`, `parentId` (the comment it answers, `null` for a reply to the post), `depth` (0 for a reply to the
post), the author and community fields, `score`, `upvotes`, `downvotes`, `replyCount`, `publishedAt`, `updatedAt`,
`distinguished`, `position`.

**Communities** (`rowType: "community"`): `id`, `name`, `handle` (`name@instance`), `title`, `description`, `apId`, `url`,
`homeInstance`, `iconUrl`, `bannerUrl`, `nsfw`, `postingRestrictedToMods`, `subscribers`, `subscribersLocal`, `posts`,
`comments`, `usersActiveDay`, `usersActiveWeek`, `usersActiveMonth`, `usersActiveHalfYear`, `publishedAt`, `position`.

Every row also carries `input` (what you pasted), `instance` (where it was read) and `scrapedAt`.

**Free status rows** (`rowType: "status"`) explain a target that gave nothing: `not_found` (no such community or post on that
instance), `invalid`, `unsupported` (a user profile, a comment link, a Kbin/Mbin magazine, or a site that is not Lemmy),
`disallowed` (closed by the instance's robots.txt), `blocked` (the instance refused or showed a challenge page),
`duplicate`, `no_results`, `site_error`. They are never charged.

### Pricing

Pay per event, no subscription:

| event | price |
|---|---|
| `post` | US$0.0003 |
| `comment` | US$0.0003 |
| `community` (with its counts) | US$0.0005 |

1,000 posts cost US$0.30. Status rows are free, and the run stops at your maximum cost per run.

### Tips and limits

- **A community of another instance** is known to an instance only once one of its users subscribed; read it through its own
  instance (`technology@lemmy.world` reads lemmy.world) for its whole history.
- **Post numbers differ on each instance**: `lemmy.world/post/53761662` and `sh.itjust.works/post/69140705` are the same post.
  Use `apId` to match them.
- **Sorts** are Lemmy's own (New, Hot, Active, Top by time window…). Pages of a long thread are a minute apart on most
  instances: a comment written meanwhile can shift a page, and the repeated comment is delivered once.
- **Instances behind a challenge page** (programming.dev answered one in October 2026) give a free `blocked` row: the
  Actor never solves or bypasses challenges.
- User profiles are not read.

### Is it legal to scrape Lemmy?

This Actor is unofficial: it is not affiliated with, endorsed by or sponsored by the Lemmy project, its developers or any
Lemmy instance. It reads only public data that each instance publishes through its own public API, without logging in, and it
obeys every instance's robots.txt, including its crawl delay. Posts and comments can contain personal data; you are
responsible for using the results lawfully (GDPR and similar laws) and within each instance's terms. Do not use it to harass
users or to republish content against its authors' wishes.

# Actor input Schema

## `targets` (type: `array`):

One per line, from any Lemmy instance: a community link (<code>https://lemmy.world/c/technology</code>) or handle (<code>technology@lemmy.world</code>, <code>!asklemmy@lemmy.ml</code>), a community of another instance as one instance shows it (<code>https://sh.itjust.works/c/technology@lemmy.world</code>), a post link (<code>https://lemmy.world/post/53761662</code>), an instance for its front-page feed (<code>lemmy.ml</code>), or an instance's community list (<code>https://lemmy.world/communities</code>) for every community with its subscriber and activity counts.

## `searchTerms` (type: `array`):

Keywords to search with the instance's own search (one search per line): the posts it finds, and with <b>Latest comments</b> the comments it finds.

## `searchInstance` (type: `string`):

The instance whose search is used for the search terms, e.g. <code>lemmy.world</code>, <code>lemmy.ml</code>, <code>sh.itjust.works</code>.

## `includePosts` (type: `boolean`):

Deliver the posts of each community, feed, search and post link (priced as <code>post</code>). Turn off to get only comments.

## `maxPostsPerTarget` (type: `integer`):

Stop each community, feed or search after this many posts. 0 means no maximum (up to 10,000).

## `sort` (type: `string`):

Lemmy's own sorts. <b>New</b> suits monitoring; <b>Top…</b> sorts by score within a time window.

## `comments` (type: `string`):

<b>Latest comments</b>: the newest comments of each community, feed or search across all its posts (50 per request, the fastest way to collect comments), and all comments of each post link. <b>Comments of each post</b>: the comment thread of every post scraped, one request or more per post, so on an instance that asks 60 seconds between requests 20 posts take about 20 minutes. Priced as <code>comment</code>.

## `maxComments` (type: `integer`):

Latest comments: per community, feed or search. Comments of each post: per post. 0 means every comment.

## `commentSort` (type: `string`):

The order a post's comments are read in, which decides which ones a maximum keeps. Latest comments are always newest first.

## `listingType` (type: `string`):

<b>Local</b>: what the instance itself hosts. <b>All</b>: everything it receives from the instances it federates with. Applies to instance feeds, searches and community lists; a community link always reads that community.

## `communitySort` (type: `string`):

For community-list links. <b>Top: all time</b> lists the most subscribed first.

## `maxCommunities` (type: `integer`):

Stop each community list after this many communities (priced as <code>community</code>). 0 means every community.

## `includeNsfw` (type: `boolean`):

Ask post lists and community lists for NSFW content too (instances that allow it).

## Actor input object example

```json
{
  "targets": [
    "https://lemmy.world/c/technology"
  ],
  "searchTerms": [],
  "searchInstance": "lemmy.world",
  "includePosts": true,
  "maxPostsPerTarget": 5,
  "sort": "New",
  "comments": "none",
  "maxComments": 100,
  "commentSort": "Top",
  "listingType": "Local",
  "communitySort": "TopAll",
  "maxCommunities": 100,
  "includeNsfw": false
}
```

# Actor output Schema

## `rows` (type: `string`):

No description

## `summary` (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 = {
    "targets": [
        "https://lemmy.world/c/technology"
    ],
    "maxPostsPerTarget": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadyscrape/lemmy-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 = {
    "targets": ["https://lemmy.world/c/technology"],
    "maxPostsPerTarget": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("steadyscrape/lemmy-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 '{
  "targets": [
    "https://lemmy.world/c/technology"
  ],
  "maxPostsPerTarget": 5
}' |
apify call steadyscrape/lemmy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadyscrape/lemmy-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/zKP9n9Z41Ebttjibr/builds/H6bXbyhRrGafcyfOk/openapi.json
