API & Developers·6 min read·Updated 1 April 2026

API Rate Limits

AskBiz API rate limits by endpoint. How limits work, HTTP 429 error handling, exponential backoff implementation, webhook alternatives to polling, and how to optimise your integration to stay well within limits.

Default Rate Limits

Rate limits are applied per API key, not per account. If you have multiple integrations using separate keys, each has its own independent limit bucket:

  • Standard endpoints (GET /pulse, GET /alerts, GET /brief): 60 requests/minute, 1,000/hour
  • AI question endpoint (POST /ask): 10 requests/minute, 100/hour — AI generation is compute-intensive; this limit prevents runaway costs
  • Data push endpoint (POST /data/push): 30 requests/minute, 500/hour
  • Tool endpoints (GET /tools/fx-risk, GET /tools/landed-cost): 20 requests/minute, 200/hour

All limits reset on a rolling window basis — not at the top of the clock hour. A rolling window means the limit applies to any 60-second or 60-minute period, not fixed clock boundaries. This is stricter than fixed-window rate limiting: sending 60 requests in the last 5 seconds of a minute and 60 more in the first 5 seconds of the next minute will trigger a 429 even though you're in two different clock-minutes.

Rate Limit Response Headers

Every API response includes rate limit headers so you can track your usage proactively:

  • X-RateLimit-Limit — your total limit for this endpoint (per minute)
  • X-RateLimit-Remaining — requests remaining in the current rolling window
  • X-RateLimit-Reset — Unix timestamp (seconds) when the current window resets
  • X-RateLimit-Retry-After — only present on 429 responses; seconds to wait before retrying

Read these headers in your integration to implement proactive throttling:

```

if (response.headers['x-ratelimit-remaining'] < 5) {

// slow down — you're close to the limit

await sleep(2000);

}

```

Handling HTTP 429 — Too Many Requests

When you exceed a rate limit, the API returns HTTP 429 Too Many Requests with:

  • A JSON body: { "error": "rate_limit_exceeded", "retry_after": 12 }
  • The Retry-After header set to the number of seconds to wait

Never retry immediately on a 429. Always wait at least the retry_after value. The recommended pattern is exponential backoff with jitter:

```javascript

async function fetchWithRetry(url, options, maxRetries = 4) {

for (let attempt = 0; attempt < maxRetries; attempt++) {

const res = await fetch(url, options);

if (res.status !== 429) return res;

const retryAfter = res.headers.get('retry-after') || 1;

const backoff = Math.min(

parseInt(retryAfter) * 1000 + Math.random() * 1000,

30000 // cap at 30 seconds

);

await new Promise(r => setTimeout(r, backoff));

}

throw new Error('Max retries exceeded');

}

```

The jitter (Math.random() * 1000) prevents thundering herd — if multiple instances of your service all hit the limit simultaneously and retry at exactly the same moment, they'll hit it again immediately.

Webhooks — The Alternative to Polling

The most common cause of hitting rate limits is polling — repeatedly calling GET /alerts or GET /pulse on a timer to check for changes. This is inefficient and rate-limit-prone.

Use webhooks instead. AskBiz can push events to your endpoint the moment they occur:

Available webhook events:

  • pulse.updated — fires when your Business Pulse score changes
  • alert.triggered — fires when an anomaly alert is detected
  • brief.ready — fires when your Daily Brief is generated
  • sync.completed — fires when a data source sync finishes
  • churn.scan.completed — fires when a churn scan completes

To set up a webhook:

1. Go to Account Settings → Developer → Webhooks

2. Enter your endpoint URL (must be HTTPS)

3. Select the events you want to receive

4. Copy the webhook signing secret

5. Verify the X-AskBiz-Signature header on incoming requests using HMAC-SHA256

Webhook deliveries don't count against your rate limits. You receive exactly one request per event, rather than polling hundreds of times waiting for an event to occur.

Caching Strategy

Most AskBiz data doesn't change second-by-second. Cache aggressively to stay within limits:

Business Pulse score: Updates at most every 6 hours (Growth) or on sync events (Business). Cache for 30 minutes minimum — there's no value in fetching it more often.

Daily Brief: Generated once per day. Cache until midnight and fetch fresh the next morning.

Anomaly alerts: New alerts are infrequent. Cache the alert list for 15 minutes, or better — use webhooks (see above).

Tool results (FX Risk, Landed Cost): These are deterministic for a given input. Cache the result by input parameters. If the inputs haven't changed, the result won't have changed either.

Example caching pattern with a simple in-memory TTL:

```javascript

const cache = new Map();

async function getCachedPulse() {

const cached = cache.get('pulse');

if (cached && Date.now() - cached.ts < 30 * 60 * 1000) {

return cached.data; // return cached if < 30 mins old

}

const data = await fetchPulse();

cache.set('pulse', { data, ts: Date.now() });

return data;

}

```

Batching Data Pushes

If you're using POST /data/push to send custom data records, always batch them rather than sending one record per request.

The endpoint accepts up to 1,000 records per request. Sending 500 records individually uses 500 of your 500/hour quota. Sending them as a single batch uses just 1.

Batch structure:

```json

{

"records": [

{ "date": "2026-04-01", "revenue": 1240.50, "channel": "pos" },

{ "date": "2026-04-01", "revenue": 890.00, "channel": "pos" }

]

}

```

For high-volume integrations (e.g. a POS system sending every transaction), collect records in a buffer and flush on a timer (e.g. every 5 minutes) rather than pushing immediately on each transaction.

Higher Limits and Enterprise

If your integration legitimately requires higher limits — for example, you're building a multi-tenant product that serves your own customers on top of AskBiz, or you're running large-scale data imports — contact hello@askbiz.co to discuss an Enterprise arrangement.

Enterprise limits are negotiated based on your specific use case. Factors that affect the available limit include:

  • Number of end-users your integration serves
  • Endpoint mix (AI endpoints have a higher cost per call than data endpoints)
  • Whether you're on a flat-rate or usage-based billing arrangement

There is no self-serve way to increase limits — all limit increases require a conversation with our team.

Frequently Asked Questions

Was this article helpful?

Still stuck? Email our support team.