Skip to content
DocsUnitley Docs home

Rate limits

The budgets Unitley counts every request and tool call against, the order they are checked in, and what a refusal looks like over REST and MCP.

Unitley counts requests and tool calls against a few budgets. Each budget counts in fixed windows that start fresh at set times on the clock, not a set time after your first call. The counts are kept in one place, so they hold however many of Unitley's servers handle your requests.

If Unitley cannot check a budget, it refuses the request rather than letting it through uncounted. That comes back as unavailable: try again in a moment.

Budgets

BudgetLimitWhat it counts
Per address, REST API300 a minuteEvery request to the REST API from one IP address, counted before the token is checked.
Per address, MCP server300 a minuteEvery request to the MCP server from one IP address, counted before the token is checked.
Per token60 a minuteTool calls made with one access token, so one runaway app cannot spend your whole budget.
Per user120 a minuteTool calls across all your tokens and the web analyst. A call a token's own budget refuses is not counted here.
jev_classify30 every 10 minutesPer user, on top of the budgets above. Each call spends credit on your own TypeSafe key.

The order they are checked

  1. Per address. Every request is counted against the budget for the address it comes from, before the token is looked at. Over the REST API, that is every request to either endpoint. Over MCP, it is every HTTP request, whatever it asks for. An IPv6 address is counted by its /64 prefix, the block a home or mobile connection is given.
  2. Per token. Each tool call is counted against the budget of the token it was made with.
  3. Per user. Each tool call is also counted against your account's budget, which every token you have shares with the web analyst. The web analyst uses no token, so its calls count here only.

The per-token budget is checked first, and a refusal there stops the check. A call your token's own budget refuses is not counted against your account, so your other apps keep working. A call your account's budget refuses has already been counted against its token.

A tool call is counted once Unitley has found the tool, before the scope and the arguments are checked. A call with bad arguments, or a write tool called with a read-only token, still counts. A call to a name that is not a tool does not.

jev_classify has its own budget, 30 every 10 minutes per user, on top of these. A call with invalid input, or with no TypeSafe key saved, does not spend it.

What only counts per address

These count against the per-address budget and nothing else:

  • Listing the tools, with GET on the REST API or tools/list over MCP.
  • Reading resources and prompts over MCP.
  • Any request refused before a tool runs, such as one with no token.

The web analyst also limits how many questions you can ask in a short time. See The web analyst.

When a budget is spent

Every refusal says how long to wait, in seconds and in words, such as "Try again in a minute."

Over REST

HTTP 429 with code rate_limited, a Retry-After header in seconds, and the same number in retryAfterSeconds:

  • "Too many requests." when the per-address budget is spent.
  • "Too many tool calls." when your per-token or per-user budget is spent.
  • "jev_classify is limited to" and its budget, when that one is spent.

See Errors.

Over MCP

  • The per-address budget refuses the HTTP request itself: a 429 with a Retry-After header and the JSON-RPC error -32000, "Too many requests." and the wait.
  • The tool-call budgets and jev_classify's refuse inside the tool's result. The result is marked isError, and its error has code rate_limited and retryAfterSeconds. The HTTP request itself succeeds, so there is no Retry-After header.

Most agents read the message and wait on their own. See The MCP server.

Player props quota

Odds come from The Odds API, which allows Unitley a limited number of requests a month, shared by every Unitley user. Player props are fetched on request: the first request for a game's props in the 24 hours before kickoff fetches them, and a request in the last 3 hours can refresh them once. Everyone then reads the same copy.

As the month's use climbs, Unitley stops refreshing props, then stops fetching them, to keep the main lines updating. When props were not fetched or refreshed, the note in get_player_props says why. Unless the note says another request is fetching them right now, calling again soon gets the same copy. See Data and sources.

Tips

  • Reuse what you fetched. Main-line prices update at set times, not on each call, so asking for the same game's odds again soon returns the same prices. See Data and sources.
  • Keep what does not change. The tool list changes only when Unitley ships an update. The calculators, apart from calc_kelly_stake, which reads your bankroll, give the same answer for the same input.
  • Give each app its own token. One app that loops then spends only its own token's budget, 60 a minute, and leaves room in your account's 120 a minute for the rest. It does not raise the account's budget.
  • Wait as long as you are told. After a refusal, wait for Retry-After before you try again. A call made sooner is refused again and still counts.
  • Do not retry a call that cannot work. invalid_input and insufficient_scope come back the same until you change the call, and each try counts. See Retry or fix.

21+ · Gambling problem? Call 1-800-GAMBLER or visit ncpgambling.org

Unitley is an analysis tool, not a sportsbook: it takes no bets and holds no money. Nothing in these docs is a guarantee or financial advice. Only bet where it is legal for you. Unitley is not affiliated with the NFL, its teams, or any sportsbook.

©︎ 2026 Unitley · Analysis, not a guarantee.