Substack API: Search newsletters
Finds public Substack newsletters matching a topic, in Substack's search order. Subscriber counts are null when Substack does not display one.
Unofficial. Not affiliated with or endorsed by Substack.
Inputs
Values from the run on Oct 23, 2026, shown under Output.
- Topic, required
topic Words describing newsletters to find, for example, product management.
personal finance
- Max Results optional
max_results Maximum newsletters to return, for example, 20.
50
Whole number from 1 to 50. Default
20.
Input as JSON
{ "topic": "personal finance", "max_results": 50}Output
{ "newsletters": [ { "name": "Beyond Your Budget", "author": "Michela Allocca", "description": "Helping you reach your 6-figure savings goals!", "logo_image_link": "https://substackcdn.com/image/fetch/$s_!r3xM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F32003b2c-1b1f-4ba0-bc06-767055ffd484_630x630.png" , "newsletter_link": "https://breakyourbudget.substack.com" , "subscriber_count": "Over 10,000 subscribers", "offers_paid_subscriptions": true }, { "name": "The Crunch", "author": "The Money Cruncher, CPA", "description": "The Crunch provides weekly tips to ordinary people on how to build wealth. \n\nMy weekly newsletter arrives in your inbox every Saturday and tells you everything you need to know about personal finance in just 5 minutes.", "logo_image_link": "https://substackcdn.com/image/fetch/$s_!vbpr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e4f1095-bf04-44be-aa64-2189474d599e_1280x1280.png" , "newsletter_link": "https://thecrunchcpa.substack.com" , "subscriber_count": "Over 4,000 subscribers", "offers_paid_subscriptions": true }, { "name": "The Finance Notebook📝", "author": "The Finance Notebook📝", "description": "By Yukti Manglani | A finance student documenting what I learn- one concept, one insight, one day at a time.", "logo_image_link": "https://substackcdn.com/image/fetch/$s_!sv9p!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F09aaa04a-108c-43ed-ae84-4fc48d468594_1170x1170.png" , "newsletter_link": "https://yuktimanglani.substack.com" , "subscriber_count": "Over 15,000 subscribers", "offers_paid_subscriptions": false } ]}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"substack.com/search_newsletters","input":{"topic":"personal finance","max_results":50}}' # 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": "substack.com/search_newsletters" , "input": { "topic": "personal finance", "max_results": 50 }})# 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": "substack.com/search_newsletters" , "input": { "topic": "personal finance", "max_results": 50 } }), 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 substack.com/search_newsletters# with {"topic":"personal finance","max_results":50}"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": [ "topic" ], "properties": { "topic": { "type": "string", "minLength": 1, "description": "Words describing newsletters to find, for example, product management." }, "max_results": { "type": "integer", "default": 20, "maximum": 50, "minimum": 1, "description": "Maximum newsletters to return, for example, 20." } }}Output schema
{ "type": "object", "required": [ "newsletters" ], "properties": { "newsletters": { "type": "array", "items": { "type": "object", "required": [ "name", "author", "description", "subscriber_count", "offers_paid_subscriptions", "logo_image_link", "newsletter_link" ], "properties": { "name": { "type": "string" }, "author": { "type": [ "string", "null" ] }, "description": { "type": [ "string", "null" ] }, "logo_image_link": { "type": [ "string", "null" ] }, "newsletter_link": { "type": "string" }, "subscriber_count": { "type": [ "string", "null" ], "description": "Subscriber count as shown on Substack, or null when not displayed." }, "offers_paid_subscriptions": { "type": "boolean" } }, "additionalProperties": false }, "description": "Matching newsletters in Substack search order." } }, "additionalProperties": false}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
substack.com/search_newsletters- Returns
- name, author, description, subscriber count, paid subscription flag, logo, newsletter 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 substack.com/search_newsletters with the inputs above.
Ask your agent
- Find me public newsletters about product management on Substack, up to 10 results.
- Which climate change newsletters have the most subscribers? Show me the top 20 from Substack.
- I need paid newsletters on personal finance and investing, with their authors and descriptions.
- Look up indie game development newsletters and include their logos and links, max 15.
- Search for Substack newsletters covering remote work tips, showing whether each one is paid.
See more
All Substack methodsFinds a Substack newsletter by name or web address and returns its latest public posts with dates, authors, access level and engagement counts.
substack.com/list_newsletter_postsLists 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_articlesFinds an ESPN league or team by name and lists the latest headlines ESPN publishes for it, newest first.
espn.com/list_newsLists the current top Google News stories, overall or for one topic, in a chosen country and language edition.
news.google.com/list_top_storiesFinds upcoming public Meetup events by topic and city, sorted by start time. Only events that mention the topic are included; external costs and undisclosed venues may not be shown.
meetup.com/search_eventsFinds Polymarket prediction markets about a topic, ranked by total trading volume, with outcome chances and market details.
polymarket.com/search_marketsFinds Product Hunt products by name or by what they do, in Product Hunt search order, with tagline, review rating, review count, followers and topics. Ratings are null for products without reviews.
producthunt.com/search_productsFinds the best-matching Britannica encyclopedia article for a topic and returns its introduction, quick facts, section headings, update date and main image.
britannica.com/get_article