Rate Limiting

Overview

The API enforces two independent rate limiting systems: a token-bucket throttle and a daily limit. Understanding both will help you design integrations that stay within limits.

Token-Bucket Throttle

The API uses a token-bucket algorithm to control request rates. The default limits are:

  • 60 request burst — you can fire up to 60 requests immediately
  • 1 request/second sustained — the bucket refills at 1 token per second after the burst is exhausted
  • 3,600 requests/hour effective throughput

Throttle Keys

The throttle bucket is keyed by subdomain and endpoint. For example, yourchurch:individuals and yourchurch:families have separate buckets. Multiple API users on the same organization share the bucket for the same endpoint.

Note that specific organizations or endpoints may have custom limits that differ from the defaults above.

Rate Limiting Headers

Every API response includes headers to help you monitor your usage:

HeaderDescription
X-RateLimit-LimitBurst capacity (e.g., 60).
X-RateLimit-RemainingTokens remaining in the bucket.
X-RateLimit-ResetUnix timestamp when the bucket will be fully refilled.

Throttled Responses

When the bucket is empty, the API returns HTTP 429 Too Many Requests with:

  • An empty body (no XML envelope)
  • A Retry-After header with the number of seconds to wait before retrying

Daily Limit

Separate from the token-bucket throttle, each API user has a daily call limit. When the limit is reached, the API returns a standard XML error response with code 5 (API_MESSAGE_QUERY_LIMIT_REACHED).

You can check your current usage without incrementing the counter by calling the api_status service:

curl -u username:password "https://yourchurch.ccbchurch.com/api.php?srv=api_status"

This returns:

  • daily_limit — total calls allowed per day
  • last_run_date — the last date the API was called
  • counter — total calls made on that date

Best Practices

  • Monitor X-RateLimit-Remaining on each response to stay ahead of throttle limits.
  • When you receive a 429, wait for the duration specified in the Retry-After header before retrying.
  • Spread requests evenly rather than sending them in bursts.
  • Check api_status periodically to monitor daily usage.
  • Cache responses where possible to reduce unnecessary calls.