Concepts

Rate limits

Per-minute throttles + monthly quotas, plus the headers we send so you can self-throttle.

The API enforces two limits in parallel: a per-minute rate limit (throttle) and a monthly conversion quota.

Per-plan limits #

PlanConversions / monthMax file sizeRequests / minuteOverage rate
Free1,00025 MB10— (hard stop)
Hobby5,000100 MB30$0.005 / conversion
Startup25,000500 MB60$0.003 / conversion
Scale100,0001 GB120$0.002 / conversion
Growth500,0005 GB300$0.001 / conversion
EnterpriseCustomCustomCustomCustom

GET /v1/usage returns the live values for your account.

Headers #

Every response includes:

HeaderDescription
X-RateLimit-LimitRequests permitted per minute on your plan.
X-RateLimit-RemainingRequests left in the current 60-second window.
X-RateLimit-ResetUnix timestamp (seconds) when the window resets.
Retry-After(429 only) Seconds to wait before retrying.

Use these to self-throttle without ever hitting 429:

result = ctf.convert(file=f, source="png", target="jpg")
if result.rate_limit.remaining and result.rate_limit.remaining < 3:
    time.sleep(60)

What happens when you exceed a limit? #

Per-minute throttle #

HTTP/1.1 429 Too Many Requests
Retry-After: 28
X-RateLimit-Remaining: 0

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests in the last 60 seconds.",
    "details": { "retry_after": 28 }
  }
}

The SDKs surface this as RateLimitError, with the Retry-After value exposed as e.retry_after (Python) / e.retryAfter (TypeScript).

Monthly quota #

HTTP/1.1 429 Too Many Requests

{
  "error": {
    "code": "quota_exceeded",
    "message": "Monthly conversion quota exceeded.",
    "details": { "limit": 1000, "used": 1000 }
  }
}
  • Free plan: hard-stops. Wait for the 1st of next calendar month UTC, or upgrade.
  • Paid plans: by default, paid plans continue serving at the per-conversion overage rate. Disable overage from the dashboard if you'd rather hard-stop.

Best practices #

Read the headers — don't backoff blindly

Watching X-RateLimit-Remaining lets you smooth your traffic without wasting 429s. The SDK exposes them on every successful response.

Use jobs for bursty workloads

The 429 throttle is enforced on submitting requests, not on conversion completion. If you need to burst-submit 1000 conversions in 30 seconds, queue them as async jobs and let our worker pool drain at its own pace.

Respect Retry-After

Retry-After is the number of seconds until your window has fresh capacity. The SDKs don't auto-retry — that's an explicit choice so you control your retry policy. Sleep then retry.

Monitor /v1/usage

Surface monthly usage in your own dashboards. The free tier silently hard-stops at 1000/month — building this visibility upfront prevents "why are conversions failing on the 28th?" tickets.