A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Mastodon API is how an app or AI agent works with a Mastodon account: posting and deleting statuses, reading the home and public timelines, following and unfollowing accounts, and listing notifications. Access is granted through an OAuth token and a set of scopes that decide what each call can read or write, and an agent is limited to the one server that issued the token. Mastodon is federated, so the server is the user's own instance, and it streams events over a long-lived connection rather than posting them to a webhook.
How an app or AI agent connects to Mastodon determines what it can reach. Mastodon is federated, so each server is its own host, and an access token is issued by one server and works only against that server's accounts and data.
The REST API is served by each Mastodon server at its own host, under /api/v1 for most methods and /api/v2 for a few such as media upload and search. It answers JSON over HTTPS and authenticates with an OAuth bearer token.
The streaming API at /api/v1/streaming delivers events in real time, such as a new status, a deletion, or a notification. It is offered as Server-Sent Events over a kept-open HTTP connection or over a WebSocket that can multiplex several streams like user, public, hashtag, and list.
An OAuth 2.0 user token is obtained through the authorization code flow after the user approves the requested scopes on their home server. It acts on behalf of that user and is the standard way to connect to Mastodon.
An app access token is obtained with the client credentials grant and represents the application itself, not a user. It can read public data and register push subscriptions but cannot act for any account.
The Mastodon API is split into areas an agent can act on, such as statuses, timelines, accounts, media, notifications, and search. Each area maps to its own OAuth scope, and some scopes reach far more than others.
Post, read, edit, and delete statuses, and favourite, reblog, and bookmark them.
Read the home timeline of followed accounts and the server's public timeline.
Verify the token's own account, read a profile and its posts, and follow or unfollow.
Upload a file to attach to a status, and update or remove an unattached attachment.
List the account's notifications, read a single one, and clear them.
Search across accounts, statuses, and hashtags on the server.
Create and manage lists and the accounts they contain.
Read a poll attached to a status and vote on it.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
StatusesPost, read, edit, and delete statuses, and favourite, reblog, and bookmark them.7 | ||||||
| POST | /api/v1/statuses | Publish a status with the given text, media, visibility, or poll. | write | write:statuses | Current | |
An Idempotency-Key header prevents a duplicate post if the request is retried. A media_ids array attaches files uploaded beforehand. Acts onstatus Permission (capability) write:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/statuses/:id | Obtain information about a single status. | read | read:statuses | Current | |
Public statuses are readable without a token on most servers; private ones need read:statuses and access to that post. Acts onstatus Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /api/v1/statuses/:id | Delete one of the account's own statuses. | write | write:statuses | Current | |
The response returns the deleted status's source so it can be re-drafted. Deletions count against the stricter 30-per-30-minutes limit. Acts onstatus Permission (capability) write:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limit30 per 30 minutes SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/statuses/:id/context | Retrieve the parent and child statuses in a thread around a status. | read | read:statuses | Current | |
Returns the ancestors and descendants that make up the conversation. Acts onstatus Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/statuses/:id/favourite | Add a status to the account's favourites. | write | write:favourites | Current | |
Favouriting uses its own write:favourites scope rather than write:statuses. Acts onstatus Permission (capability) write:favouritesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/statuses/:id/reblog | Reshare a status on the account's own profile, also known as a boost. | write | write:statuses | Current | |
A visibility parameter sets who sees the reblog. Acts onstatus Permission (capability) write:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/statuses/:id/bookmark | Privately bookmark a status. | write | write:bookmarks | Current | |
A bookmark is private to the account and uses the write:bookmarks scope. Acts onstatus Permission (capability) write:bookmarksVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
TimelinesRead the home timeline of followed accounts and the server's public timeline.3 | ||||||
| GET | /api/v1/timelines/home | View statuses from the accounts and hashtags the user follows. | read | read:statuses | Current | |
Returns only what the authenticated account follows, so it always needs a token. Acts ontimeline Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/timelines/public | View public statuses across the server, optionally limited to local posts. | read | read:statuses | Current | |
From Mastodon 4.5 a server can require a signed-in user to read the public timeline. Acts ontimeline Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/timelines/tag/:hashtag | View public statuses that contain the given hashtag. | read | read:statuses | Current | |
The any, all, and none parameters refine which hashtags match. Acts ontimeline Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
AccountsVerify the token's own account, read a profile and its posts, and follow or unfollow.6 | ||||||
| GET | /api/v1/accounts/verify_credentials | Test that the token works and return the authenticated account. | read | read:accounts | Current | |
The profile scope, added in Mastodon 4.3, also satisfies this without granting broader read access. Acts onaccount Permission (capability) read:accountsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/accounts/:id | View information about a profile by account id. | read | — | Current | |
Public on most servers, so no scope is required, though a server in secure mode may require a token. Acts onaccount Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/accounts/:id/statuses | List the statuses posted by a given account. | read | read:statuses | Current | |
Public posts return without a token; the read:statuses scope is needed to see posts limited to followers. Acts onaccount Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/accounts/:id/follow | Follow the given account, optionally choosing whether to show its reblogs. | write | write:follows | Current | |
The follow top-level scope still works but is deprecated in favor of write:follows. Acts onaccount Permission (capability) write:followsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/accounts/:id/unfollow | Remove a follow relationship with the given account. | write | write:follows | Current | |
The follow top-level scope still works but is deprecated in favor of write:follows. Acts onaccount Permission (capability) write:followsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /api/v1/accounts/update_credentials | Update the authenticated account's display name, bio, avatar, and profile settings. | write | write:accounts | Current | |
From Mastodon 4.6 a dedicated PATCH /api/v1/profile endpoint covers profile editing and returns raw, unrendered text. Acts onaccount Permission (capability) write:accountsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
MediaUpload a file to attach to a status, and update or remove an unattached attachment.2 | ||||||
| POST | /api/v2/media | Upload a media file to attach to a status that has not yet been posted. | write | write:media | Current | |
Processing is asynchronous, so this can return 202 with a null url until the file is ready. Uploads count against the stricter 30-per-30-minutes limit. Acts onmedia attachment Permission (capability) write:mediaVersionAvailable since the API’s base version Webhook eventNone Rate limit30 per 30 minutes SourceOfficial documentation ↗ | ||||||
| PUT | /api/v1/media/:id | Update an unattached media attachment's alt text or focal point before it is posted. | write | write:media | Current | |
Only works while the attachment is still unattached to a status. Acts onmedia attachment Permission (capability) write:mediaVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
NotificationsList the account's notifications, read a single one, and clear them.3 | ||||||
| GET | /api/v1/notifications | List notifications concerning the user, optionally filtered by type. | read | read:notifications | Current | |
Types include mention, reblog, favourite, follow, and poll. Acts onnotification Permission (capability) read:notificationsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /api/v1/notifications/:id | View a single notification by id. | read | read:notifications | Current | |
Returns the same shape as one entry in the list endpoint. Acts onnotification Permission (capability) read:notificationsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/notifications/clear | Clear all notifications from the server for the account. | write | write:notifications | Current | |
Dismisses every notification at once; a single one can be cleared with the dismiss endpoint. Acts onnotification Permission (capability) write:notificationsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SearchSearch across accounts, statuses, and hashtags on the server.1 | ||||||
| GET | /api/v2/search | Search across accounts, statuses, and hashtags on the server. | read | read:search | Current | |
Basic search works unauthenticated, but the resolve and offset parameters need a token with read:search. Acts onsearch result Permission (capability) read:searchVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ListsCreate and manage lists and the accounts they contain.3 | ||||||
| GET | /api/v1/lists | Fetch all lists that the user owns. | read | read:lists | Current | |
A list groups accounts so their posts can be read on a list timeline. Acts onlist Permission (capability) read:listsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/lists | Create a new list. | write | write:lists | Current | |
A replies_policy parameter sets whose replies appear in the list timeline. Acts onlist Permission (capability) write:listsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/lists/:id/accounts | Add one or more accounts to the given list. | write | write:lists | Current | |
The account must already be followed before it can be added to a list. Acts onlist Permission (capability) write:listsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
PollsRead a poll attached to a status and vote on it.2 | ||||||
| GET | /api/v1/polls/:id | View a poll attached to a status. | read | read:statuses | Current | |
A public poll reads without a token; a private one needs read:statuses. Acts onpoll Permission (capability) read:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /api/v1/polls/:id/votes | Vote on a poll attached to a status. | write | write:statuses | Current | |
Votes are submitted as an array of the chosen option indexes. Acts onpoll Permission (capability) write:statusesVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Mastodon does not use classic webhooks that post to a receiver URL. Instead an app or AI agent opens a long-lived streaming connection and receives events, like a new status or a notification, as they happen.
| Event | What it signals | Triggered by |
|---|
Mastodon limits how fast an app or AI agent can call, through a default ceiling per account and a separate ceiling per IP address over a rolling five-minute window, with a handful of stricter limits on specific actions.
Mastodon applies a default ceiling that every endpoint shares: 300 requests per five minutes per authenticated account, and a much higher 7,500 requests per five minutes per IP address. A few actions carry their own stricter limits on top: media uploads and status deletions are capped at 30 per 30 minutes, and account creation at 5 per 30 minutes. A single method can fall under more than one limit at once, and the response headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset always report the limit closest to being hit. Going over returns 429 Too Many Requests.
List endpoints use cursor pagination through status and notification ids. The max_id parameter returns results older than that id, since_id and min_id return results newer than it, and limit sets the page size. Each response carries a Link header with prev and next URLs already built, which should be followed rather than constructed by hand, because some entities use an internal id that is not exposed in the response body.
Requests and responses are JSON. A status is capped at 500 characters by default, though a server can raise this, and the v2 instance endpoint reports the configured maximums for a server. A status can carry up to 4 media attachments, and from Mastodon 4.6 a server publishes its account and profile limits, such as max_note_length and max_display_name_length, through the instance endpoint.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | Unauthorized | Authentication is required but missing or invalid, such as on a server running in secure mode, or the token has been revoked. | Send a valid OAuth bearer token in the Authorization header. |
| 403 | Forbidden | The request is authenticated but not permitted, such as the token lacking the required scope or the action being blocked, like following an account that blocks the user. | Grant the missing scope, or stop attempting an action the relationship disallows. |
| 404 | Not Found | The record does not exist, or the token cannot see private content, in which case Mastodon returns 404 rather than confirm the content exists. | Confirm the id and that the token has access to the resource. |
| 422 | Unprocessable Entity | Validation failed, such as a missing required parameter or a duplicate action like re-pinning a status that is already pinned. | Read the error and error_description fields, correct the request, and resend. |
| 429 | Too Many Requests | A rate limit was exceeded, either the default per-account or per-IP limit or one of the stricter per-action limits. | Wait until the time in the X-RateLimit-Reset header before retrying. |
| 503 | Service Unavailable | A remote service the server depends on failed, such as a federation peer being unreachable or an SSL validation error, or the server is temporarily overloaded. | Retry later, since the failure is usually transient. |
Mastodon does not version the API by date. It uses path version segments for the API surface, v1 for most methods and v2 for a few, and ships new methods and fields with each Mastodon software release.
Mastodon versions the API by path segment rather than by date. Most methods sit under v1, and a few newer ones, such as media upload and full search, sit under v2. There is no global version header to pin, so the methods and fields a server exposes depend on the Mastodon software version it runs. New capabilities ship with each Mastodon release, and from Mastodon 4.4 a Deprecation header marks any method on the way out.
Mastodon 4.6 added a Collections API for curated public account lists, dedicated profile editing endpoints at /api/v1/profile that return raw unrendered text, a fallback attribute on notifications for unsupported types, and account and profile limits, such as max_note_length, exposed through the v2 instance endpoint. It was released on Wednesday 17 June 2026.
Mastodon 4.5 added authoring of quote posts through a quoted_status_id attribute on a new status, an experimental AsyncRefresh API for long-running background work, and administrator controls over which timelines are reachable by everyone, by signed-in users only, or not at all. It was released in November 2025.
Mastodon 4.4 added new REST methods, including GET /api/v1/accounts/:id/endorsements, follow-recommendation support, and a Deprecation header that marks endpoints scheduled for removal. It was released in July 2025.
Mastodon 4.3 added the profile OAuth scope, which grants only the authenticated account's own profile, along with broader API refinements. It was released on Tuesday 8 October 2024.
Mastodon 4.2 reworked full-text search behind the v2 search endpoint and added trends and discovery methods. It was released in September 2023.
An integration should check the Mastodon software version of the server it talks to, because a method or field may only exist from a certain release onward.
Mastodon API changelog ↗Bollard AI sits between a team's AI agents and Mastodon. Grant each agent exactly the access it needs, read or write, action by action, and every call is checked and logged.