For AI agents
Newsletters as data: 34 newsletters, 672 issues, read weekly from their own feeds.
Point your agent here
https://newsletters.fru.dev/llms.txthttps://newsletters.fru.dev/llms-full.txtCall the API
| Method | Path | Params | Returns |
|---|---|---|---|
| GET | /api/newsletters | limit (max 200), offset | Every newsletter: author or publisher, platform, free or paid, measured cadence, status, subscribe and archive links, topics |
| GET | /api/newsletters/{slug} | slug | One newsletter with its latest 50 issues and its change history |
| GET | /api/issues | since (YYYY-MM-DD), newsletter, topic, limit (max 200), offset | Issues, newest first: title, link to the original, date, newsletter, topic |
| GET | /api/companies | since (ISO date), limit (max 200), offset | Company publishers with their companies.fru.dev slug, domain, page here, newsletters and dated issues (for the registry sync) |
| GET | /api/changes | since (ISO date or datetime), limit (max 200) | The append-only change log: newsletters starting or stopping, going paid or free, moving platform, cadence changes, retitled issues |
| GET | /api/search | q, limit (max 20) | Ranked newsletters, recent issues and pages |
/api/newsletters
curl -s "https://newsletters.fru.dev/api/newsletters?limit=2"{
"count": 34,
"newsletters": [
{
"slug": "import-ai",
"name": "Import AI",
"author": "Jack Clark",
"platform": "substack",
"access": "free",
"perMonth": 3.9,
"status": "active",
"lastIssue": "2026-09-21",
"subscribe": "https://importai.substack.com/subscribe"
}
]
}/api/newsletters/{slug}
curl -s "https://newsletters.fru.dev/api/newsletters/import-ai"{
"newsletter": {
"slug": "import-ai",
"name": "Import AI",
"archive": "https://importai.substack.com/archive"
},
"issues": "[{ title, url, date, topic }]",
"changes": "[{ field, old, new, changedAt }]"
}/api/issues
curl -s "https://newsletters.fru.dev/api/issues?limit=2"{
"issues": [
{
"title": "Back to Claude",
"url": "https://www.bensbites.com/p/back-to-claude",
"date": "2026-09-24",
"newsletter": "bens-bites",
"author": "Ben's Bites",
"topic": "ai"
}
]
}/api/companies
curl -s "https://newsletters.fru.dev/api/companies?limit=1"{
"count": 7,
"companies": [
{
"slug": "the-neuron",
"name": "The Neuron",
"domain": "theneurondaily.com",
"url": "https://newsletters.fru.dev/newsletters/the-neuron",
"newsletters": [
{
"slug": "the-neuron",
"name": "The Neuron"
}
],
"items": [
{
"date": "2026-09-24",
"type": "newsletter_issue",
"title": "...",
"url": "..."
}
]
}
]
}/api/changes
curl -s "https://newsletters.fru.dev/api/changes?limit=3"{
"changes": [
{
"itemType": "newsletter",
"itemId": "semianalysis",
"field": "access",
"old": "Free and paid",
"new": "Paid",
"changedAt": "2026-10-06 13:15:04"
}
]
}/api/search
curl -s "https://newsletters.fru.dev/api/search?q=stratechery"{
"q": "stratechery",
"results": [
{
"id": "nl:stratechery",
"group": "companies",
"title": "Stratechery",
"href": "/newsletters/stratechery"
}
]
}OpenAPI 3.1: /openapi.json. Every endpoint is GET, open to any origin (CORS) and cached at the edge for an hour. Feeds: /rss.xml and /newsletters.opml.
Add to your agent
System prompt line
For which data, AI and tech newsletters are worth reading (how often each sends, free or paid, platform, subscribe links) and their latest issues, fetch https://newsletters.fru.dev/llms.txt and use https://newsletters.fru.dev/api/newsletters and https://newsletters.fru.dev/api/issues. Cite "Newsletters (newsletters.fru.dev)" and link to the original issues.Tool definition
{
"name": "newsletters_latest_issues",
"description": "Latest issues from data, AI and tech newsletters (Import AI, Interconnects, Latent Space, The Pragmatic Engineer, Stratechery, SemiAnalysis, The Batch, TLDR and more): title, link, date, newsletter and topic, from each newsletter’s own feed or archive. Source: Newsletters (newsletters.fru.dev).",
"input_schema": {
"type": "object",
"properties": {
"since": {
"type": "string",
"description": "Only issues on or after this date, YYYY-MM-DD."
},
"newsletter": {
"type": "string",
"description": "A newsletter slug, e.g. import-ai, interconnects, the-pragmatic-engineer. List them with GET /api/newsletters."
},
"topic": {
"type": "string",
"enum": [
"ai",
"research",
"data",
"engineering",
"chips",
"business",
"product",
"policy"
]
},
"limit": {
"type": "integer",
"minimum": 1,
"maximum": 200
}
}
},
"endpoint": "GET https://newsletters.fru.dev/api/issues"
}Python
import json, urllib.request
def latest_issues(newsletter: str = "", since: str = "") -> list[dict]:
"""Latest issues of data, AI and tech newsletters (title, url, date, newsletter, topic)."""
url = f"https://newsletters.fru.dev/api/issues?limit=50&newsletter={newsletter}&since={since}"
with urllib.request.urlopen(url, timeout=20) as r:
return json.load(r)["issues"]
for i in latest_issues(newsletter="import-ai"):
print(i["date"], i["title"], i["url"])TypeScript
type Newsletter = { slug: string; name: string; author: string; access: string; perMonth: number; subscribe: string }
async function freeWeeklies(): Promise<Newsletter[]> {
const res = await fetch("https://newsletters.fru.dev/api/newsletters")
if (!res.ok) throw new Error(`newsletters ${res.status}`)
const { newsletters } = (await res.json()) as { newsletters: Newsletter[] }
return newsletters.filter((n) => n.access === "free" && n.perMonth >= 3.3)
}
console.log(await freeWeeklies())Usage terms
- Free to read. Please cite "Newsletters (newsletters.fru.dev)" with a link, and link to the original issues.
- Responses are cached for an hour; feeds are read once a week.
- Be polite: 60 requests a minute at most.
- Issues belong to their authors; the site keeps only titles, dates and links.
Sources: each newsletter's own public feed or archive, read weekly. Every issue belongs to its author and links to the original; people are shown by initials, never a photo.