Repository navigation
Rate Limits
Zouhair Fouiguira edited this page Feb 28, 2026
·
1 revision
Limits are enforced per API key and depend on your plan:
| Plan | Compilations/month | Requests/min |
|---|---|---|
| Free | 50 | 10 |
| Developer | 500 | 30 |
| Pro | 2,000 | 60 |
| Scale | 10,000 | 120 |
Check current usage via the SDK:
usage = client.get_usage()
print(f"{usage.compilations_used}/{usage.compilations_limit} this month")
print(f"Overage: {usage.overage}")The API returns 429 Too Many Requests. The SDK raises RateLimitError:
from formatex import RateLimitError
import time
try:
result = client.compile(latex)
except RateLimitError as e:
print(f"Rate limited — retry after {e.retry_after}s")
time.sleep(e.retry_after)For batch processing:
import time, random
from formatex import RateLimitError
def compile_with_retry(client, latex, max_attempts=4):
for attempt in range(1, max_attempts + 1):
try:
return client.compile(latex)
except RateLimitError as e:
if attempt == max_attempts:
raise
delay = e.retry_after * (2 ** (attempt - 1)) + random.uniform(0, 1)
print(f"Rate limited — waiting {delay:.1f}s (attempt {attempt})")
time.sleep(delay)When exhausted the API returns 403 → PlanLimitError. Not temporary — upgrade or wait for the monthly reset (1st of each month, UTC):
from formatex import PlanLimitError
try:
result = client.compile(latex)
except PlanLimitError:
print("Quota exhausted — upgrade at https://app.formatex.io/billing")- Use
async_compile()for large batches — avoids holding connections open - Check quota before starting:
if usage.compilations_used >= usage.compilations_limit: return - Add
time.sleep(1)between requests if you're on a lower plan