Working with the API
Artifacts & exports
Everything a job produces is an artifact you can download. Each mesh format is one artifact holding every piece, and you can ask for any other format as an export.
Artifacts#
/v1/jobs/{job_id}/artifactsartifacts:readAn artifact is {id, job_id, label, size_bytes, sha256, media_type}. The list is empty until the job has succeeded and all of its outputs passed verification. The label says what the artifact is:
| Recipe | Labels |
|---|---|
inspect | analysis (JSON), preview (GLB), thumbnail_0 … thumbnail_7 (JPG) |
repair | result_glb, result_obj_zip (OBJ + MTL + textures), measurements, analysis, analysis_before; when produced texture, result_3mf and result_parts_zip (a STEP assembly's parts, one OBJ each) |
tool | result (the tool's JSON) always; mesh tools add one artifact per format they wrote: result_glb, result_obj_zip, result_3mf for one piece, or result_glb_zip, result_obj_zip, result_3mf_zip with a piece_NN/ folder per piece; convert adds converted (or converted_zip for several pieces or OBJ); analysis tools add heatmap, result_obj, result_parts_obj_zip or analysis_raw |
A multi-piece result (a cut with both sides kept, a mirror without merging) carries at most 50 pieces; the tool's result reports pieces and pieces_dropped.
Downloading#
/v1/artifacts/{artifact_id}/downloadartifacts:readThe answer is a temporary presigned GET: {url, method, headers, expires_at}. Fetch it without your API key, keep it private, and ask for a new one when it has expired. Check what you downloaded against the artifact's size_bytes and sha256; write to a temporary name and move it into place once it matches.
for row in $(curl -sS "$API/v1/jobs/$JOB_ID/artifacts" -H "Authorization: Bearer $PRINTY3D_API_KEY" \
| jq -r '.data[] | "\(.id),\(.label),\(.sha256)"'); do
IFS=, read -r ID LABEL SHA <<< "$row"
URL=$(curl -sS "$API/v1/artifacts/$ID/download" -H "Authorization: Bearer $PRINTY3D_API_KEY" | jq -r .url)
curl -sS -o "$LABEL.part" "$URL"
echo "$SHA $LABEL.part" | sha256sum -c - && mv "$LABEL.part" "$LABEL"
doneOutputs are kept for your plan's retention (30 days today); after that a download answers 410 expired.
Exports#
/v1/jobs/{job_id}/exportsjobs:write/v1/jobs/{job_id}/exports/{format}artifacts:readAn export is a succeeded repair or tool job's mesh output in one format, glb, obj, 3mf, stl or ply, with every piece in it. Ask with {"format": "stl"}:
200, statusready: the job already produced that format;artifactis the artifact to download.202, statusconverting: Printy3D started one conversion job (conversion_job_id) on the GPU fleet from the job's best output. PollGET …/exports/{format}(the answer carriesRetry-After) until it isready. Asking again while it converts returns the same conversion.- status
failed:error_codesays why; asking again starts a new conversion.
curl -sS -X POST "$API/v1/jobs/$JOB_ID/exports" \
-H "Authorization: Bearer $PRINTY3D_API_KEY" -H "Content-Type: application/json" \
-d '{"format": "3mf"}' | jq '{status, conversion_job_id, artifact}'
# while converting:
curl -sS "$API/v1/jobs/$JOB_ID/exports/3mf" -H "Authorization: Bearer $PRINTY3D_API_KEY" | jq .statusGET …/exports/{format} answers 404 for a format you never asked for. Only a succeeded repair or tool job can be exported; any other job, or a tool job without a mesh output, answers 409 conflict.