X3DStudios

Analyse printability

POST a mesh to /api/printability and get back geometry: watertightness, holes, non-manifold edges, size, and a ready, warning or error verdict. Free, no key.

POST a mesh file and get the geometry back: is it closed, how many holes, how many branching edges, how big, how much material. It ends with one verdict — ready, warning or error. No account, no key, no credits, and no mesh is returned or stored.

POST/api/printabilityNo auth

Analyse an uploaded STL, GLB or OBJ. multipart/form-data, one field.

Request#

multipart/form-data
modelfilerequired
The mesh. STL (binary or ASCII), GLB, GLTF, or OBJ. Format is detected from the glTF magic bytes first, then the file extension, then by sniffing the contents — so an extensionless upload still works. There are no other fields.
Anonymous check
curl https://x3dstudios.com/api/printability \
  -F [email protected]
LimitAnonymousSigned in
Checks per hour12, keyed on your IP60, keyed on your account
File size25 MB50 MB
Triangles1,500,0001,500,000
The triangle ceiling is checked from the file size before parsing — exactly for a binary STL, estimated elsewhere — so a huge upload is refused rather than parsed.
3MF and G-code are not read here
This check reads STL, GLB/GLTF and OBJ only. The /print uploader accepts a wider set — STL, GLB, 3MF and G-code — and OBJ is not among them. See /docs/file-formats.

Response#

200
{
  "ok": true,
  "filename": "bracket.stl",
  "sizeBytes": 2418084,
  "report": {
    "format": "stl",
    "unitsAssumed": false,
    "triangleCount": 48360,
    "vertexCount": 24182,
    "boundingBoxMm": [82.4, 60.1, 12.6],
    "volumeCm3": 21.44,
    "surfaceAreaCm2": 187.3,
    "watertight": true,
    "boundaryEdges": 0,
    "holes": 0,
    "largestHoleMm": 0,
    "nonManifoldEdges": 0,
    "degenerateFaces": 0,
    "consistentWinding": true,
    "smallestExtentMm": 12.6,
    "issues": [],
    "verdict": "ready"
  }
}
FieldWhat it is
formatglb, stl or obj — what the file was read as, which may not match its extension.
unitsAssumedtrue for GLB and OBJ, false for STL. glTF and OBJ carry no unit declaration; we treat glTF as metres and OBJ as millimetres. Getting this wrong is a factor of 1000, so it is stated rather than hidden.
triangleCountTriangles after the file is read.
vertexCountDistinct vertices after welding — the number topology is measured on, not the count in the file.
boundingBoxMm[x, y, z] in millimetres.
volumeCm3Signed-tetrahedron sum, absolute. Meaningful only when the surface is closed.
surfaceAreaCm2Total triangle area.
watertightboundaryEdges is 0 and there is at least one triangle.
boundaryEdgesEdges used by exactly one face.
holesThose edges walked into rings — a count of actual holes.
largestHoleMmThe widest hole rim, corner to corner. The most legible number in the report.
nonManifoldEdgesEdges shared by three or more faces: branching surfaces.
degenerateFacesZero-area triangles — a repeated index, or area at or below 1e-9.
consistentWindingfalse when the same directed edge appears twice, meaning some faces point inwards.
smallestExtentMmSmallest overall dimension. Not a wall-thickness measurement.
issuesZero or more { id, severity, title, detail } objects. See below.
verdictready, warning or error.

The verdict#

verdictRuleWhat to do
readyNo issues at all.Nothing. Order it.
warningOne or more issues, none of them an error.Read them. Most are things we fix automatically at print time — you can order anyway.
errorAt least one issue with severity error. Only one issue is ever an error: not-watertight.The surface has holes. A slicer cannot tell inside from outside through one. We repair this on print, but the result is a guess about what you meant.

Every issue it can raise#

idseverityRaised when
not-watertighterrorThere is at least one open boundary edge, or the file contains no triangles.
non-manifoldwarningOne or more edges are shared by three or more faces.
degeneratewarningOne or more triangles have no area.
inconsistent-windingwarningSome faces are wound the wrong way round and point inwards.
thinwarningThe smallest dimension is above zero and under 1 mm.
too-largewarningThe longest side is over 340 mm — past the build volume.
tinywarningThe longest side is under 5 mm. On a GLB or OBJ this usually means the file's units are not what we assumed.
title and detail are written for a human to read; id is the value to branch on.
An issue, as returned
{
  "id": "not-watertight",
  "severity": "error",
  "title": "3 holes in the surface",
  "detail": "The widest gap measures about 14.2mm across. A slicer cannot tell inside from outside through a hole, so this either fails to slice or prints hollow where it should be solid. We repair this automatically on print."
}
Overhangs and supports are not part of this check
It measures topology and size, nothing about orientation or overhang angle. Supports are decided by the slicer at print time and applied automatically. A ready verdict says the file is sound, not that the shape will print unsupported.

Errors#

StatusMessage
429You've hit the hourly limit for free checks. Try again later, or sign in for more. — with a Retry-After header.
400Attach a model file as `model`.
400That file is empty.
413That file is 31MB. The limit is 25MB — signing in raises it. (Signed in, the same message names the 50MB limit and drops the tail.)
413That mesh has roughly 4,182,000 triangles, past the 1,500,000 this check handles. Decimate it and try again.
415That does not look like an STL, GLB or OBJ. Those are the formats this check reads.
422No triangles found in that file.
422Could not read that file. It may be corrupt or use a feature this check does not support.
Every failure is a flat { "error": "…" }. Only the 200 carries ok, filename, sizeBytes and report.