Skip to content
Get API key

Concepts

Rate limits

Each key has its own budget per minute. Over it, the API answers 429 and tells you how long to wait.

Limits per key

CredentialLimit
sf_test_ API key60 requests a minute
sf_live_ API key300 requests a minute
MCP token60 tool calls a minute; a write tool counts as two

Limits are per key, not per business: two integrations with their own keys don't eat each other's budget.

When you hit the limit

The API answers 429 with error.code rate_limited and a Retry-After header in seconds. Wait that long, then retry.

429 response
HTTP/1.1 429 Too Many Requests
Retry-After: 23
Content-Type: application/json

{ "error": { "code": "rate_limited", "message": "Rate limit exceeded (300/min).", "request_id": "…" } }
Honour Retry-After
async function call(url, init = {}, tries = 5) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(url, init);
    if (res.status !== 429) return res;
    const wait = Number(res.headers.get("Retry-After") ?? 1);
    await new Promise((r) => setTimeout(r, wait * 1000));
  }
  throw new Error("still rate limited");
}

What counts

  • A request counts once it passes the key, scope, outlet and plan checks, whatever it answers next (a 404 or 409 included).
  • Requests refused before that (a bad key, a missing scope, a plan without the API, or a query or body that does not parse) do not count.
  • The menu supports ETag / If-None-Match. A 304 still counts as a request but carries no body, so polling it is cheap.

To stay well under the limit, page with limit=100 and use webhooks instead of polling for changes.

Stuck? Quote the request_id from the response and write toSansflow support.Checked against API v1 on .