Inkpluck — Article Extractor: URL to Text, Markdown & Metadata avatar

Inkpluck — Article Extractor: URL to Text, Markdown & Metadata

Pricing

$1.00 / 1,000 article extracteds

Go to Apify Store
Inkpluck — Article Extractor: URL to Text, Markdown & Metadata

Inkpluck — Article Extractor: URL to Text, Markdown & Metadata

Article extractor API for news, blogs and docs: URLs or HTML in, clean text + Markdown, title, authors, publish date, language, top image, videos and paywall flag out. newspaper3k-compatible fields. $0.001 per article; failures free.

Pricing

$1.00 / 1,000 article extracteds

Rating

0.0

(0)

Developer

CyberMax

CyberMax

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

Inkpluck: Article Extractor API, URL to Text, Markdown & Metadata

Article extractor: URL in, clean article out. Give Inkpluck news articles, blog posts or docs pages and get back the clean article text (paragraphs kept), Markdown (headings, lists, links, images and tables kept), the title, authors, publish and update dates, language, site name, section, tags, top image, images and embedded videos, plus a paywall flag, word count and reading time. No navigation, ads, cookie banners, "related stories" or footers. A maintained successor to newspaper3k (last release 2018), with the same field names available.

$0.001 per article extracted. Failures are free. No start fee and no subscription. Pages that fail to load, bot walls, PDFs, JavaScript-only pages, paywalled teasers and pages with too little text cost nothing.

Why Inkpluck

  • Metadata from the source, not guesses. Authors and dates come from the publisher's own schema.org JSON-LD (NewsArticle, BlogPosting, @graph), OpenGraph and article:* tags, Parsely/Sailthru/Dublin Core/citation meta tags and bylines, then the date in the URL (/2024/05/12/…). Dates are normalised to ISO 8601 UTC, and author lists are cleaned ("By Jane Doe and John Smith" becomes ["Jane Doe", "John Smith"]; "Staff", "About the author" and profile URLs are dropped).
  • Text you can feed straight to an LLM. Mozilla Readability (the engine behind Firefox Reader View) finds the article body; Inkpluck then writes plain text with blank lines between paragraphs, list items as - …, table rows as a | b, and captions left out, plus a separate Markdown version with links and tables. The headline is its own field and is not repeated in the text.
  • Knows what isn't an article. Home pages, section pages (/news, /tech) and teaser grids get looksLikeArticle: false. Turn on onlyArticles and they come back as free failures, handy when you feed it crawled link lists.
  • Paywalls are flagged, not hidden. paywalled: true when the publisher marks the article as subscriber content (isAccessibleForFree: false) or only a teaser is visible. A teaser with too little text is a free failure.
  • Fast and cheap because it's plain HTTP. No headless browser: a typical article takes 0.5–3 s, and runs start in seconds. Charset detection handles old Windows-1252/ISO-8859 sites; CJK word counts are correct.
  • Blocked? One automatic retry through Apify Proxy when a site answers 403/429/503 to a direct request, or send everything through your own proxy settings (e.g. residential).
  • Watch feeds, get each new article once. Give it RSS/Atom feeds (feedUrls) and turn on onlyNew: every run extracts only the articles it hasn't extracted before. Put it on an Apify Schedule and you have a daily "new articles as Markdown" feed for your agent, newsletter or RAG index.
  • Already have the HTML? Pass htmlDocuments and nothing is fetched.
  • newspaper3k drop-in. newspaper3kFields: true adds publish_date, top_image, movies, meta_lang, meta_description, meta_keywords, canonical_link and source_url next to title, authors, text, images.

Ready-made inputs (first try in one click)

Copy one into the Input tab (JSON view). Each finishes in seconds and costs a few tenths of a cent.

