Answer: Rate limits are per plan, per minute: Free 10, Starter 60, Growth 300, Pro 600, Scale 1,200 requests/minute. Every /api/v1 response carries X-RateLimit-Limit and X-RateLimit-Remaining; a 429 adds X-RateLimit-Reset and Retry-After in seconds. Concurrent-job caps apply separately: 2/3/10/25/50.
How buckets work
API-key requests are bucketed per key at your plan's limit. Dashboard (session-cookie) tool runs are bucketed per user at the same limit — there is no unmetered path. Team workspaces share the owner's bucket and plan limit across all members.
Reading the headers
Watch X-RateLimit-Remaining as you approach the limit; when you hit 429, sleep for the Retry-After value (seconds until the window resets) rather than a fixed constant.
HTTP/2 429
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 41
Retry-After: 41
{ "success": false, "error": { "code": "rate_limited", "message": "Rate limit exceeded" } }Concurrent jobs
Independently of requests/minute, each plan caps how many jobs may be processing at once — Free 2, Starter 3, Growth 10, Pro 25, Scale 50. The cap is checked before credits are reserved; exceeding it returns 429 concurrency_limit_reached. Batch submissions are internally clamped to the same cap.
Do zero-credit tools count?
Yes. The four always-free tools (rotate, extract-pages, remove-pages, metadata) consume no credits but still count against your requests/minute and concurrency — the limiter buckets requests, not credits.
Idempotency keys — safe retries
Send an Idempotency-Key header on any /api/v1/* POST and the response is cached for 24 hours, scoped to your API key. A network-level retry with the same key returns the cached response instead of running (and billing) the job again.
curl -X POST https://www.ashdocs.com/api/v1/tools/html-to-pdf \
-H "X-API-Key: ash_live_xxxxxxxx" \
-H "Idempotency-Key: order-8841-invoice" \
-H "Content-Type: application/json" \
-d '{ "html": "<h1>Invoice 8841</h1>" }'Recommended backoff
On 429: wait Retry-After seconds, then resume. For bursty pipelines, an exponential backoff with jitter (1s, 2s, 4s… capped at 30s) plus an Idempotency-Key on every POST makes retries both polite and safe.
Frequently asked questions
Are rate limits per key or per account?
Per key for API traffic (each key gets its own bucket at the plan limit) and per user for dashboard sessions. Workspace members share the owner's buckets.
Do failed requests count toward the limit?
Yes — the limiter counts requests, successful or not. 4xx responses still consume a slot in the window.