Mastodon API: List recent posts
Lists a Mastodon account's latest public posts, newest first. Replies and boosts are optional. Private and unlisted posts are left out.
Unofficial. Not affiliated with or endorsed by Mastodon.
Inputs
Values from the run on Oct 23, 2026, shown under Output.
- Account, required
account Full account handle including server, or a profile link, such as Gargron@mastodon.social.
Gargron@mastodon.social
- Max Results optional
max_results Maximum number of posts to return, for example 20.
20 (default)
Whole number from 1 to 100.
- Include Boosts optional
include_boosts Include boosts, for example true.
false (default)
True or false.
- Include Replies optional
include_replies Include replies, for example true.
false (default)
True or false.
Input as JSON
{ "account": "Gargron@mastodon.social"}Output
{ "posts": [ { "text": "RE: https://mastodon.social/@Mastodon/117411420916699261\n30% sold out as of now. Shipping should begin in early November!" , "boosts": 28, "post_id": "117461922421805136", "replies": 1, "is_boost": false, "post_link": "https://mastodon.social/@Gargron/117461922421805136" , "posted_at": "2026-10-18T12:31:37Z", "favourites": 46, "image_links": [], "content_warning": null, "original_author": null }, { "text": "It’s been a million years since i posted a picture of myself. Taken by @Ameboid.", "boosts": 51, "post_id": "117457641525342383", "replies": 31, "is_boost": false, "post_link": "https://mastodon.social/@Gargron/117457641525342383" , "posted_at": "2026-10-17T18:22:55Z", "favourites": 431, "image_links": [ "https://files.mastodon.social/media_attachments/files/117/457/624/371/113/321/original/fbe3b78d73917a55.jpeg" ], "content_warning": null, "original_author": null }, { "text": "Heh. I misremembered the date--thought it was today, but looks like it was October 5. On that day, 10 years ago, I posted a link to Mastodon on Hacker News, with the title \"Show HN: A new decentralized microblogging platform\". That it made it to the front page ended up bringing the first 5,000 users…", "boosts": 461, "post_id": "117452591132778433", "replies": 21, "is_boost": false, "post_link": "https://mastodon.social/@Gargron/117452591132778433" , "posted_at": "2026-10-16T20:58:32Z", "favourites": 1011, "image_links": [ "https://files.mastodon.social/media_attachments/files/117/452/536/172/003/130/original/2c6272a37c8b41c4.png" ], "content_warning": null, "original_author": null } ]}Code
curl https://api.fous.com/v1/runs \ -H "Authorization: Bearer $FOUS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"method":"mastodon.social/list_recent_posts","input":{"account":"Gargron@mastodon.social"}}' # 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": "mastodon.social/list_recent_posts" , "input": { "account": "Gargron@mastodon.social" }})# 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": "mastodon.social/list_recent_posts" , "input": { "account": "Gargron@mastodon.social" } }), 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 mastodon.social/list_recent_posts# with {"account":"Gargron@mastodon.social"}"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": [ "account" ], "properties": { "account": { "type": "string", "description": "Full account handle including server, or a profile link, such as Gargron@mastodon.social." }, "max_results": { "type": "integer", "default": 20, "maximum": 100, "minimum": 1, "description": "Maximum number of posts to return, for example 20." }, "include_boosts": { "type": "boolean", "default": false, "description": "Include boosts, for example true." }, "include_replies": { "type": "boolean", "default": false, "description": "Include replies, for example true." } }}Output schema
{ "type": "object", "required": [ "posts" ], "properties": { "posts": { "type": "array", "items": { "type": "object", "properties": { "text": { "type": "string" }, "boosts": { "type": "integer" }, "post_id": { "type": "string" }, "replies": { "type": "integer" }, "is_boost": { "type": "boolean" }, "post_link": { "type": "string" }, "posted_at": { "type": "string" }, "favourites": { "type": "integer" }, "image_links": { "type": "array", "items": { "type": "string" } }, "content_warning": { "type": [ "string", "null" ] }, "original_author": { "type": [ "string", "null" ] } } } } }}- Price
- 1 credit per completed run (1¢ with pay as you go); failed runs are free.
- Method
mastodon.social/list_recent_posts- Returns
- text, content warning, date, counts, boost info, images, link, id
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 mastodon.social/list_recent_posts with the inputs above.
Ask your agent
- Show me the latest 15 public posts from Gargron@mastodon.social, including boosts
- What has the account @jack@mastodon.social posted recently? Include their replies too, up to 30 posts.
- I want to see the newest 10 toots from a Mastodon user, no replies or reblogs, just their original posts
- Pull up the last 50 public posts from https://mastodon.social/@Mastodon with replies and boosts included
- Get recent posts from the account eugen@mastodon.social, limited to 5, newest first
See more
All Mastodon methodsLists the latest public posts for a hashtag on a Mastodon server, newest first. Some servers require login for public timelines.
mastodon.social/list_hashtag_postsGets a public Mastodon profile by handle or profile link, with its bio, counts, dates and profile fields. Major servers are read directly. Other servers are looked up through mastodon.social, and their home-server account ID is not available.
mastodon.social/get_profileLists an account's latest public Bluesky posts, newest first. Replies and reposts are left out unless requested; a repost's time is when the account reposted it.
bsky.app/list_recent_postsLists an account's latest public Threads posts, newest first, with text, engagement counts, thumbnails and links. Only posts shown without logging in are returned.
threads.com/list_recent_postsLists the latest publicly embeddable posts and reels from an Instagram account, newest first. Without login Instagram may show fewer posts than requested. View counts that are not available are null.
instagram.com/list_recent_postsLists 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 recent public posts of a Tumblr blog, optionally only those with a given tag. Private or login-only blogs cannot be read.
tumblr.com/list_blog_postsLists the latest posts from a public Telegram channel preview, with text, posting time, approximate views, edit flag, forwarded source, thumbnails and post links.
t.me/list_channel_posts