← Back to Docs
Rate Limits
Understand API rate limits and how to handle them.
Limits
| Scope | Limit | Window |
|---|---|---|
| API requests (per IP) | 100 | per minute |
| Notification sends | 60 | per minute |
| Auth attempts | 10 | per minute |
Response Headers
Every API response includes these headers:
| Header | Description |
|---|---|
| X-RateLimit-Limit | Maximum requests per window |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when the window resets |
Handling 429 Too Many Requests
When rate-limited, you receive a 429 response:
{
"error": "Rate limit exceeded",
"retryAfter": 42
}Best Practices
- Implement exponential backoff when you receive a 429 response.
- Check
X-RateLimit-Remainingto preemptively slow down requests. - Batch operations where possible instead of making many individual requests.
- Cache responses to reduce redundant API calls.
- Use webhooks instead of polling to get delivery status.
Example: Retry with Backoff
import time, requests
def send_with_retry(payload, max_retries=3):
for attempt in range(max_retries):
r = requests.post(
"https://api.notfs.dev/api/notifications",
json=payload,
headers={"X-API-Key": "ntfs_..."}
)
if r.status_code == 429:
wait = r.json().get("retryAfter", 2 ** attempt)
time.sleep(wait)
continue
r.raise_for_status()
return r.json()
raise Exception("Max retries exceeded")