The public v1 API protects queue capacity, worker capacity, and input size. Size
limits are part of the OpenAPI schema and are enforced before jobs are accepted.
Score limits:
text
up to 100 items per job
up to 20,000 characters per item
up to 100,000 total characters per job
Rewrite limits (batch parity with score jobs):
text
up to 100 items per job
up to 5,000 characters per item
up to 100,000 total characters per job
Pagination limits:
text
limit defaults to 50
limit must be between 1 and 100
File upload scan limits:
text
PDF, DOCX, or TXT only
10 MB maximum file size
Pro plan required
Monthly plan allowances:
text
Plan Scan words/month Humanize words/month Max characters/scan
Free 10,000 0 15,000
Plus 200,000 30,000 50,000
Pro 1,000,000 150,000 50,000
Max 20,000,000 3,000,000 50,000
Free accounts include 10,000 scan words per month.
Humanize usage is metered at 3x input words. For example, a 1,000-word rewrite
draws 3,000 words from the humanize pool.
Anonymous browser scans are limited to 5 per day. Anonymous scans are limited to 5,000 characters.
Anonymous browser credentials can score and run one synchronous rewrite
preview per day (POST /v1/rewrites returns a redacted teaser: before/after
scores plus the single most-improved sentence, never the full rewritten
text). The rewrite preview shares the 5,000-character anonymous cap. A second
anonymous rewrite in the same day returns 429 with
error.code set to anonymous_rewrite_quota_exceeded. Async rewrite jobs
require a signed-in user or an API key and return 403 with error.code set
to anonymous_rewrite_jobs_forbidden on an App Check-only request. Free
accounts get 402 with error.code set to upgrade_required when creating
sync or async rewrites. Anonymous allowances are keyed on the App Check app
and network origin and reset at UTC midnight. The sixth anonymous scan of the
day returns 429 with error.code set to anonymous_quota_exceeded; an
over-size anonymous scan or rewrite preview returns 429 with error.code
set to anonymous_input_too_large.
Humanizer access requires a paid signed-in plan or an API key on a paid account.
File upload scanning requires a Pro signed-in account or an API key whose
account is on Pro. Non-Pro upload requests return 402 upgrade_required;
anonymous App Check upload requests return 403 insufficient_scope.
Signed-in web requests and API-key requests share the same account-level plan
pools. Free accounts use calendar-month periods. Paid accounts use the current
Stripe subscription period, so a successful subscription webhook period update
naturally starts a fresh allowance document. A score, scan, uploaded file scan,
rewrite, or rewrite job that would exceed its pool returns 402 with error.code set to
allowance_exhausted, error.pool set to scan or humanize, and
error.docs pointing back to this page.
Operational request-rate and queue-concurrency limits may be adjusted to protect
GPU capacity. Clients should use idempotency keys on create requests, poll with
backoff, and retry only retryable failures. The current public OpenAPI contract
does not publish a fixed numeric requests-per-minute quota.
Shared scan result reads (GET /v1/shared/{shareId}) are unauthenticated
capability reads. They do not consume plan word pools and do not currently have
a separate published numeric quota. Unknown and revoked share IDs return the
same 404 response.
When an operational limit is exceeded, create requests return 429 with
error.code set to rate_limited. Requests denied by billing policy return
402 with error.code set to billing_disabled, upgrade_required, or
allowance_exhausted. These failures happen before job creation, artifact
writes, callback token generation, or task dispatch.
Usage API
Read your own scan/humanize word usage, allowances, and period totals
programmatically with GET /v1/usage (scope usage:read; the same endpoint
backs the dashboard usage page):