Skip to main content

Usage limit overview

API call limits per month depend on your plan.

How API blocking works

When a Free or Trial account exceeds its monthly API call limit, the API returns a 429 Too Many Requests response:
{
  "detail": "API Calls limit reached."
}

Response headers

Blocked responses may include a Retry-After header indicating seconds until the monthly reset.

Handling rate limits

Detecting rate limits

Check for HTTP status code 429:
const response = await fetch(url);

if (response.status === 429) {
  const error = await response.json();
  console.log('API limit reached:', error.detail);
  // Check Retry-After header and wait until the monthly reset
}

What to do when blocked

  • Check your usage in Settings → Billing
  • Reduce call volume with caching and webhooks
  • Wait for the monthly reset or upgrade your plan
Paid plans are not blocked for monthly API call overages. If you see 429 on a paid plan, contact support.

Best practices for avoiding rate limits

1. Always include trailing slashes

All ButterCMS API URLs require a trailing slash. Requests without a trailing slash receive a 301 Redirect to the correct URL, which causes your client to make a second request — doubling your API call count.
# Bad — triggers a redirect, counts as 2 API calls
GET /v2/posts?auth_token=TOKEN

# Good — single request, counts as 1 API call
GET /v2/posts/?auth_token=TOKEN
Every missing trailing slash doubles your API usage for that request. This is the simplest way to accidentally burn through your monthly limit.
Instead of making many small requests, use features like: Multi-collection retrieval:
# Fetch multiple collections in one request
GET /content/?keys=categories,tags,authors
Reference resolution:
# Let ButterCMS resolve references automatically
GET /pages/homepage/?levels=2

3. Implement client-side caching

Cache API responses in your application:
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes

async function fetchCached(url) {
  const cached = cache.get(url);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.data;
  }

  const response = await fetch(url);
  const data = await response.json();

  cache.set(url, { data, timestamp: Date.now() });

  return data;
}

4. Use webhooks for real-time updates

Instead of polling the API for changes, use webhooks to receive notifications when content changes:
  • Reduces unnecessary API calls
  • Provides immediate update notifications
  • More efficient for cache invalidation

Write operations

Write API calls count toward your monthly API usage. For large imports, pace requests and monitor usage to avoid hitting monthly limits on Free or Trial accounts.

Monitoring API usage

Track your requests

Implement logging to understand your API usage patterns:
let requestCount = 0;
const requestLog = [];

async function trackedFetch(url) {
  requestCount++;
  const start = Date.now();

  const response = await fetch(url);

  requestLog.push({
    url,
    status: response.status,
    duration: Date.now() - start,
    timestamp: new Date().toISOString()
  });

  return response;
}

// Periodically review usage
setInterval(() => {
  console.log(`API requests in last hour: ${requestCount}`);
  requestCount = 0;
}, 3600000);

Check ButterCMS status

Monitor the ButterCMS Status Page for:
  • Service availability
  • Planned maintenance

When you need higher monthly limits

If your application requires higher monthly API call limits:
  1. Review your implementation - Often, optimizations can reduce API calls significantly
  2. Contact ButterCMS support - Discuss your use case at support@buttercms.com
  3. Consider plan upgrades - Higher-tier plans include increased limits

Summary

Best PracticeImpact
Always use trailing slashesPrevents redirect doubling your call count
Batch collection requestsFetches multiple collections in one call
Implement client cachingFewer API calls
Use webhooksEliminates polling
Respect Retry-AfterClear recovery for 429 blocks