Rate Limits
Understand rate limiting, quotas, and best practices for efficient API usage.
Rate limits protect the API from abuse and ensure fair usage across all users. Limits are enforced using a sliding window algorithm and vary by subscription plan.
Per-Plan Limits
| Plan | Price | Requests / Minute | Requests / Day |
|---|---|---|---|
| Free | Free | 10 | 100 |
| Basic | ₹499/mo | 60 | 1,000 |
| Pro | ₹1,499/mo | 200 | 10,000 |
| Enterprise | ₹4,999/mo | 1,000 | 100,000 |
Rate Limit Headers
Every API response includes rate limit information in the response headers. Use these to monitor your usage and proactively avoid hitting limits:
| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute for your plan | 60 |
X-RateLimit-Remaining | Number of requests remaining in the current window | 45 |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets | 1707142260 |
HTTP/1.1 200 OKContent-Type: application/jsonX-RateLimit-Limit: 60X-RateLimit-Remaining: 45X-RateLimit-Reset: 1707142260X-Request-ID: req_abc123X-API-Version: v1X-Disclaimer: Data for informational purposes only. Not investment advice.X-Data-Source: Aggregated from publicly accessible sources including NSE, BSE, AMFI, RBIRate Limit Exceeded (429)
When you exceed the rate limit, the API returns a 429 Too Many Requests response. The response includes a Retry-After header indicating how many seconds to wait before retrying:
{
"success": false,
"error": {
"code": "RATE_001",
"message": "Rate limit exceeded. Please wait before making more requests.",
"documentation": "https://docs.ipoguruji.com/errors/RATE_001",
"retryAfter": 30
},
"disclaimer": "Data aggregated from publicly accessible sources. Not investment advice.",
"timestamp": "2026-02-09T14:30:00.000Z",
"requestId": "req_r4t3l1m2t3"
}HTTP/1.1 429 Too Many RequestsContent-Type: application/jsonRetry-After: 30X-RateLimit-Limit: 60X-RateLimit-Remaining: 0X-RateLimit-Reset: 1707142290Handling Rate Limits in Code
Implement exponential backoff with jitter to gracefully handle rate limit errors:
async function fetchWithRetry(url, apiKey, maxRetries = 3) { for (let attempt = 0; attempt <= maxRetries; attempt++) { const response = await fetch(url, { headers: { 'X-API-Key': apiKey }, }); if (response.status === 429) { const retryAfter = parseInt( response.headers.get('Retry-After') || '30', 10 ); // Add jitter: random delay between 0-1 second const jitter = Math.random() * 1000; const delay = retryAfter * 1000 + jitter; console.log( `Rate limited. Retrying in ${Math.round(delay / 1000)}s...` ); await new Promise((resolve) => setTimeout(resolve, delay)); continue; } return response.json(); } throw new Error('Max retries exceeded');}Monitoring Your Usage
You can check your current usage and remaining quota at any time using the usage endpoint:
curl -X GET "https://api.ipoguruji.com/v1/usage" \ -H "X-API-Key: ipg_live_your_api_key_here"You can also view your usage history and detailed analytics in your dashboard.
Best Practices
Cache responses locally
Cache API responses on your server. IPO list data can be cached for 5-15 minutes. GMP data changes every ~2 hours.
Monitor X-RateLimit-Remaining
Track the remaining requests header and slow down before hitting zero. This prevents 429 errors entirely.
Use webhooks instead of polling
For real-time updates, use webhooks instead of polling endpoints repeatedly. Available on Pro and Enterprise plans.
Use exponential backoff with jitter
When retrying after a 429 error, always use exponential backoff with random jitter to avoid thundering herd problems.
Upgrade your plan if needed
If you consistently hit rate limits, consider upgrading to a higher-tier plan. View pricing for details.