Reference
Rate limits & limits
What the API refuses with 429 and 503, and the fixed limits worth designing around.
Rate and concurrency#
| code | Status | What is limited |
|---|---|---|
rate_limited | 429 | Requests per key, set by your plan. |
concurrency_limit | 429 | Active jobs (queued, running or verifying) per account, set by your plan. |
quota_exceeded | 429 | A plan quota, such as your input storage. |
service_unavailable | 503 | A dependency is briefly down; job and file creation fail closed rather than run unmetered. |
capacity_exhausted | 503 | No GPU can start a live job now, or no Exact Check worker is running for a live check. |
Every one of these answers carries Retry-After (seconds). Wait at least that long, then retry; keep the same Idempotency-Key on a create so the retry cannot duplicate it. POST /v1/jobs checks concurrency first, then capacity for live jobs (a GPU, or for an Exact Check a running Exact Check worker), then credits (402).
Poll jobs every two seconds or so rather than in a tight loop, and list jobs with GET /v1/jobs instead of polling each one when you track many.
Request rate#
Each API key has a bucket of requests. A request takes one, the bucket refills at the plan's rate, and it holds at most the burst. When it is empty the API answers 429 rate_limited, and Retry-After says when a request is free again. The official SDKs wait and retry for you.
| Plan | Requests per second | Burst |
|---|---|---|
| Free (and pending approval) | 2 | 10 |
| Developer | 10 | 50 |
| Team | 25 | 100 |
Responses carry the state of the bucket, so a client can slow down before it is refused:
| Header | Meaning |
|---|---|
RateLimit-Limit | The burst: how many requests the bucket holds. |
RateLimit-Remaining | How many it holds now. |
RateLimit-Reset | Seconds until it is full again. |
A request without a valid key (missing, malformed or unknown) counts against its address instead, at 5 per second with a burst of 20. Long-lived requests such as GET /v1/jobs/{id}/events count once, when they start.
Fixed limits#
| What | Limit |
|---|---|
| Simple upload | 10 MiB per file |
| Resumable upload | Approved accounts: your plan's per-file limit (200 MB on free, 2 GB on developer and team), never above 1 GiB |
| Accounts not yet approved | 10 MiB per file, 100 MiB of inputs in total; no resumable upload |
| Upload URL lifetime | 15 minutes (simple), 1 hour per part URL (resumable; replay to renew) |
| Starting a resumable upload | Three times per file (resuming does not count) |
| Idempotency-Key retention | 24 hours |
| File names | 5–200 characters, no path separators or control characters |
| Retention of files and outputs | 30 days, then 410 expired |
| Attempt time limit | inspect 3600 s, repair 7200 s, tool 1800 s, Exact Check 290 s for the checker (less with max_credits), stopped at 300 s |
| Exact Check ZIP | At most 2,000 entries and 850 MiB unpacked, ratio at most 200:1 |
| Attempts per job | Up to 3 (a lost worker is retried, never charged) |
| Queue | A queued live job fails free after 10 minutes without GPU capacity (an Exact Check: without an Exact Check worker) or 24 hours in the queue |
| Pieces in one mesh artifact | 50 |
| Cut planes per job | 8 |
| Lattice model size | Longest side at most 635 mm |
| Active API keys | 25 per account |
| Key rotation grace | 0 to 7 days (default 24 h) |
| List page size | 1–100, default 20 |
| Minimum charge of a live job | 10 credits |
Plan values (rates, concurrent jobs, storage, included credits) are set per plan; ask the Printy3D team about yours. See also Uploads and Credits & billing.