> **For coding agents and LLMs:** This is one Social Fetch marketing page (markdown export). For API orientation start with [`/llms.txt`](https://www.socialfetch.dev/llms.txt); for auth and crawl rules use [`/agents.txt`](https://www.socialfetch.dev/agents.txt); for every operation use [`/llms-endpoints.txt`](https://www.socialfetch.dev/llms-endpoints.txt).

## This page

- **On-site (HTML):** <https://www.socialfetch.dev/platforms/mastodon>
- **Markdown (.mdx) URL:** <https://www.socialfetch.dev/platforms/mastodon.mdx>

---

# Mastodon API. Any server, as JSON.

Profiles, posts, replies, hashtag timelines, trends and server details from Mastodon-compatible servers. Name the server and get one JSON shape back.

- Any compatible server
- 24 routes
- 1 credit per request, 2 for emoji lists

Mastodon is many independent servers speaking one client API, so the server is part of every request. Pass it as `host` on server and feed routes, inside the `handle` on profile routes, or inside the post `url` on post routes. Ids belong to the server you asked: `mastodon.social` post `1` is not post `1` anywhere else, and every account and post in a response carries the `host` it came from.

The 24 routes cover accounts (`profile.get`, `profile.posts.list`, `profile.followers.list`, `profile.following.list`, `profile.collections.list`, `profiles.batch.get`), posts (`post.get`, `post.context.get`, `post.edits.list`, `post.reactions.list`, `posts.batch.get`), feeds (`timeline.hashtag.list`, `timeline.public.list`, `hashtag.get`, `trends.posts.list`, `trends.hashtags.list`, `trends.links.list`, `directory.list`, `search.get`) and servers (`server.get`, `server.activity.list`, `server.peers.list`, `server.emojis.list`, `server.blocks.list`).

Every response is the `{ data, meta }` envelope and every outcome is HTTP 200, so branch on `data.lookupStatus`: `found`, `not_found`, `restricted` (a login is needed or the operator closed the feed), `unsupported` (the server does not offer the route) or `not_compatible` (the host is not a Mastodon-compatible server). Cursor pages carry `page.nextCursor`; trends and the directory carry `page.nextOffset`. Batch routes return the items they found plus `missingIds` for the rest.

## What you can get

- Resolve a handle such as `Gargron@mastodon.social` or a profile URL to a full account with counters, flags, fields and roles.
- List an account's posts with `filter=all`, `original`, `media` or `pinned`, and follow `page.nextCursor` for older pages.
- Read a post with its author, media, poll, link card, hashtags and mention list, or a whole reply tree with ancestors and descendants.
- Get the edit history, the accounts behind boosts or favourites, and up to 40 accounts or 20 posts in one batch call.
- Pull a hashtag timeline, a server's public timeline, trending posts, hashtags and links, the profile directory and search.
- Read server details, twelve weeks of activity, the peer list, custom emoji and published domain blocks.

## Mastodon endpoints

| Endpoint | Request | Credits | Docs |
| --- | --- | --- | --- |
| Profile | GET /v1/mastodon/profiles/{handle} | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/handle/get) |
| Profile posts | GET /v1/mastodon/profiles/{handle}/posts | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/handle/posts/get) |
| Followers | GET /v1/mastodon/profiles/{handle}/followers | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/handle/followers/get) |
| Following | GET /v1/mastodon/profiles/{handle}/following | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/handle/following/get) |
| Collections | GET /v1/mastodon/profiles/{handle}/collections | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/handle/collections/get) |
| Profiles by id | GET /v1/mastodon/profiles/batch | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/profiles/batch/get) |
| Post | GET /v1/mastodon/posts | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/posts/get) |
| Post context | GET /v1/mastodon/posts/context | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/posts/context/get) |
| Post edits | GET /v1/mastodon/posts/edits | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/posts/edits/get) |
| Boosts and favourites | GET /v1/mastodon/posts/reactions | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/posts/reactions/get) |
| Posts by id | GET /v1/mastodon/posts/batch | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/posts/batch/get) |
| Hashtag timeline | GET /v1/mastodon/timelines/hashtags/{tag} | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/timelines/hashtags/tag/get) |
| Public timeline | GET /v1/mastodon/timelines/public | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/timelines/public/get) |
| Hashtag | GET /v1/mastodon/hashtags/{tag} | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/hashtags/tag/get) |
| Trending posts | GET /v1/mastodon/trends/posts | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/trends/posts/get) |
| Trending hashtags | GET /v1/mastodon/trends/hashtags | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/trends/hashtags/get) |
| Trending links | GET /v1/mastodon/trends/links | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/trends/links/get) |
| Directory | GET /v1/mastodon/directory | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/directory/get) |
| Search | GET /v1/mastodon/search | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/search/get) |
| Server | GET /v1/mastodon/servers/{host} | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/servers/host/get) |
| Server activity | GET /v1/mastodon/servers/{host}/activity | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/servers/host/activity/get) |
| Server peers | GET /v1/mastodon/servers/{host}/peers | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/servers/host/peers/get) |
| Server emoji | GET /v1/mastodon/servers/{host}/emojis | 2 credits Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/servers/host/emojis/get) |
| Server blocks | GET /v1/mastodon/servers/{host}/blocks | 1 credit Failed requests are free | [docs](https://www.socialfetch.dev/docs/api/v1/mastodon/servers/host/blocks/get) |

## How to start

1. **Create an API key.** Sign up at Social Fetch and copy a key (`sfk_...`). New accounts get 100 free credits, enough to try every Mastodon route on a few servers.
2. **Name the server and route.** Use `GET /v1/mastodon/profiles/Gargron%40mastodon.social` for an account or `GET /v1/mastodon/timelines/public?host=fosstodon.org&limit=20` for a public timeline. Send `x-api-key` on every request.
3. **Branch, then page.** Check `data.lookupStatus` before storing a row. Continue with `page.nextCursor` while `page.hasMore` is true (or `page.nextOffset` on trends and the directory), and bill from `meta.creditsCharged`.

## Pricing

Each Mastodon route charges one credit per completed request, except the custom emoji list, which charges two because a server sends its whole catalogue in one answer. The price on every endpoint page is the billing source of truth, and each page of a list or timeline is its own request. Credits never expire on pay-as-you-go packs, and `meta.creditsCharged` on every response is the billing source of truth.

## Compared with the official API

Each Mastodon-compatible server exposes the client API its software ships with, and the answer depends on the server you ask: its version, its software, its operator settings and whether a route is open to the public. Social Fetch gives you one request shape and one response shape across servers, typed `lookupStatus` instead of a different error on each host, stable cursors, and the same credit metering as every other source.

## FAQ

### Which servers can I ask?

Any Mastodon-compatible server that answers the client API, including forks such as Hometown, Pleroma, Akkoma and Friendica. Pass the host with or without a scheme. A host that answers but is not compatible, such as a Misskey or Lemmy instance, returns `lookupStatus: not_compatible` with the software it reports.

### How do I pass a handle or a post?

Profile routes accept `user@host`, `acct:user@host`, `@user@host` or a profile URL such as `https://mastodon.social/@Gargron` or `https://mastodon.social/web/@Gargron`. Post routes accept a post URL such as `https://mastodon.social/@Gargron/1`; the server in the URL is the server asked, because post ids belong to that server.

### What does lookupStatus mean?

`found` means the item exists and is returned. `not_found` means the account, post or server does not exist. `restricted` means a login is required, the operator closed the feed, or the account is suspended. `unsupported` means the route is not offered there. `not_compatible` means the host is not a Mastodon-compatible server. HTTP 200 only means the request finished.

### Why is a follower or following list empty?

An account can hide its network. When the owner does, `isHidden` is true and `accounts` is empty even though the profile counters are not. Without a hidden network, an empty list means the account has no followers or follows nobody on that server.

### Can I search posts?

Search covers accounts and hashtags on every server. `type=posts` works only where the software allows public post search, such as Pleroma and Akkoma. On Mastodon `type=posts` normally comes back `restricted` with `reason.code: login_required` rather than an empty success. Search has no paging.

### Why do some timelines return restricted?

Operators can restrict the public and hashtag timelines. The response may carry `declaredAccess` with the operator's `local` and `remote` settings (`public`, `authenticated` or `disabled`) so you can see which switch applies. About a third of servers close the public timeline.

### How do batches report what is missing?

`profiles.batch.get` takes up to 40 account ids and `posts.batch.get` up to 20 post ids on one `host`. Both return the items the server sent plus `missingIds` for the ids it did not return. Ids are local to that server, and neither route pages.

### How much does a Mastodon route cost?

Each Mastodon route charges one credit per completed request, except the custom emoji list, which charges two because a server sends its whole catalogue in one answer. A completed answer is billed even when `lookupStatus` is `not_found`, `restricted`, `unsupported` or `not_compatible`, and a name with no DNS record is one of those billed 200 answers. HTTP error responses (400, 401, 402, 502 and 503) are free. The price on the endpoint page is the billing source of truth, each page of a list or timeline is billed separately, and `meta.creditsCharged` on every response is the final word. New accounts start with 100 free credits.

### What happens when a server name is correct but the server is down?

If the name resolves but the server does not answer, the response is HTTP 503 `temporarily_unavailable` with `Retry-After`, and no credits are charged. A name with no DNS record is different: it returns HTTP 200 with `lookupStatus: not_found` and `reason.code: host_not_found`, and that answer is billed. Both describe the named server, not a Social Fetch outage.

### Can I use these routes from agents or MCP?

Yes. Every Mastodon route is a typed MCP tool and is reachable through Ask (`POST /v1/ask`) in plain English. Use the typed routes for production jobs.

## Related

- [Mastodon Profile API](https://www.socialfetch.dev/platforms/mastodon/profiles-handle): One account with counters, flags and profile fields (`GET /v1/mastodon/profiles/{handle}`).
- [Mastodon Profile Posts API](https://www.socialfetch.dev/platforms/mastodon/profiles-handle-posts): An account's posts with filters and cursor paging (`GET /v1/mastodon/profiles/{handle}/posts`).
- [Mastodon Post API](https://www.socialfetch.dev/platforms/mastodon/posts): One post with its author, media, poll and link card (`GET /v1/mastodon/posts`).
- [Mastodon Hashtag Timeline API](https://www.socialfetch.dev/platforms/mastodon/timelines-hashtags-tag): Posts with one hashtag on one server (`GET /v1/mastodon/timelines/hashtags/{tag}`).
- [Mastodon Server API](https://www.socialfetch.dev/platforms/mastodon/servers-host): Server details, limits, registration state and rules (`GET /v1/mastodon/servers/{host}`).
- [Ask in plain English](https://www.socialfetch.dev/ask): Route a natural-language Mastodon question to the matching operation.
