The Stepsies API implements rate limiting to ensure fair usage and maintain service quality. This guide explains the limits that apply to your account.
Overview
Rate limits are applied at two levels:
- Per-minute limits — Maximum requests per minute
- Monthly quotas — Maximum requests per billing cycle
Limits are based on your subscription plan and apply to all API keys under your account.
Rate Limits by Plan
| Plan | Requests/Minute | Requests/Hour | Monthly Quota |
|---|---|---|---|
| Pro | 300 | 10,000 | 50,000 |
| Team | 600 | 30,000 | 200,000 |
| Enterprise | Custom | Custom | Custom |
Need higher limits?
Contact us at [email protected] to discuss Enterprise plans with custom rate limits.
Rate Limit Headers
Every API response includes headers showing your current rate limit status:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295
X-RateLimit-Reset: 1702500000
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests allowed per minute |
X-RateLimit-Remaining |
Requests remaining in current window |
X-RateLimit-Reset |
Unix timestamp when the limit resets |
Handling Rate Limits
When you exceed the rate limit, the API returns a 429 Too Many Requests response:
{ "error": { "code": "rate_limit_exceeded", "message": "Too many requests. Please slow down.", "retry_after": 45 } }
The response includes a Retry-After header indicating how many seconds to wait:
HTTP/1.1 429 Too Many Requests Retry-After: 45 Content-Type: application/json
Best Practices for Handling 429 Errors
- Respect
Retry-After— Wait the specified time before retrying - Implement exponential backoff — If still rate limited, wait progressively longer
- Add jitter — Add random delays to prevent thundering herd
async function fetchWithRetry(url, options, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, options); if (response.status === 429) { const retryAfter = parseInt(response.headers.get('Retry-After') || '60'); const jitter = Math.random() * 1000; // 0-1 second of jitter await sleep((retryAfter * 1000) + jitter); continue; } return response; } throw new Error('Max retries exceeded'); }
Monthly Quotas
Monthly quotas reset on the first day of each billing cycle. To check your current usage:
curl https://api.stepsies.com/v1/usage \ -H "Authorization: Bearer sk_your_api_key"
Response:
{ "period": "2024-12", "requests_used": 15420, "quota_limit": 50000, "quota_remaining": 34580, "usage_percentage": 30.8, "rate_limits": { "per_minute": 300, "per_hour": 10000 } }
Quota Exceeded
When you exceed your monthly quota, the API returns a 402 Payment Required response:
{ "error": { "code": "quota_exceeded", "message": "Monthly API quota exceeded. Please upgrade your plan.", "upgrade_url": "https://stepsies.com/pricing" } }
Optimizing API Usage
Batch Operations
Instead of creating steps one at a time, include them in the stepsy creation request:
Inefficient (4 requests)
POST /stepsies
POST /stepsies/123/steps
POST /stepsies/123/steps
POST /stepsies/123/steps
Efficient (1 request)
POST /stepsies
{
"stepsy": {
"title": "...",
"steps": [...]
}
}
Caching
Cache responses that don’t change frequently:
const cache = new Map(); const CACHE_TTL = 60 * 1000; // 1 minute async function getStepsy(id) { const cacheKey = `stepsy:${id}`; const cached = cache.get(cacheKey); if (cached && Date.now() - cached.timestamp < CACHE_TTL) { return cached.data; } const response = await fetch(`/api/v1/stepsies/${id}`); const data = await response.json(); cache.set(cacheKey, { data, timestamp: Date.now() }); return data; }
Monitoring Usage
Dashboard
View your API usage in Dashboard > Developer:
- Current period usage vs quota
- Requests over time (chart)
- Top endpoints by usage
- Error rate breakdown
Usage Alerts
Set up alerts when you’re approaching your quota:
- Go to Dashboard > Developer > Settings
- Enable usage alerts
- Set thresholds (e.g., 80%, 90%, 100%)
You’ll receive email notifications when thresholds are reached.
FAQ
Do read and write requests count differently?
No, all successful API requests count equally toward your quota regardless of method (GET, POST, PATCH, DELETE).
Do failed requests count toward my quota?
Requests that return 4xx or 5xx errors do not count toward your monthly quota, but they do count toward rate limits.
Can I see usage per API key?
Yes, the Developer dashboard shows usage broken down by API key, allowing you to identify which integrations consume the most quota.
What happens to unused quota?
Monthly quota does not roll over. Unused requests expire at the end of each billing cycle.
Next Steps
- Authentication — Learn about API keys and scopes
- API Reference — Explore available endpoints