Quotas & rate limits
How SimplyFill counts requests, when it warns you, and what happens at 100%.
Quotas & rate limits
SimplyFill enforces three kinds of limits: hourly rate limits (requests per hour), monthly quotas (PDFs generated and AI generations consumed), and feature limits (templates and API keys). Every limit is tier-based and visible from the dashboard.
This page is the operational reference. If you only want a price comparison, see Pricing.
Hourly rate limits
The rate limit is a sliding-window counter, measured per API key per hour. Every authenticated request increments the counter; the counter ticks back down as requests age out.
| Tier | Requests / hour |
|---|---|
| PRO | 1,000 |
| BUSINESS | 10,000 |
| ENTERPRISE | 100,000 |
When the counter hits the limit, the next request returns 429 Too Many Requests with a Retry-After header naming the number of seconds until the oldest request ages out. Production-grade HTTP clients should honour Retry-After automatically — see the API errors reference for the retry policy contract.
Rate-limit headers are returned on every response, hit or miss:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | The hourly cap for this key |
X-RateLimit-Remaining | Requests left in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
Monthly PDF generation quotas
The PDF quota is a monthly counter that resets on the first of each calendar month at 00:00 UTC. Each successful POST /api/v1/generate/pdf (or its bulk equivalents) increments the counter by one per output PDF.
| Tier | PDFs / month | Overage allowed | Overage price |
|---|---|---|---|
| PRO | 1,000 | Yes | $0.10 / PDF |
| BUSINESS | 10,000 | Yes | $0.05 / PDF |
| ENTERPRISE | Unlimited | n/a | n/a |
On PRO and BUSINESS the overage is metered through Stripe and billed at month-end — generation is never hard-blocked for exceeding your monthly PDF quota. The only state that blocks generation is an inactive subscription (a failed payment or a canceled plan), which puts the account into read-only mode until billing is brought current. See Read-only lockout below.
Monthly AI generation quotas
The AI generation counter is independent from the PDF counter. AI generations cover automated mapping suggestions and template intelligence features — see Templates for what triggers an AI generation.
| Tier | AI generations / month | Overage |
|---|---|---|
| PRO | 100 | Blocked |
| BUSINESS | Unlimited | n/a |
| ENTERPRISE | Unlimited | n/a |
AI-quota exhaustion never blocks ordinary PDF generation. You'll see 402 Payment Required only when calling the AI endpoints themselves.
Feature limits
Two hard caps that don't reset monthly:
Templates per account
Templates are unlimited on every plan — PRO, BUSINESS, and ENTERPRISE alike. There's no per-account template cap to manage.
API keys per account
| Tier | Max API keys |
|---|---|
| PRO | 5 |
| BUSINESS | 20 |
| ENTERPRISE | Unlimited |
Adding a key past your tier's cap returns 403 Forbidden (feature_limit_reached). Existing keys keep working — you just can't create a new one until you revoke an old one or upgrade.
Spanning the cap across environments is your call — see Environments.
HTTP status codes
| Scenario | Status | Response body |
|---|---|---|
| Hourly rate limit exceeded | 429 Too Many Requests | { "error": "rate_limit_exceeded", "retry_after": 1247 }. Retry-After header set. |
| API-key limit reached | 403 Forbidden | { "error": "feature_limit_reached", "limit": "api_keys", "tier": "PRO" } |
| Monthly AI quota exceeded | 402 Payment Required | { "error": "ai_quota_exceeded", "tier": "PRO" } |
These are the exact codes the backend emits — see also API errors.
Warning thresholds
You won't be surprised by an outage. SimplyFill sends email notifications at three thresholds during the month:
| Threshold | Action |
|---|---|
| 80% | Warning email to the account owner |
| 95% | Urgent warning email + dashboard banner |
| 100% | PRO/BUSINESS start incurring overage billing; ENTERPRISE is unaffected (unlimited) |
The emails include the exact counts (824 / 1000 PDFs this month) and a one-click link to upgrade. If you've delegated billing to another team member, configure the notification recipient in Settings → Notifications.
Worked example: a PRO account at 100%
You're on PRO. You've generated 1,000 PDFs this month. Here's what happens to call #1,001:
- Your backend calls
POST /api/v1/generate/pdfwith a valid API key. - SimplyFill sees the request, validates the key, and increments the counter.
- The counter hits 1,001 — past the PRO included quota of 1,000.
- The response is
200 OK— the generation succeeds. PRO and BUSINESS are never hard-blocked for exceeding the monthly PDF quota. - The dashboard surfaces a yellow overage banner, and the extra PDF is metered through Stripe. You'll be billed
$0.10 × overage(PRO) or$0.05 × overage(BUSINESS) at month-end.
BUSINESS behaves identically at its own 10,000 threshold; ENTERPRISE is unlimited and never meters overage.
Read-only lockout (inactive subscription)
Every SimplyFill account is on a paid plan — either inside its 14-day trial or actively subscribed. A credit card is required to start the trial, and the plan auto-converts to paid when the trial ends. There is no perpetual free tier. The one state that blocks the API is an inactive subscription: a plan that has expired or been canceled, or a failed payment (a declined card when the trial converts, or a failed renewal).
When that happens the account drops to read-only:
- The user can still sign in to the dashboard to review templates, usage, and invoices — they keep account access, they just can't use the generation functionality.
- Every write/generation call —
POST /api/v1/generate/pdf, bulk envelopes, template uploads, promotions — is rejected until billing is brought current. - Read-only endpoints (
GETroutes, the Billing API) keep working so your app can detect the state and prompt the user.
Generation resumes immediately once the user adds or updates a payment method in the Stripe customer portal — no need to wait for the next billing cycle.
The exact HTTP status code and error body returned during read-only lockout are still being finalized; this section will document the wire-level contract once it's confirmed.
Where these values come from
The backend app/config.py file is the single source of truth:
RATE_LIMIT_PRO: int = 1000
RATE_LIMIT_BUSINESS: int = 10000
RATE_LIMIT_ENTERPRISE: int = 100000
QUOTA_PDF_PRO: int = 1000
QUOTA_PDF_BUSINESS: int = 10000
QUOTA_PDF_ENTERPRISE: int = 999999 # unlimited
QUOTA_AI_PRO: int = 100
STRIPE_OVERAGE_PRICE_PRO: int = 10 # cents per PDF
STRIPE_OVERAGE_PRICE_BUSINESS: int = 5 # cents per PDFIf you're self-hosting (Enterprise), these are environment-overridable.
What's next
- Environments — per-environment quota counters
- Webhooks — usage events you can subscribe to
- Billing API — read your current quota state programmatically