Printy3D

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#

An 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:

RecipeLabels
inspectanalysis (JSON), preview (GLB), thumbnail_0 … thumbnail_7 (JPG)
repairresult_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)
toolresult (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#

The 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"
done

Outputs are kept for your plan's retention (30 days today); after that a download answers 410 expired.

Exports#

An 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, status ready: the job already produced that format; artifact is the artifact to download.
  • 202, status converting: Printy3D started one conversion job (conversion_job_id) on the GPU fleet from the job's best output. Poll GET …/exports/{format} (the answer carries Retry-After) until it is ready. Asking again while it converts returns the same conversion.
  • status failed: error_code says 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 .status

GET …/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.