Rate Limits
Plan quotas, edge throttling, and retry guidance
Overview
Plans include monthly quotas plus short-term edge throttles to protect the service. Monthly quotas:
Free
500,000 requests/month — attribution required
Launch
1,000,000 requests/month — attribution removed
Growth
5,000,000 requests/month — priority support
Enterprise
Custom limits — contact sales
Only the Free tier requires attribution. If attribution is not verified, the worker can return 403 before rate limits are applied.
Edge Throttling
To prevent abuse, the edge also enforces short-term per-minute thresholds by tier. These are higher than typical usage but can trigger 429s if you burst excessively; respect Retry-After when that happens.
Plan Details
| Plan | Price (monthly) | Yearly Prepay | Key Features |
|---|---|---|---|
| Free | $0 | - | Attribution required; 500k requests/month |
| Launch | $45 | $325 (~1M/mo) | Remove attribution, email support |
| Growth | $170 | $1,449 (~5M/mo) | Priority support & QA, self hosting/caching |
| Enterprise | Custom | Custom | Custom SLAs, unlimited options, dedicated support |
Rate Limit Headers
Every response includes:
X-RateLimit-Remaining: 482
X-RateLimit-Reset: 1706745600When limited, a Retry-After header is also present.
Header Details
| Header | Description |
|---|---|
X-RateLimit-Remaining | Requests left in the current minute for this key |
X-RateLimit-Reset | Unix timestamp when the current window resets |
Retry-After | Seconds to wait before retrying (only on 429) |
Handling 429 (Too Many Requests)
async function fetchLogoWithRetry(domain, apiKey, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(`https://logos.getquikturn.io/${domain}?token=${apiKey}`);
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get('Retry-After') || 0);
const backoffMs = retryAfter ? retryAfter * 1000 : Math.pow(2, attempt) * 1000;
await new Promise((resolve) => setTimeout(resolve, backoffMs));
}
throw new Error('Rate limit retries exhausted');
}import time, requests
def fetch_logo_with_retry(domain: str, api_key: str, max_retries: int = 3):
for attempt in range(max_retries):
res = requests.get(f"https://logos.getquikturn.io/{domain}?token={api_key}")
if res.status_code != 429:
res.raise_for_status()
return res
retry_after = res.headers.get("Retry-After")
wait = int(retry_after) if retry_after else 2 ** attempt
time.sleep(wait)
raise RuntimeError("Rate limit retries exhausted")Avoiding Limits
- Cache logos in your app; the worker returns cacheable assets for 24h (
Cache-Control: public, max-age=86400). - Avoid unnecessary repeated requests on the same page load.
- Use separate keys per environment and per app to keep usage isolated.
Troubleshooting
- 429: Wait for the
Retry-Afterduration and retry with backoff. - 403: If you expect access, check domain restrictions and attribution status for your key.
- Unexpected 401: Ensure the key starts with
pk_and is still active in the portal.
See Errors for more debugging tips.