Documentation Python quickstart Blog Free tools hello@quanticdata.ioLog in

Mastodon Proxies: What 11 Servers Return

One Mastodon account lookup requested through four proxy exit countries on 21 September 2026: the United States, Germany, Brazil and Japan all receive the identical 1082 byte cached response, carrying the same entity tag and the same origin request identifier, which means the exit country changes nothing except the edge server that replays it
One Mastodon account lookup requested through four proxy exit countries on 21 September 2026: the United States, Germany, Brazil and Japan all receive the identical 1082 byte cached response, carrying the same entity tag and the same origin request identifier, which means the exit country changes nothing except the edge server that replays it

Search this keyword and Google returns Warhammer miniatures and nginx tutorials. Nobody measures what a Mastodon server actually hands a proxied client. So we asked eleven of them, without a token, on 21 September 2026: seven answered, four refused, and one reply was byte-identical on four continents.

First, the word means two opposite things

On every other network in this series, "proxy" has one meaning. On Mastodon it has two, and they point in opposite directions.

  • An inbound reverse proxy. You run your own instance and put nginx or Caddy in front of it. This is what the autocomplete suggestions are about — mastodon reverse proxy, mastodon nginx proxy manager, trusted_proxy_ip, media proxy. It is a self-hosting question and has nothing to do with this article.
  • An outbound proxy. You are a client, collecting public posts and profiles across many independent servers, and you need exit IPs. That is what follows.

The confusion is worth naming because it is why the search results on this term are useless. The first page we pulled from a US exit was mostly Warhammer 40,000 model kits and self-hosting guides, plus one vendor page of 166 words that says proxies let you reach an instance "where the desired instance is open". That is not an answer. Here are the numbers instead.

Seven of eleven servers answer with no token at all

Mastodon is not one site. Every server runs the same software with its own settings, so the only honest way to describe "Mastodon's API" is to query a sample of servers and count. We sent one request — GET /api/v1/timelines/public?limit=1, plain HTTP client, no browser, no credentials, US exit — to eleven well-known instances inside five minutes.

ServerStatusBodyPublic timeline without a token
mstdn.social2003,232 BOpen
fosstodon.org2003,255 BOpen
hachyderm.io2004,106 BOpen
mas.to2003,080 BOpen
mastodon.world2003,939 BOpen
techhub.social2003,792 BOpen
universeodon.com2004,934 BOpen
mastodon.social42254 BClosed
mastodon.online42254 BClosed
infosec.exchange42254 BClosed
chaos.social42254 BClosed

Seven open, four closed. No captcha anywhere, no browser challenge, no TLS fingerprint check, no interstitial. Eleven out of eleven answered a plain HTTP client on the first attempt, which is already a different world from the platforms earlier in this series: on TikTok, the same shape of request returned a firewall page disguised as an HTTP 200.

All eleven also returned the same throttle: x-ratelimit-limit: 300. That matches the documented default of 300 requests per five minutes per IP address, and it is the single number that decides how many proxies this job needs.

One cached answer for four continents

Next we changed only the exit country. Same URL — mastodon.social/api/v1/accounts/lookup?acct=Mastodon — from the United States, Germany, Brazil and Japan, inside ninety seconds.

All four returned HTTP 200. All four returned exactly 1,082 compressed bytes. All four carried the same entity tag. And all four carried the same x-request-id: one single response, generated once at the origin, replayed to four continents from four different edge caches. Not similar responses. The same response.

The practical consequence is blunt, and it is the opposite of what a vendor page wants to tell you: on Mastodon's public API, geo targeting buys nothing. There is no country-specific pricing, no localised ranking, no regional partition of the backend. A German exit and a Japanese exit get the identical bytes, because a cache in Frankfurt and a cache in Tokyo are replaying one origin answer.

Language does vary in the data, but it comes from the server you chose, not the IP you left from. The top public post on hachyderm.io when we sampled it was in Dutch, delivered to a US exit. On Mastodon, "targeting" means picking instances, not picking countries.

The rate-limit headers are lying to you

