Skip to main content
Limits exist to protect two different things. Request rate protects the API and the database. Store capacity protects the proxy pool and the daily run, because an API caller that triggers a refresh spends exactly what a dashboard user spends by clicking refresh.

Limits are per workspace

Every limit counts against the workspace, never against the token or the client address. Minting a second token buys no extra capacity, and several people behind one office address do not share a bucket. Counters live in Redis, so every API instance sees the same window. Two things are counted per client address instead, because no workspace is known yet when they happen: the authentication endpoints, and rejected credentials. A caller that presents a session cookie or an asob_ token the API refuses may do so 120 times a minute from one address before the next attempt is answered with 429 without a lookup. A credential the API accepts costs nothing against that count, so a working client never meets it.

Self hosted instances are unlimited

With BILLING_ENABLED set to false there are no API rate limits at all beyond the existing authentication throttle, which answers a refusal with the same error envelope, retryAfterSeconds and Retry-After as the plan limits. See How are sign in attempts throttled? The only cost of a read is your own machine, and the only real constraint is store collection, bounded by SCRAPE_ITUNES_RPM and SCRAPE_GPLAY_RPM. See The daily pipeline and rate limits. Everything below applies to a metered instance.

Request size limits apply everywhere

These ceilings are resource safety rather than plan capacity, so they hold on a self hosted instance too. A keyword is also capped at five words. Each tracked keyword market costs one real store search every day, so a pasted spreadsheet column or a scripting mistake would otherwise multiply a workspace’s daily store volume without anyone choosing to. Exceeding any of these returns 400 and writes nothing, so a refused batch never lands half applied. Split a larger list across several requests. The keyword field text may run to ten times the 100 characters Apple indexes, so spacing and duplicates in a pasted field never cost a refusal. The 100 character limit applies to the field once it is normalized. See App Store and Google Play for how a save is measured.

Three request classes

Reading a year of stored rankings is cheap. Triggering a refresh is not, which is why store endpoints carry a separate on demand allowance on top of the request rate. Three classes do not mean three budgets. There are two per minute budgets, one for reads and one shared by writes and store requests, and a single daily allowance every class spends from. The class names how a request is priced, never how much room it buys. A class is also not a permission. A read only token may call any endpoint that does not change data, including the store touching lookups, and it spends store capacity when it does.

What each plan allows

A trial runs at Indie limits. A workspace whose plan has lapsed keeps the same read allowance, because its data stays readable and exportable while its capacity does not.

Read the headers

Every response carries the tightest limit the request touched. A client that reads RateLimit-Remaining and honours Retry-After never needs to guess.

A 429 names the window that closed

window is minute, day or concurrent. Waiting for resetSeconds is the whole fix for the first two. For concurrent, reduce how many requests you have open at once.

A rate limit is not a quota

Three refusals look similar and mean different things. Conflating them makes all three unfixable. Waiting does not help a 403, and upgrading a plan does not clear a 429 that is already in flight.

Suspension

An operator can suspend a workspace after sustained abuse. A suspended workspace keeps reading and exporting its data from the dashboard and keeps full access to billing, so it can always pay and always leave with its data. API tokens stop authenticating, every write is refused with 403, and the daily run skips the workspace.

Error responses

The envelope every failure shares.

Personal API tokens

Scope, expiry and revocation.
Last modified on September 15, 2026