Credits & Rate Limits
Two account limits can affect your API integration: your credit balance and your plan’s API rate limits. This page shows how to handle both. (For how credit costs are calculated, see How Credits Work.)
Insufficient credits (HTTP 402)
Section titled “Insufficient credits (HTTP 402)”A live document is admitted only when your available balance covers its
smallest possible charge: one unit of it (20 credits for a filled PDF form, 4
for a PDF from an HTML template or a combined PDF), plus 60 credits for each
data request that asks for a signature, or 4 for each source PDF of a combined
PDF. When your balance can’t cover that, or storage credits have been due for
more than seven days, requests that would generate a live document return
402 Payment Required:
{ "status": "error", "error": "Insufficient credits. This submission will be processed automatically once you add credits in Billing. If it's still waiting after 30 days, it won't be processed.", "code": "insufficient_credits", "submission": { "id": "sub_000000000000000001", "state": "insufficient_credits", "...": "..." }}Key points for your integration:
- The submission is saved. It’s held in the
insufficient_creditsstate and automatically resumes once enough credits are available, so you don’t need to resubmit. If support has turned off automatic resumption for your account, theerrorsays so: add credits and send a new request; the saved request won’t resume. - If storage credits are overdue, the
errorsays so (“Live processing is paused because 20 storage credits are due. Add credits in Billing to resume. Your stored PDFs remain available.”) and the submission waits the same way. Adding credits pays the storage charge first, then resumes waiting work. - No webhook is sent when a submission starts waiting for credits. If you rely on webhooks, poll submissions that haven’t finished, or watch for the alert on the Billing page.
- Waiting submissions are not kept forever. A submission or combined
submission that is still waiting for credits 30 days after it first ran out
of credits moves to the
errorstate (“Not processed: this request waited 30 days for credits.”), and DocSpring sends thesubmission.failed(orcombined_submission.failed) webhook with the reason inerror_message. You can also discard waiting work yourself, all at once from the Billing page or one at a time from the submission’s page. Through the API, expire a waiting submission or combined submission to discard it. Discarded submissions move toerrorthe same way. - Batch endpoints return
402when any submission in the batch is blocked; each blocked submission is reported in the response with its error message. Other submissions in the same batch may already be processed and charged, so check each submission’sstateand don’t resubmit the whole batch. The blocked submissions resume automatically. - A batch stays
pendingwhile any of its submissions are waiting for credits (they are counted inpending_count), so a client polling the batch keeps waiting until those submissions resume. Check the submissions’stateto see which ones are blocked. - Combined PDF requests behave the same way:
the combined submission is created in the
insufficient_creditsstate and resumes automatically after you add credits. Combined jobs have no test mode and consume credits even with a test API token or watermarked source PDFs. - A submission can also enter
insufficient_creditsafter being accepted, if the balance runs out while it’s in the queue. If you poll for results, handle this state alongsideprocessedanderror. - Synchronous requests return
402if processing encounters insufficient credits before the response is returned. Preserve the response body and saved submission ID even when your HTTP client raises for a non-2xx response. - The
402on creation is a best-effort check against the balance at that moment; it does not reserve credits. A batch, or several requests sent close together, can all be accepted and some may still enterinsufficient_creditsonce the earlier ones consume the balance. Always check each submission’sstaterather than relying on the creation status alone. - Data requests can be created without credits. Credit admission happens when the signers finish and the live PDF is ready to render. The final charge includes the PDF’s own cost plus 60 credits for each data request that asks its signer to sign or initial. Data requests that only collect values add nothing to the PDF’s cost.
- Test submissions never consume credits and are not blocked by a low credit balance. They remain subject to API request limits.
To avoid hitting 402 in production, enable
automatic top-ups.
Plan features (HTTP 403)
Section titled “Plan features (HTTP 403)”Some features depend on your plan: the number of templates and users, live data
requests and e-signatures, and the embedded template editor (see
Plans). A request that needs a higher plan returns
403 Forbidden before anything is created:
{ "status": "error", "error": "Your Developer plan includes 10 templates. Upgrade to Starter or higher to add more.", "code": "upgrade_required"}Unlike 402, nothing is queued: upgrade the plan, then send the request again.
Only accounts on a plan purchased before prepaid credits can be suspended. A
suspended account gets the same 403 with "code": "account_suspended" when it
tries to create submissions, batches or combined PDFs. Nothing is stored, and
reading existing submissions still works. Reactivating it from the Billing
page moves it to the free Developer plan (the earlier plan can’t be restored);
subscribe to a paid plan there for more credits and higher limits.
Rate limits (HTTP 429)
Section titled “Rate limits (HTTP 429)”API limits are shared across all API keys and IP addresses on the account. Live and test API tokens have separate limits. The mode comes from the token: a live token still uses the live limit when it requests a watermarked test PDF.
Signed-in web app requests normally share the live limit. Template and submission reads, including the editor’s status polling, and the template editor’s autosaves use a separate, larger per-account allowance (300 requests burst, refilling at 600 per minute) so editing and viewing progress do not use your integration’s limit. The exception requires a signed-in browser session; API-key requests to those endpoints still count. Creating PDFs in the web app continues to use the account’s live limit.
A synchronous request (wait=true) counts once. The status polling DocSpring
performs on your behalf while it waits for the PDF is not counted against your limit.
| Plan | Live requests | Test requests |
|---|---|---|
| Developer | 10/min (burst 20) | 5/min (burst 15) |
| Starter | 60/min (burst 120) | 5/min (burst 15) |
| Growth | 120/min (burst 240) | 5/min (burst 15) |
| Scale | 300/min (burst 600) | 5/min (burst 15) |
Each limit refills continuously at the listed rate, up to its burst capacity. For example, Developer can send 20 live requests at once after an idle period; after exhausting that burst, capacity returns at one request every six seconds. Creating another API key or changing IP addresses does not reset the limit.
Every response to a rate-limited API request includes the limit’s current state, so you can slow down before you reach the limit:
| Header | Meaning |
|---|---|
RateLimit-Limit | The limit’s burst capacity |
RateLimit-Remaining | Requests you can send right now |
RateLimit-Reset | Seconds until the limit has refilled to full capacity |
Requests over the limit receive 429 Too Many Requests with a Retry-After
header containing the minimum delay in seconds. These requests have not reached
the API action and are safe to retry. Wait at least that long and use exponential
backoff with jitter if retries are also limited. Spread large workloads with
the batch endpoint,
which counts as a single request.
These limits count API requests, not PDFs within a batch or simultaneous PDF renders. Credit availability is checked separately for each live document.
If you need a higher rate limit than your plan provides, contact [email protected].