# Medium Articles by Author, Publication or Tag (`usta/medium-articles`) Actor

For content strategists: one table of Medium articles by author, publication or tag, from public RSS, with title, author, date, tags, signed-out preview and URL.

- **URL**: https://apify.com/usta/medium-articles.md
- **Developed by:** [US Tech Automations](https://apify.com/usta) (community)
- **Categories:** Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 result rows

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

## Medium Articles by Author, Publication or Tag

This medium scraper lists medium articles for the authors, publications, or tags you name, one public-feed row each, billed pay per result.

It reads Medium's public RSS feeds (`medium.com/feed/...`) the same way a signed-out visitor's feed reader does. Each article becomes one row: title, author, date, tags, the short preview Medium puts in the feed, and the canonical URL. Claps and reading time are included when the public feed shows them; on the feeds checked here they were not shown, so those fields are left empty rather than guessed. Member-only story text is never returned.

### Input

Give at least one of:

- **Author handles** — `tomaspueyo`, `@tomaspueyo`, or a profile URL
- **Publications** — a slug such as `towards-data-science` or a `medium.com` publication URL
- **Tags** — `python` or `https://medium.com/tag/python`

**Maximum rows** is the spend cap. Several named feeds are merged and de-duplicated by article id.

Apify Proxy is optional and **off** by default.

Input used for the live local run:

```json
{
  "authors": ["tomaspueyo"],
  "publications": [],
  "tags": ["python"],
  "maxItems": 15,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output (one row per article)

| Field | What it holds |
|---|---|
| `title` | Headline as published in the feed |
| `author` | Public display name (`dc:creator`) |
| `date` | Publication time, UTC |
| `claps` | Clap count if the public feed or public page shows one; otherwise empty |
| `reading_time` | Reading time if shown; otherwise empty |
| `tags` | Category tags from the feed; an empty list when Medium listed none |
| `preview` | The signed-out snippet from the feed, not the full story |
| `canonical_url` | Article URL with tracking query removed |
| `article_id` | Medium's public story id |
| `source_type` / `source_query` | Which input produced this row (`author`, `publication`, or `tag`) |
| `source_url` | Same as `canonical_url` |
| `fetched_at` | When this run read the feed, UTC |
| `error` | Empty on a normal article row |

One row from a live run on 2026-09-20 (15 rows, two feed requests):

```json
{
  "title": "What China Wants and Why",
  "author": "Tomas Pueyo",
  "date": "2026-07-20T04:52:15Z",
  "claps": null,
  "reading_time": null,
  "tags": ["history", "geography", "china", "geopolitics", "maps"],
  "preview": "Why is China increasing its assertiveness towards Taiwan? Why the Belt and Road initiative? Why the oppression of Uighurs? Why the…",
  "canonical_url": "https://tomaspueyo.medium.com/what-china-wants-and-why-390de6b595e5",
  "article_id": "390de6b595e5",
  "source_type": "author",
  "source_query": "tomaspueyo",
  "source_url": "https://tomaspueyo.medium.com/what-china-wants-and-why-390de6b595e5",
  "fetched_at": "2026-09-20T21:45:56Z",
  "error": null
}
```

### Pricing

**Pay per result.** Every article row bills at the listed store price from row one. There is no start fee. A run that returns zero rows costs nothing. **Maximum rows** is the most a single run can cost.

### Limits (measured on 2026-09-20)

- Each public Medium RSS feed returned **10** items (`@tomaspueyo`, tag `python`, publication `towards-data-science`).
- Feeds are requested **one second apart**.
- A missing author/publication/tag is HTTP 404 and adds no article rows.
- Signed-out HTML article pages from this machine were answered **HTTP 403** (Cloudflare). RSS feeds were HTTP 200.

### What this does not do

- Does not log in, use cookies, or open a saved session.
- Does not return member-only story text. Only the public feed preview.
- Does not invent claps or reading time when Medium does not show them.
- Does not use Medium search (`/search?q=` is disallowed in robots.txt).
- Does not call Medium's authenticated API and does not create a Medium account.
- Does not paginate older stories beyond what each public feed returns.

### Refunds and support

Refunds: if a run returns zero rows for a valid input, email operations@ustechautomations.com within 7 days and we refund that run. Support: same address, replies within 2 business days.

# Actor input Schema

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

Medium handles, with or without @, or profile URLs. Example: tomaspueyo or https://medium.com/@tomaspueyo.

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

Publication slugs or medium.com publication URLs. Example: towards-data-science or https://medium.com/towards-data-science.

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

Tag slugs or tag URLs. Example: python or https://medium.com/tag/python.

## `maxItems` (type: `integer`):

Hard ceiling on rows returned, and therefore on the cost of the run. Every row bills at the listed price from row one; there is no start fee. Each Medium RSS feed typically holds about ten latest items.

## `proxyConfiguration` (type: `object`):

Optional. Apify Proxy is off by default. Turn it on only if Medium blocks the Actor IP. Local runs do not use a proxy.

## Actor input object example

```json
{
  "authors": [
    "tomaspueyo"
  ],
  "publications": [],
  "tags": [
    "python"
  ],
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `articles` (type: `string`):

No description

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

No description

## `report` (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 = {
    "authors": [
        "tomaspueyo"
    ],
    "tags": [
        "python"
    ],
    "maxItems": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("usta/medium-articles").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 = {
    "authors": ["tomaspueyo"],
    "tags": ["python"],
    "maxItems": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("usta/medium-articles").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 '{
  "authors": [
    "tomaspueyo"
  ],
  "tags": [
    "python"
  ],
  "maxItems": 25
}' |
apify call usta/medium-articles --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,usta/medium-articles"
        }
    }
}
```

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/vtuc0iEsegf1UZHeM/builds/7neEbjQd2AR3FRQad/openapi.json
