Medium API: Read an article
Reads a public Medium article from its link, including publication-domain links: details, engagement counts, tags and the plain-text paragraphs. Member-only stories include only the publicly visible preview.
Unofficial. Not affiliated with or endorsed by Medium.
Inputs
Values from the run on Oct 31, 2026, shown under Output.
- Article, required
article Link to a Medium article, including a publication's own domain, such as https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1.
https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1
Input as JSON
{ "article": "https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1" }Output
{ "tags": [ "Writing", "Community", "Mission" ], "claps": 29, "title": "Why I Only Write for Medium", "author": "Taras J Seaks", "subtitle": "And why this story is free to read", "responses": 2, "paragraphs": [ "Why I Only Write for Medium", "And why this story is free to read", "Writers don’t just write to write. In some cases, we do. But in most cases, it’s to share an important message. This is as true for novels as it is for self-development content and everything surrounding them." ], "member_only": false, "publication": null, "article_link": "https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1" , "published_date": "2024-03-20", "main_image_link": "https://miro.medium.com/0*nwz5ReKI2u2dF-AV" , "full_text_available": true, "reading_time_minutes": 6}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"medium.com/read_article","input":{"article":"https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1"}}' # Save as fous.py, then run: python3 fous.pyimport json, os, timefrom urllib.error import HTTPErrorfrom urllib.request import Request, urlopenAPI = "https://api.fous.com/v1/runs" KEY = os.environ["FOUS_API_KEY"]HEADERS = { "Authorization": f"Bearer {KEY}", "Content-Type": "application/json" ,}def call(url, body=None): data = json.dumps(body).encode() if body else None request = Request(url, data, HEADERS) try: with urlopen(request, timeout=120) as r: return r.status, json.load(r) except HTTPError as error: message = json.load(error)["error"]["message"] raise RuntimeError(message) from errorstatus, run = call(API, { "method": "medium.com/read_article" , "input": { "article": "https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1" }})# 202: still going after 30 s. Ask again until it ends.while status == 202: time.sleep(2) status, run = call(f"{API}/{run['id']}")print(json.dumps(run["data"], indent=2))// Save as fous.mjs, then run: node fous.mjsconst api = "https://api.fous.com/v1/runs" ;const headers = { Authorization: `Bearer ${process.env.FOUS_API_KEY}`, "Content-Type": "application/json" ,};let response = await fetch(api, { method: "POST", headers, body: JSON.stringify({ "method": "medium.com/read_article" , "input": { "article": "https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1" } }), signal: AbortSignal.timeout(120_000),});let run = await response.json();// 202: still going after 30 s. Ask again until it ends.while (response.status === 202) { await new Promise((done) => setTimeout(done, 2_000)); response = await fetch(`${api}/${run.id}`, { headers }); run = await response.json();}if (!response.ok) throw new Error(run.error.message);console.log(run.data);# Connect your agent to Fous once, over MCP (Streamable HTTP):# https://api.fous.com/mcp# Set FOUS_API_KEY first: create a key at https://app.fous.com/keys.# Claude Codeclaude mcp add \ --scope user \ --transport http fous https://api.fous.com/mcp \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Codexcodex mcp add fous \ --url https://api.fous.com/mcp \ --bearer-token-env-var FOUS_API_KEY# Cursor, VS Code, Windsurf, Cline and morenpx -y add-mcp https://api.fous.com/mcp -g -n fous \ --header "Authorization: Bearer ${FOUS_API_KEY:?Set FOUS_API_KEY to your Fous API key}"# Then ask your agent:# "Use Fous to run medium.com/read_article# with {"article":"https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1"}"Over HTTP, the answer’s data holds the output. A run still going after 30 seconds answers 202 with its id: ask GET /v1/runs/{id} until it ends.
Schema
Input schema
{ "type": "object", "required": [ "article" ], "properties": { "article": { "type": "string", "description": "Link to a Medium article, including a publication's own domain, such as https://medium.com/@tarasjseaks/why-i-only-write-for-medium-0b8c500134a1." } }}Output schema
{ "type": "object", "required": [ "title", "subtitle", "author", "publication", "published_date", "reading_time_minutes", "claps", "responses", "tags", "member_only", "full_text_available", "paragraphs", "main_image_link", "article_link" ], "properties": { "tags": { "type": "array", "items": { "type": "string" }, "description": "Article tags." }, "claps": { "type": "integer", "description": "Number of claps." }, "title": { "type": "string", "description": "Article title." }, "author": { "type": "string", "description": "Author name." }, "subtitle": { "type": [ "string", "null" ], "description": "Article subtitle, if any." }, "responses": { "type": "integer", "description": "Number of responses." }, "paragraphs": { "type": "array", "items": { "type": "string" }, "description": "Publicly visible text in reading order, with headings as separate paragraphs." }, "member_only": { "type": "boolean", "description": "Whether the article is member-only." }, "publication": { "type": [ "string", "null" ], "description": "Publication name, if the story is in one." }, "article_link": { "type": "string", "description": "Article page link." }, "published_date": { "type": "string", "format": "date", "description": "Original publication date." }, "main_image_link": { "type": [ "string", "null" ], "description": "Main image link, if any." }, "full_text_available": { "type": "boolean", "description": "Whether the complete text is publicly available." }, "reading_time_minutes": { "type": "integer", "description": "Reading time shown to readers, in minutes." } }}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
medium.com/read_article- Returns
- title, subtitle, author, publication, date, reading time, claps, responses, tags, member-only flag, paragraphs, image, link
Use it from your agent
Give your agent this line. It reads SKILL.md, gets a Fous API key and connects the Fous MCP server. Its run then takes the method medium.com/read_article with the inputs above.
Ask your agent
- Pull the full text and clap count from this Medium post: https://medium.com/@sarah.drasner/the-art-of-code-review-8f3c2a91d4e7
- What tags and reading time does this article have? https://towardsdatascience.com/a-gentle-introduction-to-transformers-5b2e9c7a1f04
- Can you get me the paragraphs of https://betterprogramming.pub/stop-using-console-log-for-debugging-3d91ab7c0e52 so I can summarize it?
- Check whether this Medium story is member-only and who wrote it: https://medium.com/@jameswrites/how-i-paid-off-60k-in-student-loans-a4c7e1290bd3
- How many responses and claps did https://uxdesign.cc/the-death-of-the-hamburger-menu-7e2f04b8c193 get, and when was it published?
See more
All Medium methodsLists the latest public articles by a Medium writer or publication (by username, publication name or Medium link), with dates, reading times, claps, member-only labels and tags.
medium.com/list_author_articlesLists public Medium articles for a topic, newest first or popular this week, with author, publication, reading time, claps and membership status.
medium.com/list_topic_articlesReads a CNN article by link or headline and returns its headline, summary, authors, dates, section, tags, main image and public paragraphs. Subscriber stories return only a brief public preview; live blogs include their entries.
cnn.com/read_articleReads one public Guardian article by link or headline and returns its details and available full-text paragraphs. Live blogs return the latest entries shown on the page; some older articles may be unavailable.
theguardian.com/read_articleReads an NPR article by its link or headline and returns its text and publication details. For live blogs, returns the displayed updates.
npr.org/read_articleReads the text and details of a BBC News article from its link or headline. Live coverage pages return the latest entries available.
bbc.com/read_articleReads a public Daily Mail article from its link, or from a headline (the best-matching result of the site's search), and returns its text and details; live blogs give the latest entries shown on the page.
dailymail.co.uk/read_articleReads a public TechCrunch article by link or headline and returns its text, authors, dates, section, tags and image. Live blogs return their latest public updates.
techcrunch.com/read_article