How to track Product Hunt launches and what each product charges
Pull Product Hunt leaderboards with each launch's real website, pricing page, plan tiers and lowest paid price, from Python or cURL.
datagrit › Guides › Medium Publication Finder: Subscribers & Activity
GuideFind Medium publications by keyword and score each by followers, posting cadence, claps per 1,000 followers and paywalled share, in Python or cURL.
Published 2026-10-07 · uses the Medium Publication Finder: Subscribers & Activity Actor
Anyone who writes for an audience on Medium eventually asks the same question: which publications are worth pitching? Founders want a place to publish a launch story, agencies build outreach lists for clients, newsletter writers look for cross-promotion, and analysts compare the publications in a niche. Medium search answers "which publications match this keyword" but not the questions that decide where to spend time. Is it still publishing? How many followers does it have? Do its stories get any claps?
This guide shows how to turn a keyword into a ranked table of publications with those answers, using the Medium Publication Finder Actor. The same field notes apply if you build the pipeline yourself on Medium's public data.
Medium's web pages sit behind a bot filter, and scraping the HTML of a publication page is fragile. The Actor does not parse pages. It asks the same public GraphQL endpoint that Medium's own site uses, which returns structured records: the publication (name, slug, optional custom domain, tagline, description, follower count, creator, editors) and its most recent posts (publication timestamp, claps, responses, reading time, word count, member-only flag, tags, author).
Two properties of that source shape the output:
postsSampled) and how long that window is (sampleSpanDays).The input needs at least one keyword in queries or one publication in publications. This input searches two topics, keeps up to ten publications per topic, and drops everything below 200 followers or without a post in the last 90 days:
{
"queries": ["startup", "machine learning"],
"maxPublicationsPerQuery": 10,
"minSubscribers": 200,
"activeWithinDays": 90,
"maxItems": 50
}
Call it from Python with apify-client:
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("datagrit/medium-publication-finder").call(run_input={
"queries": ["startup", "machine learning"],
"maxPublicationsPerQuery": 10,
"minSubscribers": 200,
"activeWithinDays": 90,
"maxItems": 50,
})
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())
Or with cURL, which returns the rows directly:
curl -X POST "https://api.apify.com/v2/acts/datagrit~medium-publication-finder/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries":["startup"],"maxPublicationsPerQuery":10,"activeWithinDays":90}'
You can also look up publications you already know. The publications field accepts a slug (better-programming), a link (https://medium.com/swlh) or a custom domain (uxdesign.cc). Profiles of people (@name) are not publications, so they are ignored and listed in the run message.
| Field | Example | What it tells you |
|---|---|---|
subscribers | 389 | Followers of the publication. |
postsPerWeek | 0.2 | Sampled posts divided by the window they span. |
daysSinceLastPost | 4.4 | Whether anyone is still publishing. |
activityStatus | active | active up to 14 days, slowing up to 60, dormant beyond. |
medianClaps | 2 | A typical story, not one viral outlier. |
medianClapsPer1kSubscribers | 5.14 | Engagement normalised by size. |
memberOnlySharePct | 0 | Share of sampled stories behind Medium's paywall. |
topAuthors | [{"username": "midweststartups", "posts": 22}] | Who actually writes there. |
bestPost | {"title": "...", "claps": 139} | The standout story of the sample. |
The numbers in that table are a real row. The Midwest Startups publication has 389 followers, posts about once every five weeks and earns a median of two claps per story, which works out to 5.14 claps per 1,000 followers. The Startup publication has 894,499 followers and a median of 269 claps, but its newest sampled post was more than four months old when we checked, so it is dormant and its engagement per follower is 0.3. Size alone would have ranked the two the other way round.
A pitch list in pandas. Rank the publications that are alive and small enough to answer:
import pandas as pd
df = pd.DataFrame(rows)
df = df[df["found"] == True]
shortlist = df[(df["activityStatus"].isin(["active", "slowing"])) & (df["subscribers"] < 20000)]
print(shortlist.sort_values("medianClapsPer1kSubscribers", ascending=False)
[["name", "subscribers", "postsPerWeek", "medianClapsPer1kSubscribers", "url"]].head(15))
A weekly competitor sheet. Put your own publication and three competitors in publications, schedule the Actor weekly in Apify, and append the rows to a spreadsheet or a database. Because every row carries scrapedAt, you can chart follower counts and postsPerWeek over time without storing anything in the Actor.
An editor lookup for outreach. Each row has creatorUsername, an editors list and topAuthors. Take the publications on your shortlist and read the usernames to find whom to address, then check the public profile pages yourself before writing to anyone.
The Actor never returns silent empty results. When nothing can be returned for an input, you get one row with found: false and a reason:
noMatches: the keyword found no publications.filteredOut: publications were found, but none passed your subscriber and activity filters.notFound: no publication with that slug or domain exists.fetchFailed: Medium did not answer after several retries.Status rows are not charged, and neither are publications removed by your filters. If Medium changes its response format so that follower counts, post lists or post dates stop appearing, the run fails with a message that says what is missing, instead of delivering rows full of nulls.
postsPerWeek describes recent activity rather than the long-run average. Check sampleSpanDays.averageClaps and bestPost before ruling a publication out.maxPublicationsPerQuery. A narrow keyword gives a better list than a broad one.Search gives you names, and the scorecard tells you which of those names deserve an email. The Actor is on the Apify Store as Medium Publication Finder: Subscribers & Activity, and the full input and output reference is on the documentation page. It is priced per result, and a maximum spend on the run caps what a run can cost.
Pull Product Hunt leaderboards with each launch's real website, pricing page, plan tiers and lowest paid price, from Python or cURL.
Pull Bilibili's Top 100 anime ranking, a filterable catalog with follower and rating counts, and the release calendar as clean JSON using Python or cURL.
Pull TikTok Creative Center Top Ads for several countries and industries, merge the lists, and get only the ads that are new since your last run.