|
| 1 | +# API Rate Limiting Documentation |
| 2 | + |
| 3 | +StrellerMinds employs a multi-layered rate limiting strategy to ensure platform stability, prevent abuse, and provide fair resource allocation across different user tiers. |
| 4 | + |
| 5 | +## 1. Overview |
| 6 | +Rate limits are applied at two levels: |
| 7 | +1. **Global IP-based Limiting**: Applied to all requests based on the client's IP address. |
| 8 | +2. **Tiered User Limiting**: Applied to authenticated requests based on the account's subscription tier. |
| 9 | + |
| 10 | +Limits are calculated using a **sliding window** of 60 seconds. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## 2. Global Limits (IP-Based) |
| 15 | +These limits apply to all unauthenticated traffic and serve as a first line of defense. |
| 16 | + |
| 17 | +| Endpoint Group | Limit | Description | |
| 18 | +|----------------|-------|-------------| |
| 19 | +| **General API** | 60 requests / min | Applies to most endpoints (`/auth`, `/students`, etc.) | |
| 20 | +| **Verify Endpoint** | 100 requests / min | Specifically for `GET /api/v1/certificates/:id/verify` | |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## 3. Tiered User Limits (Authenticated) |
| 25 | +Authenticated requests are subject to higher limits based on the user's assigned tier. Authenticated users benefit from a **Token Bucket** algorithm that allows for short bursts of traffic. |
| 26 | + |
| 27 | +| Tier | Limit (RPM) | Burst Allowance | Use Case | |
| 28 | +|------|-------------|-----------------|----------| |
| 29 | +| **Free** | 30 | 10 | Individual students and researchers | |
| 30 | +| **Pro** | 120 | 30 | Professional educators and small institutions | |
| 31 | +| **Enterprise**| 600 | 100 | Large universities and corporate partners | |
| 32 | +| **Internal** | 6,000 | 500 | StrellerMinds internal services and high-trust partners | |
| 33 | + |
| 34 | +--- |
| 35 | + |
| 36 | +## 4. Response Headers |
| 37 | +Every API response includes headers to help you track your current usage. |
| 38 | + |
| 39 | +| Header | Description | |
| 40 | +|--------|-------------| |
| 41 | +| `X-RateLimit-Limit` | The maximum number of requests allowed in the current window. | |
| 42 | +| `X-RateLimit-Remaining` | The number of requests remaining in the current window. | |
| 43 | +| `X-RateLimit-Reset` | The Unix timestamp when the current rate limit window resets. | |
| 44 | +| `X-RateLimit-Tier` | The subscription tier applied to the current request. | |
| 45 | +| `X-RateLimit-Burst-Limit` | (Authenticated only) The size of your burst bucket. | |
| 46 | +| `Retry-After` | (Only on 429 errors) Number of seconds to wait before retrying. | |
| 47 | + |
| 48 | +--- |
| 49 | + |
| 50 | +## 5. Error Responses |
| 51 | +When a limit is exceeded, the API returns a `429 Too Many Requests` status code. |
| 52 | + |
| 53 | +### 5.1. Global Limit Exceeded |
| 54 | +```json |
| 55 | +{ |
| 56 | + "success": false, |
| 57 | + "data": null, |
| 58 | + "error": { |
| 59 | + "code": "RATE_LIMIT_EXCEEDED", |
| 60 | + "message": "Too many requests. Please slow down and try again later.", |
| 61 | + "details": { |
| 62 | + "retryAfter": 60 |
| 63 | + } |
| 64 | + } |
| 65 | +} |
| 66 | +``` |
| 67 | + |
| 68 | +### 5.2. User Tier Limit Exceeded |
| 69 | +```json |
| 70 | +{ |
| 71 | + "success": false, |
| 72 | + "data": null, |
| 73 | + "error": { |
| 74 | + "code": "USER_RATE_LIMIT_EXCEEDED", |
| 75 | + "message": "Rate limit exceeded for tier 'free'. Limit: 30 req/min, burst: 10 req/10s.", |
| 76 | + "details": { |
| 77 | + "tier": "free", |
| 78 | + "limit": 30, |
| 79 | + "burstLimit": 10, |
| 80 | + "retryAfter": 45, |
| 81 | + "upgradeUrl": "https://strellerminds.com/pricing" |
| 82 | + } |
| 83 | + } |
| 84 | +} |
| 85 | +``` |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## 6. Monitoring Usage |
| 90 | +You can programmatically check your current status using the following endpoints: |
| 91 | + |
| 92 | +- **Check Current Status**: `GET /api/v1/rate-limit/status` (Requires Auth) |
| 93 | +- **List Tier Definitions**: `GET /api/v1/rate-limit/tiers` (Public) |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## 7. Best Practices |
| 98 | +1. **Honor `Retry-After`**: Always respect the `Retry-After` header. Hard-polling after a 429 may result in temporary IP blocking. |
| 99 | +2. **Exponential Backoff**: Implement an exponential backoff strategy for retries to smooth out traffic spikes. |
| 100 | +3. **Caching**: Cache immutable resources (like certificate details) locally to reduce redundant API calls. |
| 101 | +4. **Header Monitoring**: Monitor `X-RateLimit-Remaining` to proactively slow down requests as you approach your limit. |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## 8. Code Example (JavaScript) |
| 106 | +```javascript |
| 107 | +async function fetchWithRetry(url, options = {}) { |
| 108 | + const response = await fetch(url, options); |
| 109 | + |
| 110 | + if (response.status === 429) { |
| 111 | + const retryAfter = response.headers.get('Retry-After') || 5; |
| 112 | + console.warn(`Rate limited. Retrying after ${retryAfter}s...`); |
| 113 | + |
| 114 | + await new Promise(resolve => setTimeout(resolve, retryAfter * 1000)); |
| 115 | + return fetchWithRetry(url, options); |
| 116 | + } |
| 117 | + |
| 118 | + return response.json(); |
| 119 | +} |
| 120 | +``` |
0 commit comments