Two articles to text + Markdown (the Store's default input):

{ "urls": ["https://techcrunch.com/2026/09/23/meta-introduces-camera-free-ai-glasses/", "https://blog.cloudflare.com/vary-support/"] }

Latest posts from an RSS feed, only new ones on each run (pair with a daily Schedule):

{ "feedUrls": ["https://blog.cloudflare.com/rss/"], "maxArticlesPerFeed": 5, "onlyNew": true, "monitorName": "cloudflare-blog" }

newspaper3k drop-in (same field names as newspaper.Article):

{ "urls": ["https://blog.cloudflare.com/vary-support/"], "newspaper3kFields": true, "onlyArticles": true }

Example

Input:

{
"urls": [
"https://blog.cloudflare.com/vary-support/",
"https://www.theguardian.com/world/2026/sep/23/harvey-weinstein-sentencing-prison",
"bbc.com/news"
],
"onlyArticles": true,
"newspaper3kFields": true
}

Output (one record per URL; a real record from a real run, text shortened here):

{
"url": "https://blog.cloudflare.com/vary-support/",
"finalUrl": "https://blog.cloudflare.com/vary-support/",
"ok": true,
"title": "We just shipped support for the ugliest part of HTTP: Vary",
"authors": ["Alex Krivit", "Zaidoon Abd Al Hadi"],
"publishDate": "2026-09-22T14:04:31.803Z",
"modifiedDate": "2026-09-22T14:04:31.803Z",
"siteName": "Cloudflare Blog",
"language": "en",
"description": "Vary support is now available in Cache Rules on every plan. …",
"section": null,
"tags": [],
"topImage": "https://blog.cloudflare.com/_emdash/api/media/file/01M34KKV86R35ZHS0THH5PGPVZ.01M34KKW3REWTTYD2ZHH5261DV.png",
"images": [],
"videos": [],
"text": "The response header, Vary, has been called “the ugliest part of HTTP that we haven't yet improved.” …",
"markdown": "The response header, `Vary`, has been called “[the ugliest part of HTTP that we haven't yet improved.](https://mnot.net/blog/2026/linting_the_web)” …",
"wordCount": 2695,
"readingTimeMinutes": 11,
"looksLikeArticle": true,
"paywalled": false,
"canonicalUrl": "https://blog.cloudflare.com/vary-support/",
"publish_date": "2026-09-22T14:04:31.803Z",
"top_image": "https://blog.cloudflare.com/_emdash/api/media/file/01M34KKV86R35ZHS0THH5PGPVZ.01M34KKW3REWTTYD2ZHH5261DV.png",
"movies": [],
"meta_lang": "en",
"canonical_link": "https://blog.cloudflare.com/vary-support/",
"source_url": "https://blog.cloudflare.com",
"httpStatus": 200,
"fetchedVia": "direct",
"extractedAt": "2026-09-23T23:45:10.863Z"
}

A home page with onlyArticles on (not charged):

{ "url": "https://www.bbc.com/news", "ok": false, "looksLikeArticle": false, "wordCount": 1281,
"error": "not an article (home, section or listing page) and onlyArticles is on" }

In the same test batch, articles from the BBC, The Guardian, The Verge, Smashing Magazine, fly.io and Japanese Wikipedia all came back with their bylines and dates (full outputs in examples/).

Input

FieldDefaultWhat it does
urlsArticle URLs, one per line (https:// optional; duplicates skipped)
feedUrlsRSS/Atom feeds; their newest items are extracted
maxArticlesPerFeed20Newest items taken from each feed
onlyNewfalseMonitor mode: skip URLs extracted by earlier runs (free, no record)
monitorNamedefaultSeparate memory per watch list (kept in a named key-value store in your account)
htmlDocuments[{"url", "html"}]: extract HTML you already have, without fetching
onlyArticlesfalseHome/section/listing pages become free failures
outputMarkdowntrueAdd the markdown field
includeHtmlfalseAdd the cleaned article body as html
newspaper3kFieldsfalseAdd newspaper3k's attribute names
minWords50Fewer words of article text = free failure
maxConcurrency10Pages processed in parallel
timeoutSecs20Per-page timeout (one automatic retry on network errors/5xx)
retryBlockedWithProxytrueRetry 403/429/503 pages once through Apify Proxy
proxyConfigurationnoneSend every request through this proxy
startUrlsSame as urls, in the [{"url": …}] format

Output

One dataset record per input, in the order they finish. ok: true records are charged and have the article fields above; ok: false records are free and carry an error (HTTP 403 (the site blocked the request), not an HTML page (application/pdf), paywalled: only 38 words are visible…,

no article text in the page HTML (the page is built by JavaScript in the browser)
, not a valid http(s) URL…). Views: Articles (overview table) and Text.

Pricing

$0.001 per article extracted (event article-extracted), no start fee. 1,000 articles cost at most $1. Everything with ok: false is free.

For comparison (Apify Store, 23 Sep 2026): the most-used article Actor is free but crawls whole sites with a browser (you pay the compute, and ~5% of its public runs in the last 30 days failed or timed out); per-article Actors charge from about $0.003 per article plus a start fee of up to $0.09 per run.

Benchmark

Same 6 articles (The Guardian, BBC, The Verge, TechCrunch, Smashing Magazine, Cloudflare blog), each Actor with its default settings, run on Apify on 23 Sep 2026. Rivals are the most-used article extractors on the Apify Store.

Articles returnedWith authorWith dateWith top imageWith languageRun timePrice for the 6
Inkpluck6/666666.5 s$0.006
Rival A6/6466016.9 s$0.19 (two start fees + per article)
Rival B4/6 (2 missing, 3 unrequested pages; run ended FAILED)444010.6 s$0.017
Rival C6/6 (one article cut to 183 of ~1,240 words)56364.2 s$0.03

The most-used (free) rival could not be tested: it only runs after you grant it full access to your Apify account. Inkpluck needs no special permissions.

Run it on a schedule (monitor mode)

Watch feeds and get every new article exactly once, as Markdown, every morning:

  1. Create a task from this Actor with this input (free to save):
    { "feedUrls": ["https://techcrunch.com/feed/", "https://blog.cloudflare.com/rss/"], "onlyNew": true,
    "monitorName": "tech-news", "onlyArticles": true }
  2. In Apify Console → Schedules → Create, pick the task and a cron such as 0 7 * * * (07:00 daily).
  3. Connect the output: a webhook, the Make/Zapier/n8n integration below, or read the task's last dataset with GET https://api.apify.com/v2/actor-tasks/<task-id>/runs/last/dataset/items?token=<TOKEN>.

Only new articles are charged, so a schedule on 20 feeds that publish 50 new posts a day costs about $0.05 a day.

Integrations

  • Make: add the Apify → Run an Actor module (Actor cybermax/article-extract, "Run synchronously" on), then Apify → Get dataset items and map title, authors, publishDate, markdown to Notion, Airtable or Slack.
  • Zapier: Apify → Actor Run Finished trigger for your scheduled task, then Apify → Find Last Dataset Items; send each article to Google Docs, Slack or an email digest.
  • n8n: the Apify node (Run Actor and get dataset) with {"urls": {{ $json.links }}}, then an AI Agent node to summarise each markdown.
  • Google Sheets: =IMPORTDATA("https://api.apify.com/v2/actor-tasks/<task-id>/runs/last/dataset/items?format=csv&fields=title,authors,publishDate,wordCount,url&token=<TOKEN>") gives a live sheet of the latest articles. Use a separate, limited-permission Apify token here: anyone who can open the sheet can see it.
  • JavaScript:
    import { ApifyClient } from 'apify-client';
    const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
    const run = await client.actor('cybermax/article-extract').call({ urls: ['https://blog.cloudflare.com/vary-support/'] });
    const { items } = await client.dataset(run.defaultDatasetId).listItems();
    console.log(items[0].title, items[0].authors, items[0].markdown.slice(0, 200));
  • Python (newspaper3k migration):
    from apify_client import ApifyClient
    client = ApifyClient("<APIFY_TOKEN>")
    run = client.actor("cybermax/article-extract").call(run_input={"urls": urls, "newspaper3kFields": True})
    for a in client.dataset(run["defaultDatasetId"]).iterate_items():
    if a["ok"]:
    print(a["title"], a["authors"], a["publish_date"], a["text"][:200])
  • AI agents (MCP): see below.

Use it from an AI agent (MCP)

  • Apify MCP server: connect your MCP client (Claude, Cursor, VS Code, LangChain, n8n…) to https://mcp.apify.com/?tools=cybermax/article-extract with your Apify token. The agent gets one tool that takes {"urls": [...]} and returns the records above.
  • API (synchronous): POST https://api.apify.com/v2/acts/cybermax~article-extract/run-sync-get-dataset-items?token=<TOKEN> with the input JSON returns the records directly.
  • Typical agent prompts: "Read these 20 links and summarise each", "Who wrote this article and when?", "Turn this blog post into Markdown for my notes", "Build a RAG corpus from these URLs".

When NOT to use it

  • Crawling a whole site to discover articles. Inkpluck extracts the URLs and feed items you give it; it doesn't follow links. Sites without a feed need their URLs from a sitemap or a search first.
  • Pages rendered only by JavaScript (some single-page apps). Inkpluck reads the HTML the server sends, without a browser; such pages return a free failure that says so.
  • Hard bot walls and logins. Sites like AP News, Reuters and the New York Times block data-centre IPs, including Apify's default proxy; use a residential proxy in proxyConfiguration, or expect a free failure. Inkpluck never logs in and never gets around paywalls.
  • PDFs, images, video transcripts. HTML only.
  • Republishing. Articles are the publishers' copyright. Use the output for reading, analysis, search, summaries and research, and link to the source.

FAQ

Is this a newspaper3k replacement? For Article(url).download(); .parse(), yes: the same fields (title, authors, publish_date, text, top_image, images, movies, meta_*, canonical_link), maintained, with Markdown and paywall detection on top. It does not do newspaper3k's nlp() keywords/summary; pass the text to your LLM instead.

Am I charged for failures? No. Only records with "ok": true are charged.

How accurate are dates and authors? They come from the publisher's own structured data first, so they are what the site itself declares. Pages without any date markup get the date in their URL, or null; Inkpluck never invents a date.

Does it respect sites? It fetches each URL once, like a browser's first visit, with no crawling, no login and no personal data beyond the public byline.

Also from CyberMax

All tools: apify.com/cybermax.

© 2026 CyberMax. All rights reserved.