# Medium Scraper 📰 (articles by tag, author, publication) (`tagadanar/medium-scraper`) Actor

Latest Medium articles for any tag, author or publication: title, author, publication, tags, publish date, reading time, member-only flag and the full text of free stories. Filter by date, dedupe across sources. No API key, no login.

- **URL**: https://apify.com/tagadanar/medium-scraper.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** News, SEO tools, Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.05 / 1,000 articles

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Medium Scraper: the newest Medium articles by tag, author or publication

Give it Medium tags, authors or publications and get back their newest articles as clean rows: title, author, publication, tags, publish and update dates, reading time, a member-only flag and, if you ask for it, the full text of free stories.

Schedule it daily with **Published after** set to yesterday and you have a new-article feed for a topic, a competitor's blog or a creator, without opening Medium.

$1.50 per 1,000 articles, platform usage included. No API key, no login.

### What you get

One row per article:

| Field | Description |
| --- | --- |
| `articleId`, `url` | The article (tracking parameters removed) |
| `title` | Title |
| `summary` | The story's snippet, or its first 300 characters when the full text is available |
| `author`, `authorHandle` | Who wrote it (`@handle` when Medium shows one) |
| `publication`, `publicationSlug` | The publication's name (when you scrape a publication) and its slug or domain |
| `publishedAt`, `updatedAt` | ISO dates |
| `tags` | The tags the author gave the story |
| `imageUrl` | Lead image |
| `isMemberOnly` | `true` for stories behind Medium's paywall, `false` for free ones. `null` for tag results (see limits) |
| `wordCount`, `readingTimeMinutesApprox` | Length and reading time at 238 words per minute, for free stories |
| `fullText` | Plain-text article body, only with **Include full article text** and only for free stories (`null` otherwise) |
| `source` | Which input produced the row, e.g. `tag:python` or `@netflixtechblog` |
| `capturedAt` | When the row was collected |

#### Example row (real, from a run on 2026-10-16)

```json
{
  "articleId": "d62b03a96d7a",
  "url": "https://netflixtechblog.com/reliable-gpu-compute-for-large-training-inference-jobs-d62b03a96d7a",
  "title": "Reliable GPU compute for large training & inference jobs",
  "summary": "How we detect failing GPUs and network fabric, remediate machines automatically, and let long-running jobs survive hardware loss. Authors: Nick Rutigliano, Argha C, Samartha Chandrashekar Open Netflix",
  "author": "Netflix Technology Blog",
  "authorHandle": "@netflixtechblog",
  "publication": null,
  "publicationSlug": "netflixtechblog.com",
  "publishedAt": "2026-10-14T16:01:04.000Z",
  "updatedAt": "2026-10-15T05:56:37.458Z",
  "tags": ["site-reliability", "gpu", "machine-learning", "cost-efficiency", "artificial-intelligence"],
  "imageUrl": "https://cdn-images-1.medium.com/max/1024/1*d15z8m06XjWnYeauK7iXfQ.png",
  "isMemberOnly": false,
  "wordCount": 3111,
  "readingTimeMinutesApprox": 13,
  "source": "@netflixtechblog",
  "capturedAt": "2026-10-16T00:43:43.550Z"
}
```

### Who uses this

- **Content and SEO teams.** Watch what competitors and category leaders publish, which tags they use and how long their posts are.
- **Newsletter and curation builders.** Pull the newest stories under a tag or from a publication on a schedule.
- **AI and research teams.** Collect free article text by topic for summaries, trend reports or datasets.
- **Agencies and recruiters.** Track the authors and engineering blogs of the companies you follow.

### Input

| Field | What it does |
| --- | --- |
| Tags / topics | `artificial-intelligence`, `startup`, `#Data Science`, or a `medium.com/tag/...` link |
| Authors | `@ev` or a `medium.com/@...` profile link |
| Publications | `towards-data-science`, `https://medium.com/better-programming` or a publication's own domain such as `https://netflixtechblog.com` |
| Include full article text | Adds `fullText` for free stories |
| Published after | Keep only articles from this date on, e.g. `2026-10-01` |
| Max articles per source | 1 to 10 (10 is the most Medium lists per source) |

Example:

```json
{
  "tags": ["artificial-intelligence", "startup"],
  "authors": ["@netflixtechblog"],
  "publications": ["towards-data-science"],
  "includeFullText": true,
  "publishedAfter": "2026-10-01"
}
```

The same story found through several sources is delivered once.

### Pricing

Pay per article delivered, platform usage included, plus a flat start fee per run.