This is the finding that will cost somebody a weekend if they do not know it.

That cached lookup carried x-ratelimit-remaining: 299 and x-ratelimit-reset: 2026-09-21T05:10:00Z. It reached our Tokyo exit at 05:35:37 UTC. The reset timestamp was already twenty-five minutes in the past. The lookup we ran against infosec.exchange was worse: served at 05:36:58 with a reset of 04:10:00Z, eighty-seven minutes stale.

The reason is structural. Mastodon marks these GETs cache-control: max-age=15, public, so the reverse cache in front of the instance stores the whole response, throttle headers included, and replays them to everyone. Those headers describe whichever client happened to populate the cache. They are not your counter, and rotating your IP will not refresh them.

Compare the responses that cannot be cached. Every 422 we received was marked private, no-store and carried a correct, forward-dated reset — 05:35:00Z and 05:40:00Z, the next five-minute boundaries. So the rule is simple:

  • Treat x-ratelimit-remaining on a cacheable 200 as decoration. Log it, never branch on it.
  • Count your own requests per exit IP per host, and hold yourself under 300 per five minutes.
  • Back off when you actually receive a 429, not when a header tells you to.

If you have ever wondered why a Mastodon client seems to get throttled at unpredictable moments while its own budget tracker says it has 299 requests left, this is why.

The four error shapes, and which one is about you

Mastodon's failure modes are unusually legible once you stop reading status codes as verdicts.

What you getWhat it meansDoes rotating the IP help?
422 with This method requires an authenticated userThe server's admin turned off unauthenticated access to that method. A policy, applied to everyone.No. Use a different server or authenticate.
404, 28 bytesThat handle does not exist on that server. Federated accounts live on their home server.No. Fix the handle or query the home instance.
429You genuinely exceeded 300 requests in five minutes from this IP.Yes — this is the one case proxies solve.
HTML where JSON belongsYou reached a CDN or firewall in front of the instance, not Mastodon itself.Sometimes. First check whether the instance is simply down.

The 422 deserves a second look, because it is easy to misread as a block. Note that it is not a 401 — Mastodon's authentication guard returns 422 Unprocessable Entity, which most HTTP clients classify as "your input was wrong". It is not your input, and it is not you.

We proved that by asking the four refusing servers something else. All four still served /api/v1/accounts/lookup to the same anonymous client: infosec.exchange returned a full account object, chaos.social returned one in 888 bytes, and mastodon.online returned a clean 404 for a handle that does not exist there — which is itself proof the endpoint was reachable. So those four have not disabled anonymous API access wholesale, as the DISALLOW_UNAUTHENTICATED_API_ACCESS setting would. They have switched off one thing: unauthenticated access to the public timeline. Profiles and posts remain readable.

Diagnosis rule: when a Mastodon method fails, test a second method on the same host before you touch your proxy configuration. One failing endpoint is policy. Every endpoint failing is infrastructure.

Which proxy type Mastodon actually needs

Here is where this post disagrees with every vendor page on the keyword. Mastodon does not need residential IPs, and it does not need mobile IPs.

The reasons come from the measurements above. Nothing checks whether you look like a household: eleven servers out of eleven served a bare HTTP client with no browser, no JavaScript and no challenge. Nothing changes by country: four exits received one identical cached response. The only limit that exists is arithmetic — 300 requests per five minutes per IP per host, which is one request per second.

So the thing you are buying is not trust. It is concurrency: more independent buckets of 300. That makes the cheapest network the correct one. Datacenter exits start at $0.50/GB and are the right default here; if you would rather not manage a pool at all, a rotating endpoint gives you a fresh IP per request from the same $0.50/GB, which maps neatly onto a crawl that fans out across dozens of hosts. Residential from $0.80/GB and mobile from $2.30/GB are excellent on networks that fingerprint you. This is not one of them, and paying for that here is money set on fire.

Sizing is easy because the throttle is documented and uniform. One IP sustains one request per second against one host. Ask for forty statuses per request and that is 12,000 posts per five-minute window, per IP, per server. Two IPs double it. A crawl that touches fifty instances at one request per second each needs concurrency, not stealth.

