Rate Limits & Quotas

Understand API rate limits and monthly quotas by subscription tier.

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:

  1. Per-minute limits — Maximum requests per minute
  2. 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

  1. Respect Retry-After — Wait the specified time before retrying
  2. Implement exponential backoff — If still rate limited, wait progressively longer
  3. 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:

  1. Go to Dashboard > Developer > Settings
  2. Enable usage alerts
  3. 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

On this page