| Plan | Per 1,000 articles | Run start |
| --- | --- | --- |
| Free | $1.50 | $0.001 |
| Bronze | $1.35 | $0.001 |
| Silver | $1.20 | $0.001 |
| Gold | $1.05 | $0.001 |

Sources Medium has nothing for cost nothing beyond the start fee. Set a maximum charge per run and the actor stops when it is reached.

### Limits and honest caveats

- **About the newest 10 stories per source.** Medium lists only the latest 9-10 stories per tag, author or publication and offers no way to page back. This is a "what is new" scraper, not an archive downloader. Run it on a schedule to build history.
- **No claps, comments or responses count, no subtitle, no keyword search.** Those are not available without logging in to Medium; this actor does not use a login.
- **Member-only flag.** For authors and publications, a story that comes with no body is flagged `isMemberOnly: true`; free stories are `false`. Tag results carry only a snippet for every story, so the flag is `null` there. Scrape the author or publication to get it.
- **Full text** comes only for free stories of authors and publications, not for tag results and never for member-only stories.
- **Large source lists.** Medium limits how many feeds one network address may read in a row, so a list of more than ~20 sources moves across several routes and takes a few minutes. Anything the run could not read is named in its status.

### FAQ

**Do I need a Medium account or API key?** No.

**Can I scrape a whole tag or all articles of a publication?** No: Medium only exposes the newest stories per source. Schedule daily runs with Published after to collect everything going forward.

**Why is `isMemberOnly` null?** The row came from a tag. Add the author or publication as a source to learn whether the story is free.

**Why did a source return nothing?** The run status says why: the tag has no stories, no such author or publication exists, nothing was published after your date, or Medium refused the request.

### Related actors

- [Brand & News Monitor](https://apify.com/tagadanar/brand-news-monitor): Google News alerts for your brand or topics.
- [Google Trends Scraper](https://apify.com/tagadanar/google-trends-scraper): see which topics are rising before you write about them.
- [Threads Scraper](https://apify.com/tagadanar/threads-scraper): the same monitoring for Threads posts.
- [YouTube Search Scraper](https://apify.com/tagadanar/youtube-search-scraper): rank-tracked video results for a keyword.

# Changelog

This Actor's version history is a separate document: https://apify.com/tagadanar/medium-scraper/changelog.md

# Actor input Schema

## `tags` (type: `array`):

Medium tags, one per line, e.g. artificial-intelligence, startup, data-science. Spaces become dashes; a medium.com/tag/... link works too. Returns the newest stories under each tag.

## `authors` (type: `array`):

Author @handles or profile links, one per line, e.g. @ev or https://medium.com/@netflixtechblog. Returns the author's newest stories, with full text for free ones.

## `publications` (type: `array`):

Publication names or links, one per line, e.g. towards-data-science, https://medium.com/better-programming, or a publication's own domain such as https://netflixtechblog.com. Returns its newest stories, with full text for free ones.

## `includeFullText` (type: `boolean`):

Adds a plain-text fullText column. Medium only supplies it for free stories of authors and publications (member-only stories and tag results come without), and you pay the same per article either way.

## `publishedAfter` (type: `string`):

Only keep articles published on or after this date, e.g. 2026-10-01. Handy for scheduled runs that watch for new posts. Leave empty for everything Medium lists.

## `maxArticlesPerSource` (type: `integer`):

Medium lists only its newest 9-10 stories per tag, author or publication, so 10 is the most any source can return. Lower it to keep a run small. You only pay for articles delivered.

## Actor input object example

```json
{
  "tags": [
    "artificial-intelligence",
    "startup"
  ],
  "authors": [
    "@netflixtechblog"
  ],
  "publications": [
    "towards-data-science"
  ],
  "includeFullText": false,
  "maxArticlesPerSource": 10
}
```

# Actor output Schema

## `results` (type: `string`):

One item per article in the default dataset.

# 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 = {
    "tags": [
        "artificial-intelligence",
        "startup"
    ],
    "authors": [
        "@netflixtechblog"
    ],
    "publications": [
        "towards-data-science"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/medium-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 = {
    "tags": [
        "artificial-intelligence",
        "startup",
    ],
    "authors": ["@netflixtechblog"],
    "publications": ["towards-data-science"],
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/medium-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 '{
  "tags": [
    "artificial-intelligence",
    "startup"
  ],
  "authors": [
    "@netflixtechblog"
  ],
  "publications": [
    "towards-data-science"
  ]
}' |
apify call tagadanar/medium-scraper --silent --output-dataset

```

## MCP server setup

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