Rate Limits
To protect shared resources, rate limits are enforced on all endpoints except /usage.
Limits
Section titled “Limits”| Protection | Limit | Scope |
|---|---|---|
| Daily requests | 20 per day | Per user (across all your API keys) |
| Concurrent requests | 1 at a time | Per user (across all your API keys) |
What counts
Section titled “What counts”| Endpoint | Counts toward limit? |
|---|---|
/try_on_outfit | Yes |
/style_me | Yes |
/analyze_outfit | Yes |
/images | No — free and unlimited |
/images/:id | No — free and unlimited |
/usage | No — free and unlimited |
Limits are tracked per user account, not per API key. If you have multiple keys, they all share the same 20-request daily quota. The counter resets at midnight UTC.
Rate limit headers
Section titled “Rate limit headers”All rate-limited responses include these headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per day (20) |
X-RateLimit-Remaining | Requests remaining today |
X-RateLimit-Reset | UTC timestamp when the limit resets (on 429 only) |
Retry-After | Seconds until you can retry (on 429 only) |
429 responses
Section titled “429 responses”Daily limit exceeded
Section titled “Daily limit exceeded”When you’ve used all 20 requests for the day:
{ "error": "Daily rate limit exceeded. You can make 20 requests per day.", "limit": 20, "remaining": 0, "reset": "2026-03-01T00:00:00.000Z"}Concurrent request in progress
Section titled “Concurrent request in progress”If you send a second request while one is still processing:
{ "error": "A request is already in progress. Please wait for it to complete."}Checking your quota
Section titled “Checking your quota”The /usage endpoint returns your current rate limit status:
curl https://mcll3bnfubyazfg6wekv3xc6fi0dgpyk.lambda-url.us-east-1.on.aws/usage \ -H "X-API-Key: ss_your_key_here"{ "total_requests": 42, "requests_today": 7, "rate_limit": { "daily_limit": 20, "used_today": 5, "remaining": 15 }}Note: requests_today counts all requests (including /usage), while rate_limit.used_today only counts rate-limited endpoints.
Handling 429 in your code
Section titled “Handling 429 in your code”Python
Section titled “Python”import timeimport requests
def call_with_retry(func, *args, max_retries=3, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except requests.HTTPError as e: if e.response.status_code == 429: retry_after = int(e.response.headers.get("Retry-After", 30)) print(f"Rate limited. Retrying in {retry_after}s...") time.sleep(retry_after) else: raise raise Exception("Max retries exceeded")TypeScript / JavaScript
Section titled “TypeScript / JavaScript”async function callWithRetry<T>(fn: () => Promise<Response>, maxRetries = 3): Promise<T> { for (let i = 0; i < maxRetries; i++) { const res = await fn();
if (res.status === 429) { const retryAfter = parseInt(res.headers.get("Retry-After") || "30", 10); console.log(`Rate limited. Retrying in ${retryAfter}s...`); await new Promise((r) => setTimeout(r, retryAfter * 1000)); continue; }
if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); } throw new Error("Max retries exceeded");}