Rate limits and best practices for e-signature APIs
A rate limit caps how many requests your account can make to an API within a given window of time, returning an error instead of processing requests once you're over it. For most integrations this never comes up in practice, since typical signature-sending volume is far below any reasonable limit — but it's worth understanding how it works before you build something that sends requests in a tight loop or a large batch.
Why rate limits exist at all
Rate limiting protects the platform's infrastructure from being overwhelmed, whether that's from a genuine traffic spike, a misconfigured integration accidentally calling an endpoint in a loop, or an attempted abuse pattern. It's a standard practice across essentially every API-first product, not something specific to e-signature platforms.
How Esignapi applies rate limiting
Esignapi applies rate limiting per account, tracked across a short time window, on its API endpoints — document upload, signature request creation, status checks, and document downloads. If you exceed the limit, the API returns an HTTP 429 status with a generic error message rather than processing the request. The limit is applied to the account as a whole, not per individual API key, so generating multiple keys for the same account doesn't multiply your effective limit.
What a 429 response means for your integration
A 429 doesn't mean something is broken — it means you've sent more requests than the current window allows, and the right response is to wait before retrying, not to immediately resend the same call. Treating a 429 the same way you'd treat a genuine server error (retry immediately, repeatedly) just produces more 429 responses.
Designing for rate limits proactively
- Avoid tight loops over the same endpoint. If you're creating many signature requests at once — say, sending the same onboarding document to fifty new hires — space the calls out rather than firing them all in immediate succession.
- Back off when you hit a 429, waiting before retrying rather than resending instantly. A short, increasing delay between attempts (a basic exponential backoff) is a reasonable default.
- Prefer webhooks over polling for status updates. Repeatedly polling a status endpoint to check if a request is complete uses up your request budget for something a webhook handles more efficiently and in real time. See E-signature webhooks explained.
- Batch logically where your workflow allows it. If you're sending to many signers for genuinely separate documents, there's no way around making separate calls, but if your use case allows grouping signers onto fewer, larger requests, that reduces the total call volume.
What typical usage actually looks like against the limit
For context, the overwhelming majority of integrations — a business sending a handful to a few dozen documents a day, even a mid-sized operation sending several hundred — operate well under any reasonable per-minute rate limit. Where this becomes relevant is specifically in batch operations (a one-time bulk send to hundreds of recipients at once) or a bug that causes an unintended retry loop, both of which are avoidable with the practices above.
Rate limits and multiple environments
If you're running requests from more than one environment or script against the same account (a production server and a staging environment sharing credentials, for instance), keep in mind they share the same account-level limit — a burst of testing traffic from staging can affect your production integration's available request budget if they're on the same account. Using genuinely separate accounts for testing versus production avoids this entirely.
How this interacts with webhooks
Webhooks don't count against your outbound request rate limit in the same way — they're the platform calling your server, not the other way around. This is one more reason webhooks tend to be a better design than frequent polling: they don't compete with your own API calls for the same rate budget.
Monitoring your own usage
If your integration sends a meaningful and growing volume of requests, it's worth tracking your own call volume on your side (even something as simple as a counter per time window in your logs) so you have visibility into how close you typically run to any limit, rather than discovering it for the first time when a batch operation starts returning 429s.
A simple backoff pattern worth implementing once
Rather than re-implementing retry logic separately for every call site in your integration, it's worth writing a single wrapper function that any API call goes through: attempt the request, and if the response is a 429, wait a short delay, then retry, doubling the delay on each subsequent attempt up to a small maximum number of tries. Centralizing this once means every endpoint your integration calls benefits from the same handling automatically, rather than needing the same logic copy-pasted (or, worse, forgotten) at each individual call site.
Distinguishing a rate limit from an outage
It's worth not conflating a 429 with a genuine service outage — a 429 specifically means your account is sending requests faster than the configured limit allows, which is something under your own control to fix by slowing down, while a 5xx error or a connection failure indicates something is actually wrong on the platform side, which calling less frequently won't fix on its own. Logging the specific status code for every failure, rather than lumping all non-2xx responses into one generic "API error" bucket, makes it much easier to tell these apart when reviewing what went wrong later.
Rate limits as a signal to improve your integration's design
Hitting the rate limit repeatedly in normal operation (not during a one-time bulk operation) is often a sign that your integration's call pattern could be more efficient — polling a status endpoint too frequently instead of using a webhook, for instance, or making several separate calls where one combined operation would do. Treating a persistent rate-limit problem as a design signal, rather than just adding more aggressive retry logic around it, tends to produce a more robust integration in the long run.
Build with rate limits in mind from the start
Esignapi's API documentation covers the specific endpoints rate limiting applies to, so you can design your integration's call patterns accordingly from the outset.
Frequently asked questions
What should my code do when it receives a 429?
Wait before retrying — a short delay that increases if you hit the limit again — rather than resending the request immediately, which will just be rejected again.
Does rate limiting apply per API key or per account?
Per account. If you have multiple API keys on the same account, they share the same rate limit rather than each getting an independent allowance.
Will normal, everyday usage ever hit the rate limit?
For the vast majority of integrations — regular document sending at typical business volumes — no. It's mainly a consideration for bulk operations or integration bugs that cause unintended request loops.
Do webhook deliveries count against my rate limit?
No, webhooks are initiated by the platform calling your server, not by you calling the API, so they don't consume your outbound request budget.
Can I request a higher rate limit for my account?
If your legitimate use case genuinely requires sustained higher volume than typical usage, that's worth raising directly with support rather than trying to work around the limit with aggressive retry logic.