Per exit IP, per instance:
  300 requests / 5 min  =  1 req/s
  x 40 statuses/request = 40 statuses/s  = 12,000 per window

Throttle yourself. Do not read x-ratelimit-remaining off a cached 200.

What it costs, and why you should not render

We measured the same account four ways on the same morning. The gap between the cheapest and the most expensive route is not a rounding error.

How you fetch itOn-wire bytesWhat you getPer GB
Profile page, no JavaScript22,0468 words of body text; the counters survive only in the meta description~48,700 profiles
Profile page, real browser794,108130 words, 6.6 seconds~1,350 profiles
/api/v1/accounts/lookup1,082The complete object: followers, following, post count, creation date, four verified links, consent flags~992,000 profiles
/api/v1/accounts/:id/statuses?limit=4040,63440 full statuses — 1,016 bytes each~1,056,000 statuses

Read the first and third rows together. The API returns twenty times less traffic than the HTML page and strictly more information, because the page without JavaScript is an empty shell: an independent audit of the same URL found 21 words for a bot and 123 after rendering, no canonical tag, and no structured data in either pass. Rendering it costs 734 times the bytes of the API call to produce 130 words that the API already gave you in full.

Put a real workload through it. Refresh 50,000 public profiles every day for a month: 1.5 million lookups, about 1.5 GB, roughly $0.76 of datacenter traffic. The same job through a headless browser moves about 1,109 GB and costs about $555. Same data. Same month.

That also means we will tell you not to buy the obvious product. Our scraping API is $0.0002 per page and $0.001 rendered, and on a network with an open JSON API those are prices you simply do not need to pay. Use it for the pages around Mastodon — the linked blogs, the personal sites in profile fields, the verification targets — and call the instance API directly for the instance itself. If you drive collection from an assistant, our MCP server exposes the same fetch and audit tools, and every account gets $2 of free API usage a month, which is more than this entire measurement consumed.

What you may collect, and the flag that tells you

Mastodon's answer here is more honest than most, and it is worth quoting rather than paraphrasing. The robots.txt served by mastodon.social on 21 September 2026 was 231 bytes:

User-agent: GPTBot
Disallow: /

User-agent: *
Disallow: /media_proxy/
Disallow: /interact/
Disallow: /api/v1/instance/domain_blocks

One AI crawler named and excluded; everything else permitted, the API included. We fetched the same file from hachyderm.io and chaos.social and got the identical 231 bytes — the stock file, unmodified, even on a server that had switched its public timeline off. So on Mastodon robots.txt is not the signal. It is a default nobody edited.

The real signal ships inside the data. Every account object carries discoverable, indexable and noindex — the user's own choices, set in their preferences. In our sample the Mastodon project account was discoverable: true, indexable: true; the first account to appear on a public timeline we sampled was discoverable: false, indexable: false, an ordinary user who had opted out of exactly this. The consent flag arrives in the same response as the data, for free, before you store anything. Honouring it is one line:

if not account["indexable"] or not account["discoverable"]:
    continue  # the user said no, in the same JSON you are reading

There is no reason to skip that check, and every reason not to. Which leads to what this is properly for: measuring how a topic travels across instances, tracking your own brand's mentions, mapping which servers a community actually lives on, checking that a campaign's links resolve, research on public discourse. The Mastodon Server Covenant commits participating servers to active moderation and to giving users their data and the ability to leave — a network that takes user agency that seriously is one where you honour the opt-out flags rather than route around them.

The things not to do are the ordinary ones. Do not mass-register accounts: that method is separately throttled to five per thirty minutes per IP, and defeating that limit with proxies is abuse of a volunteer-run server, not a growth tactic. Do not run engagement bots. Do not collect followers-only posts, which the API will not give you anyway without a token from someone who was allowed to see them. And remember that a Mastodon instance is often one person paying for a server out of pocket — a crawler that ignores 300 per five minutes is not beating a corporation, it is running up somebody's bill.

A working shape for a Mastodon collector

