Mastodon API rate limits
Mastodon API rate limits: 300 requests per 5 minutes per account and per IP, 30 media uploads per 30 minutes, the X-RateLimit headers and a sender that stays under them.
Mastodon publishes its API rate limits as a short table, and the numbers are small enough that a posting job can hit them without doing anything unusual. The limits apply per Mastodon account and per IP address, and every server runs its own copy of them, so a job that posts to accounts on five instances is dealing with five separate sets of counters.
The documented limits
Mastodon's rate limit documentation lists these defaults:
| Scope | Endpoint | Limit |
|---|---|---|
| Per account | All endpoints and methods | 300 requests per 5 minutes |
| Per account | POST /api/v1/media | 30 requests per 30 minutes |
| Per account | DELETE /api/v1/statuses/:id and POST /api/v1/statuses/:id/unreblog | 30 requests per 30 minutes |
| Per IP | All endpoints and methods | 300 requests per 5 minutes |
| Per IP | POST /api/v1/accounts | 5 requests per 30 minutes |
Two rows matter for posting. The general limit of 300 requests per 5 minutes is generous for text, but it counts every call, including the reads a client makes to check a status or fetch the timeline. The media limit is the one that bites: 30 uploads per 30 minutes per account, and a status with four images spends four of them before the status itself is created. Seven four-image posts in half an hour exhausts the budget.
The delete limit has the same shape. A cleanup script that removes old statuses can delete 30 every 30 minutes, which turns a purge of a few thousand posts into a job that runs for days.
These values are the defaults in Mastodon's code. Servers running forks or modified configurations can differ, so treat the table as the starting point and the response headers as the truth for a given server.
The headers
Mastodon returns the limit state on responses, so a sender can see a limit coming before it hits it:
X-RateLimit-Limit, the number of requests allowed in the window.X-RateLimit-Remaining, how many are left.X-RateLimit-Reset, the timestamp at which the window resets.
When a request falls under several limits at once, for example a media upload that counts toward both the general limit and the media limit, the headers report the one you are closest to exceeding. That makes the headers safe to use as the single input for a limiter: read X-RateLimit-Remaining, and when it reaches zero, wait until X-RateLimit-Reset.
Requests over the limit get an HTTP 429 response. Retrying immediately only produces more 429s; wait until the reset time from the last response you received.
Per account, per IP and per server
The per-IP limit is the one people forget. A service that posts for many users from one server shares a single 300-per-5-minutes budget per Mastodon instance across all of them, regardless of how many accounts it holds tokens for. Fifty users on mastodon.social posting through the same worker draw from the same per-IP counter on mastodon.social. Users on other instances do not, because each instance counts on its own.
So the key for a local limiter is the instance host plus the account for account limits, and the instance host plus your outgoing IP for IP limits.
A sender that stays under them
post(instance, account, status):
for image in status.images:
wait_for(instance, account, "media") # 30 per 30 min
res = POST https://{instance}/api/v2/media image
update(instance, account, res.headers)
wait_for(instance, account, "all") # 300 per 5 min
res = POST https://{instance}/api/v1/statuses status
headers: Idempotency-Key: {status.id}
if res.status == 429:
sleep_until(res.headers["X-RateLimit-Reset"])
retry with the same Idempotency-Key
update(instance, account, res.headers)
The Idempotency-Key header is worth sending on every status creation. Mastodon uses it to recognise a repeated submission, so a retry after a timeout does not publish the same status twice. Rate limits and timeouts tend to arrive together during busy periods, and a duplicate post is a more visible failure than a delayed one.
For a scheduled burst, such as a release announcement going out to several accounts at once, upload media first and spread the uploads out, then create the statuses. That keeps the slow, tightly limited step away from the moment the posts are meant to appear.
The shorter route
yeetpost posts to Mastodon with one HTTP call to /api/v2/post/mastodon with an API key. It works on any instance, checks the text against that instance's own character limit, and handles image uploads and threads. The Mastodon posting API page covers what it supports, and scheduled posts let you queue a status for a set time.
Keep reading
- Discord webhook rate limitsHow the Discord webhook rate limit works: the 50 requests per second cap, per-webhook buckets, X-RateLimit headers, the 429 body and a safe queue.
- Ayrshare alternatives for developers in 2026Ayrshare, Zernio, Postiz and yeetpost compared on how they charge, what the API includes and where each one fits. Prices as of October 2026, each linked to its source.
- Bluesky API: posting with an app password, threads and imagesPost to Bluesky from a script with an app password: the session call, the post record, image upload, reply threads, and the one-call version.
Post from your code today
Two accounts are free and need no credit card. Your first post can go to the sandbox connection, which takes it and publishes nothing.