Rate Limits

Which endpoints have rate limits today, and how to handle a 429 response.

Why we rate-limit

Rate limits protect:

  • Upstream providers from being overloaded — most SignCare APIs proxy to government or financial systems with their own limits.
  • Other clients from being starved of capacity.
  • You from runaway loops accidentally burning through your quota.

Which endpoints are limited

Most endpoints have no rate limit today. This includes eSign: creating a request, checking status, revoking, re-initiating, extending expiry and fetching the audit trail are not limited. Only the endpoints below are. Limits are counted per App ID (the X-API-APP-ID header) unless the table says otherwise.

EndpointLimitCounted per
POST /api/v1/StockHoldingEStamp/generate and POST /api/v1/StockHoldingEStamp/bulk-generate50 requests per secondApp ID
POST /api/v1/aadhaar-ovse/init, /qr-intent and /app-callback10 requests per secondApp ID
GET /api/v1/aadhaar-ovse/result/{txnId} and the event read endpoints30 requests per secondApp ID
POST /api/v1/aadhaar-ovse/events and PATCH /api/v1/aadhaar-ovse/events/{eventId}1 request per 5 minutesApp ID
POST /api/v1/aadhaar/secure-qr/read30 requests per minuteApp ID
POST /api/v1/esign/dsc-bulk-sign10 requests per minuteApp ID
POST /api/v1/esign/resendInvitation1 request per 5 minutesApp ID
POST /api/v1/dgft/iec-lookup, POST /api/v1/dgft/itchs-policy and POST /api/v1/GujRera/verify1 request per 5 minutesApp ID
POST /api/v1/template/render, POST /api/v1/template/design and GET /api/v1/template/design/{templateId}50 requests per minuteApp ID and client IP

Limits work like a token bucket: you can burst up to the limit, then requests are allowed again as the bucket refills evenly over the time window. Limits can change, so always handle a 429 (see below).

Need a higher limit for one of these endpoints? See Need higher limits? below.

What a 429 looks like

When you exceed a limit the API answers with HTTP 429 Too Many Requests and this body. It does not send a Retry-After header.

{
  "data": "",
  "message": "Too many requests. Please wait before retrying.",
  "statusCode": 429,
  "success": false
}

Handling 429 correctly

1. Wait for the limit window

There is no Retry-After header, so wait for the endpoint's window from the table above before retrying: about 1 second for the per-second limits, up to 1 minute for the per-minute limits and 5 minutes for the "1 request per 5 minutes" endpoints.

2. Use exponential backoff with jitter

Don't hammer the API with immediate retries. Use this pattern:

async function callWithBackoff(fn, maxAttempts = 5) {
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
    const res = await fn();
    if (res.status !== 429) return res;

    const backoff = Math.min(Math.pow(2, attempt) * 1000, 30_000);
    const jitter = Math.random() * 500;
    await new Promise((resolve) => setTimeout(resolve, backoff + jitter));
  }
  throw new Error('Max retry attempts exceeded');
}

3. Batch and queue on your side

If you're onboarding many users at once, queue the requests on your side and drain at a steady rate rather than bursting.

4. Monitor and alert

Track the frequency of 429s in your logs. A sudden spike usually means:

  • A runaway loop
  • Load beyond your contracted rate
  • An upstream provider in degraded state

Need higher limits?

Contact support@signcare.io with:

  • Your API Key (never your secret — just the ID prefix is enough)
  • Expected requests per minute / per day
  • Which endpoint(s)
  • Business justification (volume, campaign, seasonality)

We can often increase limits within hours for contracted customers.

Fair-use limits on free accounts

Free / evaluation accounts are restricted to Stage only and share a global soft limit. Contact us for a paid account to unlock production capacity.