ClipCash API implements comprehensive rate limiting to ensure fair usage, prevent abuse, and maintain system stability for all users.
Rate limits are applied per IP address and reset automatically after the specified time window. All limits are enforced using Redis-backed throttling for distributed deployments.
- Limit: 100 requests per 60 seconds
- Applies to: Most general API endpoints
- Use case: Standard API operations, listing resources, fetching data
- Limit: 10 requests per 60 seconds
- Applies to:
POST /auth/loginPOST /auth/registerPOST /auth/password-resetPOST /auth/google
- Use case: Authentication operations to prevent brute force attacks
- Limit: 3 requests per 15 minutes (900 seconds)
- Applies to:
POST /auth/mfa/enableDELETE /users/:idPUT /users/:id/change-password
- Use case: Critical security operations requiring additional protection
- Limit: 3 requests per 60 minutes (3600 seconds)
- Applies to:
POST /auth/resend-verification
- Use case: Prevents spam and abuse of email services
- Limit: 10 requests per 60 seconds
- Applies to:
POST /clips/generatePOST /videos/:id/clips
- Use case: Resource-intensive video processing operations
- Limit: 5 requests per 60 seconds
- Applies to:
POST /clips/:id/mintPOST /nft/mint
- Use case: Blockchain operations with gas costs
- Limit: 10 requests per 60 seconds
- Applies to:
POST /wallets/connect
- Use case: Wallet connection operations
- Limit: 10 requests per 60 seconds
- Applies to:
DELETE /wallets/:id
- Use case: Wallet disconnection operations
- Limit: 5 requests per 60 seconds
- Applies to:
POST /payoutsPOST /transactions/send
- Use case: Blockchain transaction submissions
Every API response includes rate limit information in the following headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704067200| Header | Description | Example |
|---|---|---|
X-RateLimit-Limit |
Maximum number of requests allowed in the current window | 100 |
X-RateLimit-Remaining |
Number of requests remaining in the current window | 95 |
X-RateLimit-Reset |
Unix timestamp (seconds) when the rate limit window resets | 1704067200 |
When you exceed the rate limit, the API returns a 429 Too Many Requests status code:
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests",
"error": "Too Many Requests"
}The response also includes the standard rate limit headers showing when the limit will reset.
Always check the X-RateLimit-Remaining header to know how many requests you have left.
const response = await fetch('https://api.clipcash.io/clips');
const remaining = response.headers.get('X-RateLimit-Remaining');
if (parseInt(remaining) < 10) {
console.warn('Approaching rate limit!');
}When you receive a 429 response, implement exponential backoff before retrying:
async function fetchWithRetry(url: string, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url);
if (response.status === 429) {
const resetTime = parseInt(response.headers.get('X-RateLimit-Reset'));
const waitTime = Math.min((resetTime * 1000) - Date.now(), 60000);
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}Reduce API calls by caching responses that don't change frequently:
const cache = new Map();
async function getCachedClips(videoId: string) {
if (cache.has(videoId)) {
return cache.get(videoId);
}
const clips = await fetch(`/videos/${videoId}/clips`).then(r => r.json());
cache.set(videoId, clips);
// Cache for 5 minutes
setTimeout(() => cache.delete(videoId), 5 * 60 * 1000);
return clips;
}For real-time updates, use webhooks instead of repeatedly polling endpoints:
// ❌ Bad: Polling every second
setInterval(async () => {
const status = await fetch('/clips/123/status');
// ...
}, 1000);
// ✅ Good: Use WebSocket or webhook
const socket = new WebSocket('wss://api.clipcash.io');
socket.on('clip:status', (data) => {
// Handle status update
});Group multiple operations into a single request if the API supports it:
// ❌ Bad: Multiple requests
for (const clip of clips) {
await fetch(`/clips/${clip.id}`, { method: 'DELETE' });
}
// ✅ Good: Batch delete (if supported)
await fetch('/clips/bulk-delete', {
method: 'POST',
body: JSON.stringify({ clipIds: clips.map(c => c.id) })
});For production integrations requiring higher limits, you can request IP whitelisting by contacting support.
Set the THROTTLER_WHITELIST environment variable with comma-separated IPs:
THROTTLER_WHITELIST=192.168.1.100,10.0.0.50Whitelisted IPs bypass all rate limits.
Rate limits are configured in src/app.module.ts:
ThrottlerModule.forRootAsync({
throttlers: [
{
name: 'default',
ttl: 60000, // 60 seconds
limit: 100, // 100 requests
},
{
name: 'auth',
ttl: 60000, // 60 seconds
limit: 10, // 10 requests
},
// ... more tiers
],
})To apply a specific tier to a controller or route:
import { Throttle } from '@nestjs/throttler';
@Controller('clips')
export class ClipsController {
@Post('generate')
@Throttle({ clipGenerate: { ttl: 60000, limit: 10 } })
async generateClips() {
// ...
}
}You can test rate limits in development:
# Send 15 requests to auth endpoint (limit: 10)
for i in {1..15}; do
curl -X POST http://localhost:3000/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"wrong"}' \
-i | grep -E "HTTP|X-RateLimit"
doneExpected output:
- Requests 1-10:
200 OKor401 Unauthorized - Requests 11-15:
429 Too Many Requests
Rate limits are enforced using Redis, which allows consistent limits across multiple server instances in a load-balanced environment.
Monitor rate limit hits using the /metrics endpoint:
# Rate limit rejections by endpoint
clipcash_http_request_duration_seconds{status_code="429"}
If your use case requires different limits, contact the development team or submit a pull request with justification.
For questions or issues related to rate limits:
- Open an issue: GitHub Issues
- Contact support: support@clipcash.io
- Request higher limits: api@clipcash.io