Rate Limits

Rate limits protect the SignalStack API from abuse and ensure fair resource distribution. Limits are applied per API key and reset on a rolling hourly window.

Rate limit tiers

PlanRequests / HourRequests / MonthBurst LimitConcurrency
Starter105,00021
Business1,00050,0005010
EnterpriseCustomUnlimitedCustomCustom

Rate limit headers

Every API response includes rate limit information:

Code
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 842
X-RateLimit-Reset: 1700000000
X-RateLimit-Policy: 1000;w=3600
HeaderDescriptionExample
X-RateLimit-LimitMaximum requests allowed in the window1000
X-RateLimit-RemainingRequests remaining in the current window842
X-RateLimit-ResetUnix timestamp when the window resets1700000000
X-RateLimit-PolicyHuman-readable rate limit policy1000;w=3600
Retry-AfterSeconds to wait before retrying (on 429 only)3600

Rate limit error

When a rate limit is exceeded, the API returns 429 Too Many Requests:

Code
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1700003600
Retry-After: 3600

{`{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Limit: 1000 requests per hour. Resets at 2025-01-22T15:00:00Z.",
    "retry_after": 3600,
    "request_id": "vrf_a1b2c3d4e5f6"
  }
}`}

Burst handling

SignalStack uses a token bucket algorithm that allows short bursts above the sustained rate. The burst limit is the maximum number of requests you can send in a single minute without triggering rate limiting.

  • Starter: Burst of 2 requests per minute
  • Business: Burst of 50 requests per minute
  • Enterprise: Custom burst limits configured to your traffic patterns

Handling rate limits in code

Code
# Python — with retry + rate limit awareness
import time
from signalstack import SignalStack, RateLimitError

client = SignalStack(api_key="ssk_live_...")

def verify_with_rate_handling(claim: str):
    while True:
        try:
            return client.verify.claim(claim=claim)
        except RateLimitError as e:
            retry_after = e.retry_after  # seconds
            print(f"Rate limited. Retrying in {retry_after}s...")
            time.sleep(retry_after)
Code
// TypeScript — check remaining before requests
import { SignalStack, RateLimitError } from "@signalstack/sdk"

const client = new SignalStack({ apiKey: "ssk_live_..." })

async function verifyWithRateCheck(options: VerifyClaimOptions) {
  const remaining = client.getRemainingRateLimit()
  if (remaining !== null && remaining < 10) {
    console.warn(`Only ${remaining} requests remaining in window`)
  }
  return client.verify.claim(options)
}

Upgrade paths

If you consistently hit rate limits, consider upgrading:

Current PlanNext TierBenefit
Starter (10/hr)Business (1,000/hr)100x more requests, burst, media & claim endpoints, paid data sources
Business (1,000/hr)Enterprise (custom)Custom rate limits, dedicated infra, on-premise

Best practices

  • Monitor X-RateLimit-Remaining to anticipate limits
  • Cache verification results when appropriate (respect TTL)
  • Use batch verification (Enterprise) instead of multiple single calls
  • Implement exponential backoff with jitter for 429 responses
  • Contact sales for custom rate limits if needed

Next steps