Menu
Docs/Rate Limits & Plan Features

Rate Limits & Plan Features

Two levels of limits apply to every API key, plus feature restrictions by plan.

Request limits by plan

PlanPer MinutePer MonthMax ResolutionPrice
Free51001920×1080$0
Starter305,0003840×2160$19/mo
Growth6025,0003840×2160$49/mo
Business120100,0003840×2160$149/mo
Enterprise300Unlimited3840×2160Custom

Feature access by plan

Not all features are available on every plan. Requests using a restricted feature return 403 with plan_required.

FeatureFreeStarterGrowthBusinessEnterprise
Screenshot API
PNG & JPEG
Dark mode
Device presets
Caching
WebP format
Full page
Retina (2× DPR)
Ad blocking
CSS injection
OG Image API
No watermark
JS injection
Stealth mode
Custom proxy
Custom templates
Team members310Unlimited
SupportCommunityEmailPrioritySlackDedicated
SLA99.9%Custom

Response headers

Every response includes rate limit info:

X-RateLimit-Limit: 30        # Your plan's per-minute limit
X-RateLimit-Remaining: 22    # Requests left this minute
X-RateLimit-Reset: 1711382400  # Unix timestamp when the window resets

When rate limited:

HTTP/1.1 429 Too Many Requests
Retry-After: 30

Handling 429 errors

Per-minute rate limit exceeded:

{
  "error": "rate_limited",
  "message": "Rate limit exceeded. Retry after 30 seconds",
  "status": 429,
  "retry_after": 30
}

Monthly quota exceeded:

{
  "error": "quota_exceeded",
  "message": "Monthly request quota exceeded. Upgrade plan.",
  "status": 429
}

Feature access denied (403)

When you use a feature above your plan:

{
  "error": "plan_required",
  "message": "Stealth mode requires Growth plan or above",
  "required_plan": "growth",
  "status": 403
}

Retry strategy

Implement exponential backoff when you receive a 429. Start with the Retry-After value and double on each subsequent failure.

async function screenshotWithRetry(url, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(`https://api.snapsharp.dev/v1/screenshot?url=${url}`, {
      headers: { Authorization: `Bearer ${process.env.SNAPSHARP_KEY}` },
    });
    if (res.status === 429) {
      const retryAfter = parseInt(res.headers.get('Retry-After') ?? '30');
      await new Promise(r => setTimeout(r, retryAfter * 1000 * Math.pow(2, attempt)));
      continue;
    }
    return res;
  }
  throw new Error('Max retries reached');
}

Usage monitoring

  • Check your current usage via the Usage API or the Dashboard
  • Set up webhooks to get alerts at 80% and 100% usage
  • Export usage data as CSV from the dashboard