Dev.to WebDev 🛠 Dev 👁 0 📖 3 min read

The Rate Limit Is Not One Number: 120, 60 and 30 on the Same API Host, and the One Route That Answers 8

Most rate-limit documentation tells you the number for the API. Ours is per route, and the spread is wider than I expected: 120 on most routes, 60 on three of them, and 30 on one. I work on OnePassApps, the team behind

Most rate-limit documentation tells you the number for the API. Ours is per route, and the spread is wider than I expected: 120 on most routes, 60 on three of them, and 30 on one.

I work on OnePassApps, the team behind app.onepassapps.com, so I went and measured our own API host route by route with plain curl - no browser, no session, no cookies - and this is what came back.

If you would rather look at the surface than the plumbing, the community voting board is at the voting board and the tools behind it are listed in the app guides.

The numbers

I called twelve routes three times each - 36 requests in all - and read the two budget headers off every response.

Route Status Rate limit Concurrency limit
/api/plans 200 120 64
/api/runtime 200 120 64
/api/config/feature-flags 200 120 64
/api/guest-data/movie-tracker 200 120 64
/api/guest-data/signaldesk 200 120 64
/api/guest-data 200 120 64
/api/guest-data/ 200 120 64
/api/auth/config 200 120 64
/api/voting 200 60 64
/api/health 200 60 8
/api/movie-tracker/catalog 200 60 64
/api/signaldesk/audio 404 30 64

Three different ceilings for requests, two for requests in flight, and the odds and ends of the API spread across all of them.

The budget belongs to the path, not to whether the route exists

/api/signaldesk/audio answers 404 and still carries a 30-request budget, and that budget spent itself on every call - 28, then 27, then 26. A path that does not exist still has a rate limit, and a client that spends it on a typo is spending a real budget.

The remaining counter moves by exactly one

On all twelve routes the remaining counter came back one lower on each successive call. 36 requests, three ceilings, the same decrement every time: 57, 56, 55 on /api/voting; 114, 113, 112 on /api/guest-data/movie-tracker; 105, 104, 103 on /api/guest-data/.

The concurrency counter told a different story. It did not move at all on any route, because each of my calls finished before the next one began. It counts requests in flight, not requests made - which is the difference between a budget and a queue.

/api/health is the odd one out: it answers x-concurrency-limit: 8 where every other route answers 64, and it reported seven free slots on all three calls, so one slot was busy on each of them even though my own request had already finished.

Eight names, five answers

Every one of the twelve routes sent the same access-control-expose-headers list, and it named the same eight headers each time: X-Request-Id, X-RateLimit-Limit, X-RateLimit-Remaining, X-Concurrency-Limit, X-Concurrency-Remaining, Retry-After, X-ToolPass-Credits-Changed and X-ToolPass-Impersonating.

Five of those eight actually arrived. The other three never did, on any route: Retry-After, X-ToolPass-Credits-Changed and X-ToolPass-Impersonating. I grepped the full header block of all 36 responses for x-toolpass and got zero lines.

So the list is a promise about the API surface rather than an inventory of any one response. Read as "these are the headers this host can produce" it is accurate. Read as "these are the headers this response contains" it is three over.

What I got wrong before, and what this corrects

An earlier post of mine listed those eight names as the headers a page is allowed to read off the response. That list is accurate, and what it did not do was count how many of them turn up in a real response - the answer is five.

Two earlier posts of mine also measured x-ratelimit-limit: 120 and x-concurrency-limit: 64. Both are right for the routes they measured, and neither is a statement about the host as a whole. I read one route's budget as the host's budget. There are three request ceilings here, and one route whose concurrency ceiling is not 64 - and I only found them by going through a list of routes rather than through the handful I happened to already know about.

The honest limits

  • 36 requests, one network, one build, 8 November 2026, plain curl, no session and no cookies.
  • Twelve routes is what I knew about from our own code and pages. It is not an inventory of the host, and a route I did not call may carry a ceiling I have not seen.
  • I did not push any route to its ceiling, so I cannot tell you what a 429 carries, what Retry-After would hold, or how fast the remaining counter refills.
  • I did not test an authenticated request, so nothing here says what the credit headers do when they do appear.
  • The /api/health figure of eight was stable across three calls, but I cannot say what was holding the ninth slot.
📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.