KasarKasar Docs
API Reference

Rate Limits

The ceilings that apply to the API and to inbound webhooks, how they are counted, the headers that describe them, and how to back off.

Rate limits protect a platform shared by every workspace. A valid key is never exempt: an integration that sends a burst is slowed down before it can slow down anyone else.

The ceilings of the REST API

A request to /api/v1 meets these five ceilings in this order, and stops at the first one that refuses it:

PolicyLimitWindowCounted perChecked
api:ip1,0001 minute, fixedClient IP addressFirst, before the key is read
api:burst101 second, fixedIntegrationAfter the key's signature is checked, before any database read
api:token6001 minute, fixedIntegrationAfter the key is verified
api:global6001 minute, slidingIntegrationAfter the key is verified
api:global-org600 + 300 per active seat1 minute, fixedWorkspaceAfter the key is verified

In practice:

  • 10 requests per second per integration is the ceiling you meet first, and 600 per minute over any 60 seconds. Every key of an integration shares the same budget: a new key does not open a new one.
  • api:ip is wide on purpose, because an office shares one IP address. It is shared with the Kasar MCP connector called from the same address.
  • api:global-org caps the whole workspace: every integration, plus the members using the Kasar MCP connector. A workspace with 10 active seats has 3,600 requests per minute in total.
  • No route has a ceiling of its own: listing, reading and writing records all count the same.

How requests are counted

  • Every request counts, including one that is then refused: by authentication, by a later ceiling, by validation, or by the ceiling itself. Retrying in a loop while refused keeps you refused on the sliding window.
  • A fixed window opens with the first request and closes after its duration; a sliding window counts the requests of the last 60 seconds, whenever they arrived.
  • api:ip and api:burst are counted before Kasar reads anything from its database.

Headers on every response

Every response of the API carries the state of one ceiling, successes and errors alike:

HeaderMeaning
X-RateLimit-LimitThe limit of that ceiling
X-RateLimit-RemainingRequests left in its window
X-RateLimit-ResetUnix time, in seconds, by which the window has reset: the time of the request plus the window's duration
X-RateLimit-PolicyWhich ceiling it is: api:ip, api:burst, api:token, api:global or api:global-org

The ceiling reported is the one that leaves this request the least room, as a share of its limit. That is usually api:burst. A request refused before its key was read (a missing key, for instance) only went through api:ip, so api:ip is reported.

The 429 response

A refused request returns 429 with the standard error envelope:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded for api:burst. Retry in 1s.",
    "suggestion": "Reduce call frequency, or wait for the window to reset."
  }
}
HTTP/1.1 429 Too Many Requests
Retry-After: 1
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1791891001
X-RateLimit-Policy: api:burst
X-Request-Id: 6f1c2a9e-3b7d-4e05-8c4a-2d9f0b1e7a63

The X-RateLimit-* headers of a 429 describe the ceiling that refused it. Retry-After is the duration of that ceiling's window, in seconds: 1 for api:burst, 60 for the per-minute ceilings. The delay is never in the body.

Backing off correctly

  • Honor Retry-After. It is never shorter than the wait you need.
  • Pace yourself under 10 requests per second per integration. Parallel workers sharing one integration share one budget: give them a common pacer rather than letting each fire at will.
  • Watch X-RateLimit-Remaining and slow down before reaching zero.
  • Add exponential backoff with jitter to automated retries: a fleet retrying on a fixed timer recreates the spike that got it refused.
  • Read in pages of 100 (limit=100) rather than record by record, and follow changes with webhooks instead of polling.

Inbound webhooks

The inbound webhook endpoints (the /api/webhooks/in/... addresses Kasar gives you for a third-party system to post to) have two ceilings of their own, separate from the REST API:

PolicyLimitWindowCounted perChecked
webhook-in:pre-auth6001 minute, fixedWorkspace and sender IP addressFirst, before the token is looked up
webhook-in:hook1201 minute, slidingEndpointOnce the token is recognized
  • The pre-authentication ceiling is counted per sender IP address within a workspace: a sender that floods an endpoint, or tries tokens at random, exhausts its own budget and nobody else's.
  • The per-endpoint ceiling is a sliding window: no more than 120 calls are accepted in any 60 seconds.

A refused call returns 429 with Retry-After and the X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset and X-RateLimit-Policy headers of the ceiling that refused it. Its body is not the REST API envelope:

{ "error": "Too many requests", "policy": "webhook-in:hook", "retryAfterSeconds": 60 }

A call refused by the per-endpoint ceiling is logged in the endpoint's activity in Kasar. Senders such as HubSpot and Zapier honor Retry-After and resend later. On inbound endpoints, the rate-limit headers are sent with the 429 only.

On this page