# Medium Scraper - Articles, Full Text, Tags $2/1K (`om_kh/medium-scraper`) Actor

Scrape Medium articles from writers, publications (custom domains too) and tags: title, link, author, date, tags, cover image, full text, word count and reading time. Keyword and date filters, only-new mode for schedules. No login. $2 per 1,000 articles.

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

## Pricing

from $1.50 / 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 - Articles, Full Text, Tags $2/1K

Get **Medium articles** from writers, publications and tags, many at once: title, link, author, publish date, tags, cover image, **full text**, word count and reading time. Publications on their own domain (betterprogramming.pub and others) work too. **$2 per 1,000 articles**, no login.

- **Writers:** `@handle`, a profile link or `name.medium.com`. Full text of each story.
- **Publications:** slug (`better-programming`), medium.com link or the publication's own domain. Full text of each story.
- **Tags:** `artificial-intelligence`, `python`, `startup`... The latest stories with a summary.
- **Filters:** only articles mentioning your keywords (title, tags or text), only articles published after a date.
- **Only new articles** for scheduled runs: each run delivers only what you have not received yet. Ideal for newsletters, research feeds and AI pipelines.
- Plain text for AI and spreadsheets, and the original HTML (images, links) when you want it.

### Free tier — 10 results free on every run

**The first 10 results of every run are free**, on every run you ever make — not a one-off trial. One guard: the free allowance never covers more than half of a run, so the offer stays sustainable.

### Price

| | Price |
|---|---|
| Article | **$2 per 1,000** ($0.002 each) |

Set **Max cost per run** and the run stops before it spends more. Feeds that fail and articles your filters drop are never charged.

The most used Medium Actor in Apify Store (moving_beacon-owner1/medium-scraper) charges $10 per 1,000 articles (read on 2026-10-22): this Actor is 5 times cheaper.

### What Medium allows, honestly

This Actor reads the RSS feeds Medium publishes for every writer, publication and tag. Each feed lists the **latest 10 stories**. Medium's article pages and search sit behind a Cloudflare check, which this Actor does not try to get around. So: perfect for following writers, publications and topics over time (schedule it daily with "Only new articles"), not for downloading a writer's whole archive.

### Input example

```json
{
  "users": ["@JoeyColeman"],
  "publications": ["better-programming", "https://betterprogramming.pub"],
  "tags": ["artificial-intelligence"],
  "keywords": ["agent", "RAG"],
  "onlyNewArticles": true
}
```

### Output example

One real row from a run on Apify:

```json
{
  "type": "article",
  "articleId": "bf37baef8f27",
  "title": "Let a thousand programming publications bloom.",
  "url": "https://medium.com/better-programming/let-a-thousand-programming-publications-bloom-bf37baef8f27",
  "author": "Tony Stubblebine",
  "publishedAt": "2023-11-10T18:18:10Z",
  "tags": [],
  "imageUrl": "https://cdn-images-1.medium.com/max/1024/1*tKikPWjE4MZ5WgdfZuyvEg.png",
  "fullText": true,
  "wordCount": 1298,
  "readingTimeMinutes": 5,
  "text": "I’m putting Better Programming on hiatus to make room for other programming publications.
I get that this is a big pivot given that we switched to a new editor recently. But things...",
  "feedType": "publication",
  "feedName": "Better Programming - Medium",
  "feedUrl": "https://medium.com/feed/better-programming"
}
```

#### Every field

| Field | What it holds |
|---|---|
| `articleId` | Medium article ID |
| `title` | title |
| `url` | article link |
| `author` | writer |
| `publishedAt` | publish time |
| `updatedAt` | last update |
| `tags` | tags |
| `imageUrl` | cover image |
| `text` | article text (full when Medium's feed carries it) |
| `fullText` | true when the full text is included |
| `wordCount` | words |
| `readingTimeMinutes` | reading time (minutes) |
| `feedType` | writer, publication or tag |
| `feedName` | feed name |
| `feedInput` | what you entered |
| `feedUrl` | feed read |

### Use cases

- **Content and newsletter curation:** every new story from the writers and publications you follow, in one table.
- **AI and RAG pipelines:** clean full text with author, date and tags, ready to embed.
- **Topic monitoring:** schedule a tag or keyword and get each new story about your brand, market or technology.
- **Influencer and writer research:** who writes about your topic, how often and how long.

### Why use it

1. **Try before you pay.** The first 10 results of every run are free.
2. **Pay only for data delivered.** Failed feeds and filtered articles are never billed.
3. **Hard cost cap.** Set `maxTotalChargeUsd` and a run never costs more than you allow.
4. **Ready to use.** JSON, CSV or Excel, the Apify API, n8n, Make, Zapier, or as an MCP tool for AI agents.

### How to use it in 3 steps

1. Click **Try for free**; the form opens with a ready example in **Writers** and **Publications**.
2. Optional: add tags, keywords or a date; every field has a description.
3. Click **Start** and download the results as JSON, CSV or Excel, or read them from the API.

### FAQ

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

**Can I get member-only (paywalled) stories?** You get what Medium's public feed shows; for member-only stories that is usually the beginning of the story.

**Can I search all of Medium by keyword?** Medium's search is behind a Cloudflare check. Use tags and the keyword filter instead.

**Can I call it from code?** Yes: Apify API, Python and JavaScript clients, Make, Zapier, n8n, or as an MCP tool.

# Actor input Schema

## `users` (type: `array`):

Medium writers: @handle, handle or profile link (medium.com/@name or name.medium.com). Full text included.

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

Medium publications: slug (better-programming), medium.com link or the publication's own domain (betterprogramming.pub). Full text included.

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

Medium tags (artificial-intelligence, python, startup...). Tag feeds give the latest stories with a summary, not the full text.

## `feedUrls` (type: `array`):

Any Medium-hosted site or feed link. Read like a publication.

## `keywords` (type: `array`):

Keep only articles whose title, tags or text contain one of these words (case-insensitive). Leave empty for every article.

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

Keep only articles published on or after this date.

## `includeHtml` (type: `boolean`):

Adds the original HTML of each article (with images and links) next to the plain text.

## `onlyNewArticles` (type: `boolean`):

Each run delivers only articles you have not received yet.

## `monitorId` (type: `string`):

With 'Only new articles', keeps separate memories for separate schedules.

## `maxTotalChargeUsd` (type: `number`):

The run stops before it would cost more than this.

## Actor input object example

```json
{
  "users": [
    "@JoeyColeman"
  ],
  "publications": [
    "better-programming"
  ],
  "includeHtml": false,
  "onlyNewArticles": false
}
```

# Actor output Schema

## `report` (type: `string`):

A visual summary of delivery, charges, changes, and source issues.

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

Business-ready results in a sortable table. No JSON knowledge required.

## `csv` (type: `string`):

Results ready for spreadsheets, CRMs, and analytics tools.

## `excel` (type: `string`):

Results as an Excel workbook for non-technical teams.

## `runSummary` (type: `string`):

Machine-readable delivery, billing, and source diagnostics.

# 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 = {
    "users": [
        "@JoeyColeman"
    ],
    "publications": [
        "better-programming"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("om_kh/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 = {
    "users": ["@JoeyColeman"],
    "publications": ["better-programming"],
}

# Run the Actor and wait for it to finish
run = client.actor("om_kh/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 '{
  "users": [
    "@JoeyColeman"
  ],
  "publications": [
    "better-programming"
  ]
}' |
apify call om_kh/medium-scraper --silent --output-dataset

```

## MCP server setup

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