Everything above compresses into a short design.

  1. Keep a list of instances, not a list of URLs. The unit of policy is the host. Record per host whether the public timeline answered 200 or 422, and re-test weekly — an admin can flip it.
  2. Resolve accounts through /api/v1/accounts/lookup, then page statuses by account id. Never parse the HTML profile. It has eight words in it.
  3. Pin one exit IP per host and hold it under 1 request per second. Add IPs to add hosts in parallel, not to go faster against one host.
  4. Branch on 429 only. Log the throttle headers, trust the ones on no-store responses, ignore the rest.
  5. Filter on indexable and discoverable at write time, so an opt-out never reaches your store.
  6. Follow the Link header for pagination, which every 200 we received supplied with next and prev URLs. Do not construct cursors yourself.
curl -s -x http://PROXY_HOST:PORT -U 'USER:PASS' \
  'https://mstdn.social/api/v1/accounts/lookup?acct=someone' \
  -H 'Accept: application/json'

If what you actually want is cross-platform social listening rather than Mastodon specifically, the same discipline applies elsewhere with different economics: our Reddit collector returns public posts at $0.0005 each with no rate-limit arithmetic on your side, and Bluesky's public API — the other decentralised network in this series — behaves similarly to Mastodon but partitions moderation by country rather than caching one answer for everyone. Comparing the two is the fastest way to understand why "decentralised" is a claim about governance, not about how the bytes reach you.

Sources & further reading

FAQ

Quick answers on mastodon proxies.

Something else? Ask us

Do I need residential proxies for Mastodon?

No. In our 21 September 2026 test, eleven Mastodon servers all answered a plain HTTP client with no browser, no JavaScript and no challenge, and the same request from four different countries returned one byte-identical cached response. Nothing on the network is checking whether your IP looks residential. The only constraint is 300 requests per five minutes per IP, so what you are buying is extra concurrency, which makes datacenter exits from $0.50/GB the correct choice.

Why does the Mastodon API return 422 instead of 401?

Because Mastodon’s authentication guard raises an unprocessable-entity error, not an unauthorized one. A 422 carrying This method requires an authenticated user means that server’s admin has switched off anonymous access to that specific method — most commonly the public timeline. It is a policy applied to every anonymous client, not a block aimed at you. Four of the eleven servers we tested did this, and all four still served account lookups to the same anonymous client.

Can I trust the x-ratelimit headers Mastodon returns?

Only on responses marked no-store. Cacheable GETs are stored whole by the reverse cache in front of the instance, throttle headers included, and replayed to every client. We received a cached lookup whose reset timestamp was 25 minutes in the past, and another 87 minutes stale. Count requests yourself per IP per host, and back off on an actual 429.

Is scraping public Mastodon posts allowed?

The public REST API is open by design and the stock robots.txt excludes only one named AI crawler while permitting everything else, the API included. The obligation that matters is per user: every account object carries discoverable, indexable and noindex flags that the user set themselves, in the same response you are already reading. Filter on them before you store anything. Followers-only posts are not available without a token and should not be pursued.

How many Mastodon profiles can I collect per GB of proxy traffic?

About 992,000 through /api/v1/accounts/lookup, which returned 1,082 compressed bytes containing the complete account object. The HTML profile page costs 22,046 bytes for eight words of visible text, and rendering it in a browser costs 794,108 bytes. At $0.50/GB, refreshing 50,000 profiles daily for a month is roughly $0.76 through the API and roughly $555 through a headless browser.

Does a Mastodon proxy mean a reverse proxy?

It usually does, which is why this keyword is confusing. If you run your own instance, a reverse proxy is nginx or Caddy sitting in front of it, and the relevant settings are TRUSTED_PROXY_IP and the media proxy configuration. If you are a client collecting public data across many servers, you want outbound exit IPs — a completely different product for a completely different problem. This article is about the second one.

Collect Mastodon without overpaying for it

Datacenter and rotating exits from $0.50/GB, a scraping API for the pages around the network, and $2 of free API usage every month. Size the pool to the 300-per-five-minutes limit, not to a fear of being blocked.

Related reading