CiteFlow API

Rate limits

Per-key sliding-window limits + tier ceilings.

CiteFlow enforces a sliding-window rate limit per API key, per endpoint. Each key has its own bucket — your CI key hitting the wall won't deplete your production key's budget.

The tier ceiling is derived from lifetime_purchased credits, so you auto-promote into higher limits as you spend more.

Tier ceilings

EndpointStarterGrowthScaleEnterprise
POST /audit30/min · 1k/day60/min · 5k/day200/min · 25k/day1k/min · unlimited
GET /audit/{id}300/min600/min1.2k/min6k/min
GET /balance60/min60/min60/min60/min
POST /audit/{id}:cancel30/min60/min200/min600/min
POST /billing/topup10/min · 100/day10/min · 100/day20/min · 200/day60/min
POST /webhooks/deliveries/{id}/replay10/min10/min30/min60/min

Sliding-window algorithm allows ~10% burst above the documented limit; do not depend on the burst. The window slides continuously, so spreading load is always better than spiking.

Headers on every response

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
X-RateLimit-Reset: 1748400060
HeaderMeaning
X-RateLimit-LimitThe current cap.
X-RateLimit-RemainingCalls left before the next reset.
X-RateLimit-ResetUnix epoch (seconds) when the window rolls.

When you hit the wall:

HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Remaining: 0
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded for POST /audit. Retry after 12s.",
    "retryAfter": 12
  }
}

Tier derivation

Tier comes from cumulative lifetime_purchased:

Lifetime purchasedTier
< 20,900 (Starter)starter
≥ 20,900growth
≥ 54,900scale
≥ 100,000enterprise

Top up to instantly raise your ceiling — the tier check happens on the hot path.

Per-key overrides

Enterprise customers and customers experiencing incidents can request temporary per-key overrides via partners@citeflow.io. Overrides live in partner_api_keys.rate_limit_overrides and never expose other partners' settings.

Best practices

  • Spread sustained load — sliding window punishes spikes.
  • Pre-flight GET /balance when in doubt before POST /audit; 402 has cost (rate-limited too) but the balance call is cheap.
  • Use webhooks instead of polling — GET /audit/{id} allows generous polling rates, but webhooks are still cheaper and faster.
  • Backoff on 429 — exponential with jitter, never tight-loop retry. The SDK does this for you.

On this page