Lemmy Posts, Comments, Threads & Communities (no login)
Pricing
from $1.05 / 1,000 lemmy data rows
Lemmy Posts, Comments, Threads & Communities (no login)
Public Lemmy data as rows: posts of named communities or of the whole site, keyword search over posts and comments, the full comment tree of any post, a user's public posts and comments, and community size and activity counts. Author and community server on every row. Keyless API, UTC dates.
Pricing
from $1.05 / 1,000 lemmy data rows
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Public Lemmy content as flat rows, read from the HTTP API of lemmy.world — the largest instance of the network — which answers JSON without an account, a token or a cookie. Six questions in one actor: the posts of the communities you name, the site-wide feed, a keyword across posts and comments, the whole discussion under a post numbered by reply depth, what an account published in public, and which communities exist for a topic with their subscriber and activity counts. Lemmy is federated, so that one server also holds content from thousands of other instances: every row names the server its author and its community live on, and every timestamp is UTC ISO-8601.
Need it tailored to your workflow? Missing a field, a filter, another source or a different output format? Open an issue and describe what you need — we read every request and adapt the actor.
Use cases
- Keep a topic feed after a forum closes its own. Point
communityPostsattechnology,asklemmyor any community, setsinceHoursto your schedule interval andonlyNew: true— each run then holds exactly what appeared since the last one. - Watch a product name where opinions actually are.
searchPostsfinds the posts,searchCommentsthe replies; on Lemmy most of what people think about a release sits in comments, and both modes reach communities hosted on other instances. - Summarise a discussion.
postCommentsturns one post link into its thread in reading order, withreplyDepth,parentCommentIdandchildCount, which is the shape an LLM needs to answer "what did people reply, and to whom". - Archive public announcements.
userActivityexports what a moderator, admin or project account posted and commented, with the lifetime post and comment totals the profile shows. - Size the network before you monitor it.
communitiesranks communities for a topic by subscribers and users active per day, week and month, so a listening pipeline starts with the communities that are alive. - One feed for a dashboard.
communityPostswith no community named is the site-wide feed;listingType: localkeeps it to the communities lemmy.world hosts itself,allopens it to the federated view. - Study federation.
authorInstancesandcommunityInstancesfilter on the server columns — watch one instance's voices inside a worldwide community, or drop an instance that floods a feed.
Input
Every field is optional and each mode uses the fields of its own section. Values shown in the editor are prefills — change or clear them freely; only behaviour settings have real defaults.
| Field | Type | Default | Allowed values / notes |
|---|---|---|---|
mode | string | communityPosts | communityPosts, searchPosts, searchComments, postComments, userActivity, communities — see Modes |
communities | string[] | prefill technology, asklemmy | Communities to read. name, name@server or a community link — see Writing a community or a handle. Empty in communityPosts = the site-wide feed |
listingType | string | all | all = every federated server this one knows, local = communities hosted on lemmy.world. Applies to the site-wide feed, both search modes and the community directory |
sort | string | New | 16 orders for posts, comments and communities — see Sort orders |
searchQuery | string | prefill kubernetes | The keyword for searchPosts, searchComments and the community directory. One phrase per run, matched as a case-insensitive substring |
postUrls | string[] | prefill one post link | postComments: a lemmy.world link, a bare post id, or a post link on any other instance — see Post links |
includeOriginalPost | boolean | true | postComments: write one post row per thread before its comments |
maxCommentDepth | number | 8 | 1–50. Levels of replies to read in postComments; 1 = direct replies only |
commentSort | string | Top | Top, New, Old, Hot, Controversial — the order of the branches in postComments |
users | string[] | prefill ruud@lemmy.world | userActivity: accounts as name, name@server or a profile link. The row limit is split over them |
userContent | string | posts | userActivity: posts, comments or both (split evenly, newest first) |
languages | string[] | all | Keep rows whose declared language is one of 22 codes, und included — see Languages |
authorInstances | string[] | all | Keep rows whose author lives on one of these servers, e.g. lemm.ee, programming.dev |
communityInstances | string[] | all | Keep rows whose community is hosted on one of these servers |
minScore | number | – | −100 000…100 000. Keep posts and comments with at least this score (upvotes minus downvotes) |
minComments | number | – | 0–100 000. Keep posts with at least this many comments. Comment rows carry childCount instead |
excludeNsfw | boolean | true | Drop posts, comments and communities flagged NSFW. Switch off for a complete sample |
excludeBots | boolean | false | Drop rows of accounts that declare themselves bots (authorIsBot) |
sinceHours | number | – | 1–8760. Rolling window in UTC hours. With sort: New paging also stops as soon as the source walks past it |
onlyNew | boolean | false | Remember the post and comment ids written — as they are written — and write only unseen ones on the next run of the same actor or task |
maxItems | number | 50 | 1–1000. Hard cap on rows and therefore on cost; split over the communities, users or threads of the run. The run also stops at your maximum cost per run |
fields | string[] | all | Keep only these columns, in this order; rowType, sourceMode, found and url are always kept. Letter case is corrected, unknown names are reported in the status message with the nearest column, and a list with no valid column fails the run |
Reference
Modes
mode | Endpoints used | Rows | Dataset view |
|---|---|---|---|
communityPosts | post/list | one post per post of the named communities, or of the whole instance | Posts |
searchPosts | search (Posts) | one post per match in a title, body or posted link | Posts |
searchComments | search (Comments) | one comment per match in comment text | Comments |
postComments | resolve_object → post → comment/list | one post row (optional) plus one comment per reply, in reading order | Comments |
userActivity | user | one post or comment per public item of the named accounts | Posts / Comments |
communities | community, search (Communities), community/list | one community per community, with counts | Communities |
Each mode fills one view; the others stay empty. communities answers the communities you name (with moderatorCount), otherwise the matches for searchQuery, otherwise the ranked directory for sort and listingType.
Sort orders
New, Old, Hot, Active, Scaled, MostComments, NewComments, Controversial, TopHour, TopSixHour, TopTwelveHour, TopDay, TopWeek, TopMonth, TopYear, TopAll.
A Top* order is a window as well as an order: TopWeek can never return a post older than seven days, so do not combine it with a longer sinceHours and expect more rows. New is the one order that walks strictly down the clock, which makes it the cheapest choice for a monitoring run — it is the only one where a window can end the paging early. Active and NewComments rank by recent comment activity, Scaled lifts smaller communities, Controversial surfaces what was up- and downvoted alike. Comment branches use the shorter list: Top, New, Old, Hot, Controversial.
Writing a community or a handle
A bare technology means the community of that name on lemmy.world. name@server (programming@programming.dev, climate@slrpnk.net) means the federated copy this server keeps of a community hosted elsewhere. Links work too: https://lemmy.world/c/technology, https://programming.dev/c/programming, and the !name@server form people paste from chat. Accounts follow the same rules with /u/: ruud, ruud@lemmy.world, https://lemm.ee/u/sunaurus. A name this server has never seen yields one row with found: false and the reason in notFoundReason, so one typo in a long list never disappears silently. The authorHandle column is always written as name@server, so rows from different instances can be compared.
Post links
postComments accepts https://lemmy.world/post/920294, the bare id 920294, and a post link on any other instance such as https://programming.dev/post/57357662. Every instance numbers posts itself, so a foreign link is first resolved to the copy lemmy.world holds (one extra request), and the row then carries the local postId and url plus the canonical apId of the origin server. Any post row of any mode already carries postId and url, which is how a feed or search run chains into a thread run.
Languages
und (not set), en, de, fr, es, pt, it, nl, sv, da, nb, fi, pl, cs, ru, uk, tr, ja, zh, ko, ar, ca. Only these codes are accepted: Apify refuses any other value - a name like English, a three-letter code like eng - before the run starts, so a run never keeps a language you did not pick. Read the honest part first: Lemmy stores a language per post and comment, but most clients never set it, so a large share of real rows carry und. Pick en and und together if you want English-speaking communities without losing most of their content.
Row types
rowType is post, comment or community; sourceMode repeats the mode that produced the row, and found is false only on a row that explains an input the source would not serve.
Examples
Posts of one community, last two days, newest first:
{ "mode": "communityPosts", "communities": ["technology"], "sort": "New", "sinceHours": 48, "maxItems": 20 }
The week's discussions of a question community, only the ones that got answers:
{ "mode": "communityPosts", "communities": ["asklemmy"], "sort": "TopWeek", "minComments": 5, "maxItems": 15 }
One keyword across every community the server knows:
{ "mode": "searchPosts", "searchQuery": "docker", "sort": "TopMonth", "listingType": "all", "maxItems": 15 }
The same keyword in comments, newest first:
{ "mode": "searchComments", "searchQuery": "kubernetes", "sort": "New", "maxItems": 15 }
A whole thread, two levels deep, highest-scoring branches first, comments only:
{ "mode": "postComments", "postUrls": ["https://lemmy.world/post/920294"], "commentSort": "Top", "maxCommentDepth": 2, "includeOriginalPost": false, "maxItems": 20 }
Which communities exist for a topic, biggest first:
{ "mode": "communities", "searchQuery": "climate", "sort": "TopAll", "maxItems": 15 }
The site-wide feed of the instance itself, for a dashboard:
{ "mode": "communityPosts", "listingType": "local", "sort": "Active", "maxItems": 20 }
Output
One real row of the cloud run SYSbBnAaKNBhd6CbX (input {"mode": "communityPosts", "communities": ["technology"], "sort": "New", "sinceHours": 48, "excludeNsfw": true, "maxItems": 20}):
{"rowType": "post","sourceMode": "communityPosts","found": true,"notFoundReason": null,"postId": 52605462,"title": "Google rolls out new Gemini AI model but restricts access over safety concerns","body": null,"postUrl": "https://www.theguardian.com/technology/2026/oct/01/google-releases-gemini-model-restrictions","thumbnailUrl": "https://lemmy.world/pictrs/image/583dd762-f759-4431-901f-851b259e0901.jpeg","embedTitle": "Google rolls out new Gemini AI model but restricts access over safety concerns","embedDescription": "Tech company releases Gemini 4 Argon only to a vetted group of cybersecurity experts to avoid misuse by hackers","community": "technology","communityTitle": "Technology","communityInstance": "lemmy.world","authorHandle": "orwi@programming.dev","authorDisplayName": null,"authorInstance": "programming.dev","authorIsBot": false,"authorPostCount": null,"authorCommentCount": null,"score": -1,"upvotes": 2,"downvotes": 3,"commentCount": 2,"newestCommentAt": "2026-10-01T21:43:29.984Z","createdAt": "2026-10-01T21:18:55.327Z","updatedAt": null,"nsfw": false,"locked": false,"removed": false,"deleted": false,"featuredInCommunity": false,"featuredSiteWide": false,"language": "en","matchedCommunity": "technology","matchedQuery": null,"url": "https://lemmy.world/post/52605462","apId": "https://programming.dev/post/57357662","fetchedAt": "2026-10-01T22:28:58.531Z"}
Download the dataset as JSON, CSV, Excel, HTML or XML, or read it over the API.
Post row (rowType: "post")
| Field | Type | Meaning |
|---|---|---|
postId | number | Id of the post on lemmy.world; the input of a postComments run |
title | string | Post title as written |
body | string | Post text, Markdown as the source stores it; null for a pure link post |
postUrl | string | The link the post points at, null for a text post |
thumbnailUrl | string | Preview image the server generated |
embedTitle, embedDescription | string | Title and summary the server read from the linked page |
community, communityTitle | string | Community name and its display name |
communityInstance | string | Server hosting the community, e.g. lemmy.world, slrpnk.net |
authorHandle | string | Author as name@server, always in that form |
authorDisplayName | string | Chosen display name, often null |
authorInstance | string | Server the author's account lives on |
authorIsBot | boolean | The account declares itself a bot |
authorPostCount, authorCommentCount | number | Lifetime totals of the account — filled in userActivity, null elsewhere |
score, upvotes, downvotes | number | Public vote totals at fetchedAt; the score can be negative |
commentCount | number | Comments the server counts under the post |
newestCommentAt | string | UTC time of the newest comment |
createdAt, updatedAt | string | Posted and last edited, UTC ISO-8601 |
nsfw | boolean | Flagged by the post or by its community |
locked | boolean | Closed for new comments |
removed, deleted | boolean | Moderator removal / author deletion flags the source publishes |
featuredInCommunity, featuredSiteWide | boolean | Pinned in the community or on the front page |
language | string | Declared language code, und when the client set none |
matchedCommunity | string | The community of the input that produced the row |
matchedQuery | string | The keyword that produced the row |
url | string | Permalink on lemmy.world |
apId | string | Canonical link on the instance the post was written on |
found, notFoundReason | boolean, string | false plus a reason when the source would not serve the input |
fetchedAt | string | UTC time this row was read |
Comment row (rowType: "comment")
| Field | Type | Meaning |
|---|---|---|
commentId | number | Id of the comment on lemmy.world |
text | string | Comment text, Markdown as written |
replyDepth | number | 1 for a direct reply to the post, 2 for a reply to that, and so on |
parentCommentId | number | The comment this one answers, null at depth 1 |
childCount | number | Replies hanging below it — how much a depth or row limit cut off |
postId, postTitle | number, string | The post the comment sits under |
community, communityTitle, communityInstance | string | Where the discussion happens |
authorHandle, authorDisplayName, authorInstance, authorIsBot | string, boolean | The comment's author |
score, upvotes, downvotes | number | Public vote totals at fetchedAt |
createdAt, updatedAt | string | Written and last edited, UTC |
removed, deleted, nsfw | boolean | Moderation flags; nsfw is inherited from the post or community |
language | string | Declared language code, often und |
matchedQuery, matchedCommunity | string | What produced the row |
url, apId | string | Permalink here and canonical link on the origin instance |
fetchedAt | string | UTC time this row was read |
Community row (rowType: "community")
| Field | Type | Meaning |
|---|---|---|
community, communityTitle | string | Name and display name |
description | string | Sidebar text, Markdown |
communityInstance | string | Server hosting it |
subscribers, subscribersLocal | number | Subscribers everywhere, and from lemmy.world alone |
postsCount, commentsCount | number | Totals the server counts |
usersActiveDay, usersActiveWeek, usersActiveMonth, usersActiveHalfYear | number | Accounts that posted or commented in the window |
moderatorCount | number | Moderators — filled for communities you name, null for search and directory rows |
nsfw, postingRestrictedToMods | boolean | Adult flag; only moderators may post |
createdAt, updatedAt | string | Created and last changed, UTC |
icon | string | Community icon URL |
matchedQuery | string | The topic word that produced the row |
url, apId | string | Link here and canonical link on the origin instance |
fetchedAt | string | UTC time this row was read |
Views and the run summary
Three dataset views pick the columns worth a table: Posts (author, community and its server, title, score, comments, date, link), Comments (author, post, text, score, depth, replies below) and Communities (server, subscribers, active users, posts, comments, moderators). Every run also writes a SUMMARY record into its default key-value store with the request count, the rows per community, user or thread, the skipped rows per filter, the inputs the source would not serve and every warning — useful when a scheduled run returns fewer rows than expected.
Use it from code / agents
curl -X POST "https://api.apify.com/v2/acts/yadroo~lemmy-public-posts/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"mode":"searchComments","searchQuery":"kubernetes","sort":"New","maxItems":20,"fields":["authorHandle","community","postTitle","text","score","createdAt","url"]}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/lemmy-public-posts').call({ mode: 'communityPosts', communities: ['technology'], sinceHours: 24, maxItems: 50 });const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) console.log(row.createdAt, row.authorHandle, row.score, row.title);
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])# 1) find the busiest post of a community, 2) read its discussion for a summaryfeed = client.actor("yadroo/lemmy-public-posts").call(run_input={"mode": "communityPosts", "communities": ["asklemmy"], "sort": "TopWeek", "maxItems": 20})rows = client.dataset(feed["defaultDatasetId"]).list_items().itemsbusiest = max(rows, key=lambda r: r.get("commentCount") or 0)thread = client.actor("yadroo/lemmy-public-posts").call(run_input={"mode": "postComments", "postUrls": [busiest["url"]], "commentSort": "Top", "maxCommentDepth": 3, "maxItems": 100})
Chaining works in both directions: a communities run gives community and communityInstance values to paste straight into communities (name@server), and any post row gives a url for postComments. For a schedule, set sinceHours a little above the interval and onlyNew: true — an empty run then means nothing new was posted. Narrow rows with fields when an LLM reads them.
MCP: add https://mcp.apify.com to Claude, Cursor or any MCP client and call the yadroo/lemmy-public-posts tool with the same JSON input.
Pricing
Pay per event: $0.001 per run start + $0.0015 per dataset row. Platform usage (compute and traffic) is included in these prices — nothing is charged on top. The start event is charged on every run, including a run that writes no row (a monitoring run with onlyNew and nothing new, for example). A found: false row — the one row that explains an unknown community, account or post — is a dataset row and is billed like any other; a post or comment the source serves twice in one run is written and billed once.
| Run | Rows | Cost |
|---|---|---|
| Community directory for a topic | 15 | $0.001 + 15 × $0.0015 = $0.0235 |
| Community feed, last 24 h | 50 | $0.001 + 50 × $0.0015 = $0.0760 |
| A busy thread, three levels deep | 200 | $0.001 + 200 × $0.0015 = $0.3010 |
Store discounts lower the row price automatically: Bronze −10 %, Silver −20 %, Gold and above −30 %; the start event is the same on every plan. Set Maximum cost per run and the run stops exactly there: it writes the rows that budget pays for and ends with "Stopped at your spending limit: N rows delivered". Keep maxItems small while you try inputs out — it is the one input that decides what a run costs.
Limits & FAQ
- 50 rows per request, so deep runs page. The source refuses
limitabove 50 with an HTTP 400, which the actor clamps for you; a 1000-row run is roughly 20–25 requests and a few minutes. - Politeness and rate limits. lemmy.world publishes its own per-IP limits (100 search calls per 10 minutes, 999 other reads per minute). The actor sends requests one at a time with a pause of ~350 ms, spaces searches after the first ten to one every 6 seconds, retries HTTP 5xx with backoff and honours
Retry-After. Apify runs share outgoing IPs, so the search budget can already be partly used when a run starts: when the server refuses a request for its limit (HTTP 400rate_limit_error, or 429), the actor waits 30 s, then 60 s, and if the refusal persists it stops reading and says so in the status message — the rows written so far are kept, a run that wrote nothing fails, and the next run should start about 10 minutes later. It never switches IPs to get around the limit. Only/api/v3/*of that one host is ever called, never the HTML pages. - Spending limit, timeout, restarts. Rows are written page by page as they are read. The run stops at your maximum cost per run ("Stopped at your spending limit: N rows delivered"), stops starting new requests shortly before the run timeout and ends successfully with what it saved ("Stopped before the run timeout: N rows saved"), and a platform migration or restart never writes or bills a row twice.
onlyNewmemory. Rows are remembered as they are written, in a named key-value store of your account (lemmy-seen, orlemmy-seen-<task id>for a task, up to 50 000 ids), so a run cut short bymaxItems, the spending limit or the timeout leaves the rest for the next run. Afound: falserow is remembered too: an unknown name gives one row once, and afterwards appears only in the status message.- A thread request is capped at 300 comments. Asked for a depth limit, the source answers up to 300 comments of a post and ignores paging there; the actor then continues with the pageable form of the same endpoint to fill
maxItems, and the status message says how many of the thread's comments it could read.childCountshows where a branch was cut. - No URL or domain search. The source accepts a URL search type but answered zero posts for domain queries, so "who linked my site" is not offered rather than offered broken.
- No phrase or boolean search.
searchQueryis one case-insensitive substring: no quotes, noAND/OR, no wildcards. For several phrases, run several tasks and merge the datasets. sinceHoursis applied here, not by the source. There is no date parameter in the API. Withsort: Newthe actor stops paging at the first row past the window; with any other order the window only filters what the chosen ranking already returned.- Most content declares no language.
languageisundfor a large share of rows. Thelanguagesfilter can only keep what declares a language — addundto the list or leave the filter empty. - A federated view, not all of Lemmy. Rows are what lemmy.world holds: content of instances it federates with, and nothing from instances it has defederated.
communityInstanceandauthorInstancetell you where each row really comes from, and a post can exist elsewhere on the network without existing here. - Vote totals are a snapshot.
score,upvotesanddownvotesare the values atfetchedAtand keep moving; votes are only ever read as the totals the server publishes, never per person. - Nothing behind a login, no contact harvesting. Only what a signed-out visitor sees: posts, comments, pseudonymous handles, public vote totals, community counts and the post/comment totals a profile shows. No follower or subscription lists, no e-mail addresses, no chat identifiers — the source publishes a chat handle on some profiles and this actor deliberately does not write it. Images are linked, never downloaded.
- Empty result vs. error. A quiet community, a keyword nobody used or a filter that dropped everything is a successful run with the reason in the status message and in
SUMMARY. An unknown community, account or post gives one row withfound: falseand a reason. A run that wrote nothing and hit a misbehaving source — or was stopped by the server's rate limit — fails with that reason, so a schedule can tell the two apart. - Deleted and removed content. The API already leaves it out; the
removedanddeletedcolumns stay in the row shape for the cases where it still answers with a flag. - If the server closes these endpoints. A Lemmy instance can put its API behind authentication. Should that happen here, this actor is marked paused on this page instead of working around a block.
Made by Yadroo. Sibling actors: mastodon-public-posts, bluesky-public-posts, hackernews-search, stackexchange-search, rss-to-json.