Independence Day offer · ₹52/employee/moClaim offer
INDPayroll
Payroll Engine API

Rate limits

Limits are per key, per environment. Reads and writes share one pool; payroll calculation has its own, because a run does far more work than a lookup.

PoolDefault limitCovers
General600 requests / minuteEverything except the calculation endpoints.
Payroll60 runs / hour/payroll-runs/preview, /calculate and /recalculate.
Bulk10 requests / minute/employees/bulk, /attendance/bulk and /imports.

GET /me returns the limits in force for your key. Partners running payroll for many client companies at month end are usually raised on request - tell us the shape of the load.

Headers

HeaderMeaning
X-RateLimit-LimitRequests allowed in the current window.
X-RateLimit-RemainingRequests left in it.
X-RateLimit-ResetUnix seconds at which the window resets.
Retry-AfterOn a 429 only: seconds to wait.

Backing off

javascript
async function call(request, attempt = 0) {
  const res = await fetch(request);
  if (res.status !== 429 && res.status < 500) return res;
  if (attempt >= 5) throw new Error('gave up after ' + attempt + ' retries');

  const retryAfter = Number(res.headers.get('Retry-After'));
  const backoff = Number.isFinite(retryAfter) && retryAfter > 0
    ? retryAfter * 1000
    : 2 ** attempt * 500 + Math.random() * 250;

  await new Promise((r) => setTimeout(r, backoff));
  return call(request, attempt + 1);
}
Month end is the spikeSpread bulk pushes across the days before the cut-off rather than the morning of the run, and use updated_since to sync only what changed.