Every number, one page.

These numbers are not marketing copy. They come from the same config file the extraction Lambda reads at runtime. The build fails if this page and that file disagree.

You are about to send real traffic at this API. You want the real ceilings, not a rough guess. Below is every one of them, grouped the way you will actually hit them: per plan, per request, per fetch, per archive, and per counter.

One note, stated once instead of on every row: almost every value below is an environment default, not a fixed promise. It can change with a config update on our side. What stays stable is the mechanism: what counts against a limit, what resets it, and which error code fires when you cross it. Build against the mechanism.

Two numbers are missing on purpose. The exact per-plan requests-per-minute figure and the abuse-breaker's threshold are internal tuning knobs, not part of the published contract. You still get the mechanism for each in the Counters group below. Every metered response also carries the headers your own client needs to back off correctly.

Per plan

The two numbers that change with your plan. Everything else on this page is the same for every plan.

capabilitycurrent defaulton breach
Documents / monthHobby 500 · Developer 10,000 · Scale 100,000The next request returns a 429 for the rest of the billing period. Only successful extractions count against it. See quota_exceeded.
Max file sizeHobby 10 MB · Developer 50 MB · Scale 200 MBA direct upload over your plan's ceiling is rejected before extraction starts. See too_large.

Request processing

One request, whether the input is a file upload or a ?url= fetch.

capabilitycurrent defaulton breach
Sync processing budget25 secondsThe request times out. Retry, or add ?async=true to run it off the request/response cycle. See timeout.
Async auto-switch threshold8 MBA body over this size is routed to the async path automatically. No error, no client change needed.
Sync upload ceiling10 MBThe API gateway itself refuses a larger direct upload. Use ?url= for a bigger file; that path fetches it server-side, with a much higher ceiling. See too_large.

?url= fetch

Rules for the server-side fetch that runs when you pass ?url= instead of a file.

capabilitycurrent defaulton breach
Schemes and portshttp and https only, ports 80 and 443 (or the URL's own default port)Any other scheme or port is refused before a connection is attempted. Private, internal, and link-local addresses are also blocked, by design. See fetch_failed.
Redirects3 hopsA longer redirect chain is abandoned. See fetch_failed.
Connect timeout5 secondsThe fetch gives up if the source doesn't accept a connection in time. See fetch_failed.
Read timeout15 secondsThe fetch gives up if the source stalls mid-response. See fetch_failed.
Total wall clock20 secondsCaps the whole fetch across every redirect hop. This sits on top of the per-hop timeouts above, so a chain of slow hops can't run unbounded. See fetch_failed.

Containers and archives

Guards applied to zip-based files (DOCX, XLSX, PPTX, ODF, and raw zips) before Tika ever opens them.

capabilitycurrent defaulton breach
Entries per archive10,000An archive with more entries is refused before extraction, as a zip-bomb guard. See too_large.
Inflated size256 MBAn archive that would inflate past this size is refused. See too_large.
Compression ratio200:1An archive compressed past this ratio is refused, even if it stays under the size caps above. That ratio alone is the classic zip-bomb signature. See too_large.
Embedded resources per container1,000Tika's own nested-resource cap, a backstop for containers the archive guard above doesn't parse. See too_large.

Premium quality (quality=premium)

Guardrails around the vision-model path, checked before it runs.

capabilitycurrent defaulton breach
Pages50A document over the cap downgrades to standard-quality extraction instead of erroring.
Bytes32 MBSame downgrade: standard-quality extraction runs instead of an error.
Wall clock3 minutesA premium call still running past this is stopped and the result downgrades to standard quality.

Counters

The two independent meters on every key, and what resets them. Neither one's numeric limit is published here. Both ride the X-RateLimit-* and X-Quota-* response headers instead, so your own client reads its real limit rather than a number that can drift.

capabilitycurrent defaulton breach
Rate limit windowA fixed 60-second windowEvery accepted request counts, including ones that go on to fail. A request over the limit still counts against the window it's flooding. See rate_limited.
Quota periodOne calendar month, UTCOnly successful extractions count. The counter resets at the next UTC month boundary. See quota_exceeded.
Abuse circuit breakerA rolling window of recent outcomes, weighted toward oversized/malformed rejectionsA key that trips it is locked out for a cooldown period, independent of both counters above. See abuse_detected.

Retention

How long usage data lives after it's written.

capabilitycurrent defaulton breach
Usage counters120 daysCounters older than this are deleted. This is bookkeeping retention, not a limit you can hit.
Usage records400 daysPer-request usage records older than this are deleted.

machine-readable-spec

This table is drift-tested at build time against api/extract/src/config.js and api/extract/src/plans.js, the same files the running Lambda imports. If a limit changes in code and this page falls behind, the build breaks. For the header contract and every error code these limits can raise, see the error reference →.

Watch it run, then take a key.

The playground replays a real recorded response for every sample document.

Open the playground →

Get an API key →