Rate Limits
The inSigner API enforces rate limits to ensure fair usage and platform stability.
Default limits
Section titled “Default limits”| Limit | Value |
|---|---|
| Requests per API key | 120 requests per minute |
| Bulk sends | 1 per 5 minutes per organization |
| Webhook creations | 10 per hour per user |
Rate limit headers
Section titled “Rate limit headers”Every API response includes rate limit headers so you can track your usage:
| Header | Description |
|---|---|
RateLimit-Limit | Maximum requests allowed in the current window |
RateLimit-Remaining | Requests remaining in the current window |
RateLimit-Reset | Seconds until the rate limit window resets |
Example response headers:
RateLimit-Limit: 120RateLimit-Remaining: 87RateLimit-Reset: 42Handling 429 responses
Section titled “Handling 429 responses”When you exceed the rate limit, the API returns a 429 Too Many Requests response with a Retry-After header:
{ "type": "https://docs.insigner.com/errors/rate-limited", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded. Please retry after the reset period."}Retry-After: 42Implementing retry logic
Section titled “Implementing retry logic”async function fetchWithRetry(url, options, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { const res = await fetch(url, options);
if (res.status === 429) { const retryAfter = parseInt(res.headers.get('Retry-After') || '60', 10); console.log(`Rate limited. Retrying in ${retryAfter}s...`); await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); continue; }
return res; }
throw new Error('Max retries exceeded');}import timeimport requests
def fetch_with_retry(url, headers, max_retries=3): for i in range(max_retries): res = requests.get(url, headers=headers)
if res.status_code == 429: retry_after = int(res.headers.get("Retry-After", 60)) print(f"Rate limited. Retrying in {retry_after}s...") time.sleep(retry_after) continue
return res
raise Exception("Max retries exceeded")Best practices
Section titled “Best practices”- Space out batch operations. If you’re creating many documents, add small delays between requests.
- Cache when possible. Templates and organization info don’t change often — cache those responses.
- Use webhooks instead of polling. Instead of repeatedly checking document status, set up a webhook to get notified automatically.
- Implement exponential backoff. If retries also get rate-limited, increase the delay between attempts.