Reference
Errors
Every error is one JSON problem document (RFC 9457) with a stable code. Branch on the code; show the detail to people.
The problem document#
Errors answer with a 4xx or 5xx status and application/problem+json:
{
"type": "https://docs.printy3d.com/errors/insufficient_credits",
"title": "insufficient credits",
"status": 402,
"code": "insufficient_credits",
"detail": "This job needs 1800 credits held while it runs; 312 are available.",
"instance": "/v1/jobs",
"request_id": "01JB7Q4V6Y8M2N3P4R5S6T7V8W",
"errors": [],
"required": 1800,
"available": 312
}codeis stable: use it in your code.titleanddetailare for people and may change.errorslists field-level failures ({field, message}) forvalidation_failed.- Some codes add fields beside the standard ones, such as
requiredandavailableabove orreasononcapacity_exhausted. request_idmatches theX-Request-Idresponse header. You may send your ownX-Request-Id(8–64 letters, digits,_or-); quote it when you contact support.
Error codes#
| Status | code | Meaning |
|---|---|---|
| 400 | malformed_request | The body is not valid JSON or the request cannot be parsed. |
| 401 | unauthenticated | No API key, or the Authorization header is malformed. |
| 401 | invalid_api_key | The key is unknown, revoked or expired. |
| 402 | insufficient_credits | A live job's hold exceeds your available credits. Extras: required, available. |
| 403 | insufficient_scope | The key lacks the scope this endpoint needs. |
| 403 | org_required | The credential is not tied to an account. |
| 403 | origin_not_allowed | A browser request from an origin that is not allowed. Call the API from your server. |
| 403 | ip_not_allowed | The request comes from an IP address the key's allow-list does not include. |
| 403 | account_pending | Live work for an account the Printy3D team has not approved yet: "This account is waiting for approval by the Printy3D team; live jobs start once it is approved. Test keys run simulated jobs meanwhile." |
| 404 | not_found | No such object in your account and mode. Objects of other accounts are always 404. |
| 405 | method_not_allowed | The path exists but not with this method. |
| 409 | conflict | The request conflicts with the current state: a file that is not ready, an upload with parts missing, a key already rotated, 25 active keys, a 21st webhook endpoint of one mode, an evaluation of a job that is not a succeeded Exact Check or whose measurements have expired. |
| 409 | job_not_cancellable | The job has already succeeded or failed. |
| 409 | idempotency_in_progress | Reserved, not returned today: two requests with the same Idempotency-Key at the same time are taken in turn, and the second waits for the first, then replays it. |
| 410 | expired | The file or output is past its retention period and was deleted. |
| 413 | file_too_large | The upload is larger than its upload lane or your plan allows. |
| 415 | unsupported_format | The bytes are not a format Printy3D accepts. |
| 422 | validation_failed | A field is missing, unknown or out of range; errors lists each one. |
| 422 | idempotency_key_reused | The same Idempotency-Key was sent with a different body. |
| 422 | input_too_large | The input exceeds a size limit of the job, such as a splat count. |
| 429 | rate_limited | Too many requests for this key. Always with Retry-After. |
| 429 | concurrency_limit | Too many active jobs for your plan. Always with Retry-After. |
| 429 | quota_exceeded | A plan quota is used up, such as input storage. Always with Retry-After. |
| 500 | internal | An error on our side. Quote the request_id when you report it. |
| 501 | feature_unavailable | Not available to this account or key: the resumable upload before approval, a format or tool not enabled, an export conversion with a test key, a live Exact Check where it is not set up. |
| 503 | service_unavailable | A dependency is briefly unavailable. Always with Retry-After. |
| 503 | capacity_exhausted | No GPU can start a live job now, or no Exact Check worker is running for a live cad_check; nothing was queued or held. reason: paused, spend_limit, no_gpu_available, controller_offline or cad_unavailable. Always with Retry-After. |
The spec's ErrorCode also lists bootstrap_invalid, image_not_allowed, lease_expired, lease_terminal, contracts_mismatch: they belong to the internal worker plane and are never returned to an API key.
Handling errors#
| Status | What to do |
|---|---|
| 400, 404, 405, 413, 415, 422 | Fix the request; retrying it unchanged fails again. |
| 401, 403 | Check the key, its mode and its scopes; for account_pending, use a test key (simulated jobs) until your account is approved. |
| 501 | The feature is not open to this key or account: for an export conversion, use a live key; for a resumable upload, wait for approval. |
| 402 | Wait for running jobs to release their holds, or add credits. |
| 409 | Read the detail: wait for the file to be ready, finish the upload, or retry an in-progress idempotent request. |
| 429, 503 | Wait for Retry-After, then retry with the same Idempotency-Key. |
| 500, 502, 504 | Retry idempotent requests with backoff; report the request_id if it persists. |