Analyze Printability API
Check a 3D model for printing problems by measuring its watertightness, volume, holes, non-manifold edges, and degenerate faces. You can also check wall thickness at the size you plan to print.
Create an Analyze Printability task
Creates an Analyze Printability task, which evaluates a 3D model and reports its printability metrics. The task runs in the background. For how long a task usually takes, see Processing times.
When Meshy already has the printability result for the input_task_id task, the new task is ready right away. Your first GET on it returns the result.
Request
# Analyze an existing task
curl https://api.meshy.ai/openapi/v1/print/analyze \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578"
}'
# Or analyze a model URL directly
curl https://api.meshy.ai/openapi/v1/print/analyze \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"model_url": "https://example.com/model.glb"
}'
# Also check wall thickness for a 100 mm tall SLA print
curl https://api.meshy.ai/openapi/v1/print/analyze \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578",
"printer_type": "sla",
"intended_print_height_mm": 100
}'
Response
{
"result": "0193bfc5-ee4f-73f8-8525-44b398884ce9"
}
Parameters
- Name
- input_task_id
- Type
- string
- Required
- Description
Required unless you send
model_url. The ID of the task whose model you want to analyze. The task must have the statusSUCCEEDED, and be one of yours or in a workspace you belong to.It can be one of these task types, using Meshy 6 or newer, including Meshy 7:
A Repair Printability task also works.
- Name
- model_url
- Type
- string
- Required
- Description
Required unless you send
input_task_id. The model to analyze, as a public URL or a data URI. If you send both, Meshy usesinput_task_id.From an
httporhttpsURL, the model must be a.glb,.gltf,.obj,.fbx, or.stlfile of at most 400 MB. A data URI can hold only a base64 GLB (data:model/gltf-binary;base64,...) or glTF (data:model/gltf+json;base64,...) file of at most 100 MB. Send an.obj,.fbx, or.stlfile as anhttporhttpsURL.A file over 100 MB must also follow these rules:
- A GLB, glTF, FBX, or OBJ file can have at most 10,000,000 faces. Meshy counts faces as triangles, so a quad counts as 2, and a mesh drawn more than once counts once per copy.
- An FBX file must be binary FBX 7.1 or newer.
- A GLB or glTF file must not use Draco compression.
A Meshy download URL (
assets.meshy.ai/…?Expires=…&Signature=…) is signed and stops working at its task'sexpires_at. Reading the task again doesn't renew it. For a model you made with Meshy, sendinput_task_idinstead, which works while Meshy keeps the source task (see Asset retention). To use the model after that, download it beforeexpires_atand send your own copy.
To also check wall thickness at the size you plan to print, send printer_type, a print size, or both. The result is in printability.thin_walls. Checking wall thickness takes longer, so the task usually isn't ready right away, even if Meshy analyzed the model before.
- Name
- printer_type
- Type
- string
- Description
The printer you plan to use. It sets the minimum wall thickness for the wall-thickness check. If you send a print size without
printer_type, Meshy usesfdm.Available values:
fdm: filament, 1.0 mm minimum wallsla: resin, 0.8 mm minimum wallfull_color: full-color, 2.0 mm minimum wall
Any other value returns
400.
- Name
- intended_print_height_mm
- Type
- number
- Description
The height of the print, in millimeters, from
1to1000. A value outside the range returns400. Send this orintended_print_longest_side_mm, not both.It works only with GLB input. For a
model_urlthat isn't a.glbfile, sendintended_print_longest_side_mminstead.
- Name
- intended_print_longest_side_mm
- Type
- number
- Description
The length of the print's longest side, in millimeters, from
1to1000. A value outside the range returns400. It works with every input format.
If you send printer_type without a size, Meshy uses this print size:
.glbfile or anyinput_task_id: 150 mm tall.stlfile: the file's own longest side, read as millimeters.obj,.fbx, or.gltffile: 150 mm on the longest side
For an STL file in other units, send intended_print_longest_side_mm.
Meshy rounds both print sizes to the nearest millimeter.
Returns
The result field of the response holds the ID of the new Analyze Printability task.
Failure modes
- Name
400 - Bad Request- Description
The request can't run. The error message says which problem it found. For example:
- Missing parameter: Neither
input_task_idnormodel_urlwas sent. - Invalid UUID:
input_task_idisn't a valid UUID. - Invalid model URL:
model_urlis malformed, uses an unsupported scheme, or has an unsupported file extension. - Model file too large: The
model_urlfile is over 400 MB from anhttporhttpsURL, or over 100 MB as a data URI. - Too many faces: The
model_urlfile is a GLB, glTF, FBX, or OBJ file over 100 MB with more than 10,000,000 faces. Reduce the face count, then send the file again. - ASCII FBX over 100 MB: The
model_urlfile is an ASCII FBX over 100 MB. Send it as binary FBX or GLB. - Unreadable model file: The
model_urlfile is over 100 MB, and Meshy can't read its header. For example, it's a Draco-compressed GLB or glTF, or a binary FBX older than 7.1. - Model header too complex: The
model_urlfile is over 100 MB, and its header has too many meshes, nodes, or records to check. Reduce the number of objects in the file, then send it again. - Model file can't be downloaded:
model_urlreturned an error, most often because a signed Meshy download URL expired. Reading the task again returns the same URL with the same expiry. Send your own copy of the file, or sendinput_task_idwhile Meshy keeps the source task. - Task not succeeded: The
input_task_idtask is still pending, in progress, or failed. - Invalid print size:
intended_print_height_mmorintended_print_longest_side_mmis outside1to1000, or the request has both. - Unknown printer type:
printer_typeisn'tfdm,sla, orfull_color. - Height on a non-GLB model: The request has
intended_print_height_mmand amodel_urlthat isn't a.glbfile. Sendintended_print_longest_side_mminstead. - Can't size this model by height: At the requested height, or the default 150 mm, the model's longest side would be outside 1 to 1,000 mm. It also happens when the model is flat, or when Meshy can't determine its size. Send
intended_print_longest_side_mminstead. For a.glbmodel_urland someinput_task_idtasks, Meshy finds this only after the task starts, and the task ends asFAILEDinstead. - STL size unusable: The request has
printer_typewithout a size, and Meshy can't read the.stlfile's own longest side, or it's outside 1 to 1,000 mm. Sendintended_print_longest_side_mm.
Fix the request, then send it again. See Errors.
- Missing parameter: Neither
- Name
401 - Unauthorized- Description
The API key is missing or invalid. Check the
Authorizationheader.
- Name
403 - Forbidden- Description
input_task_idis a bas-relief model, which this endpoint can't analyze. The message isThis model type does not support this operation. Send a different model.
- Name
404 - Not Found- Description
Meshy can't find a model to analyze for
input_task_id. For example:- The task doesn't exist, was deleted, or isn't yours or in a workspace you belong to.
- The task uses a model older than Meshy 6, or its type doesn't produce a 3D model.
- The task's model file is no longer in storage.
Check that
input_task_idis a supported task that's yours or in one of your workspaces, or send the model asmodel_url.
- Name
429 - Too Many Requests- Description
You exceeded your rate limit, or you have too many pending tasks. Wait, then retry. See Rate limits.
Get an Analyze Printability task
Returns an Analyze Printability task by its ID.
Request
curl https://api.meshy.ai/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
{
"id": "0193bfc5-ee4f-73f8-8525-44b398884ce9",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000001000,
"expires_at": 1715725401000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "warning",
"issue_count": 1,
"error_count": 0,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"evaluated_at": 1700000001000
},
"consumed_credits": 0
}
Response (wall thickness checked)
{
"id": "0193bfc5-ee4f-73f8-8525-44b398884ce9",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000012000,
"expires_at": 1715725412000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "error",
"issue_count": 2,
"error_count": 1,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"intended_print": {
"printer_type": "sla",
"height_mm": 100,
"longest_side_mm": 118,
"wall_thickness_mm": 0.8,
"dimensions_mm": [118, 72.41, 99.87]
},
"thin_walls": {
"thin_area_ratio": 0.083,
"has_thin_walls": true,
"status": "error"
},
"evaluated_at": 1700000012000
},
"consumed_credits": 0
}
Parameters
- Name
- id
- Type
- path
- Description
The task ID from the create response.
Returns
The Analyze Printability task object. Its printability field isn't present until the task is SUCCEEDED. When Meshy checked wall thickness, printability also includes intended_print and thin_walls.
Delete an Analyze Printability task
Permanently deletes an Analyze Printability task, including its cached result. You can't undo a delete.
Request
curl --request DELETE \
--url https://api.meshy.ai/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
// 200 OK on success, with an empty body.
//
// 409 Conflict when the task is IN_PROGRESS. The task keeps running:
{
"message": "Task is IN_PROGRESS and cannot be deleted. Credits for a task the worker has already started are not refundable; wait for it to reach SUCCEEDED, FAILED or CANCELED, then delete it."
}
Path parameters
- Name
- id
- Type
- path
- Description
The ID of the task to delete.
Task status
Deleting a PENDING task refunds the credits it used when you created it.
An IN_PROGRESS task can't be deleted. The request returns 409 Conflict,
and the task keeps running. Meshy doesn't refund a task that has started,
so deleting it would cost you both the credits and the result. Wait for it
to reach SUCCEEDED, FAILED, or CANCELED, then delete it.
Deleting a task in a final status (SUCCEEDED, FAILED, or CANCELED)
doesn't refund its credits.
Returns
200 OK when the task is deleted, or 409 Conflict when the task is
IN_PROGRESS.
List Analyze Printability tasks
Returns a list of your Analyze Printability tasks.
Request
curl https://api.meshy.ai/openapi/v1/print/analyze?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
[
{
"id": "0193bfc5-ee4f-73f8-8525-44b398884ce9",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"preceding_tasks": 0,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000001000,
"expires_at": 1715725401000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "warning",
"issue_count": 1,
"error_count": 0,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"evaluated_at": 1700000001000
},
"consumed_credits": 0
}
]
Parameters
- Name
- page_num
- Type
- integer
- default 1
- Description
The page number to return, starting at
1.
- Name
- page_size
- Type
- integer
- default 10
- Description
The number of tasks per page, up to
100.
- Name
- sort_by
- Type
- string
- Description
The sort order.
Available values:
+created_at: oldest first-created_at: newest first
Returns
A paginated list of Analyze Printability task objects.
Stream an Analyze Printability task
Streams an Analyze Printability task's updates as Server-Sent Events (SSE).
Request
curl -N https://api.meshy.ai/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response Stream
// Error event example
event: error
data: {
"status_code": 404,
"message": "Task not found"
}
// Message event examples illustrate task progress.
// Every frame is the full task object; fields not yet populated are null / empty.
// The following PENDING frame is abbreviated to the fields that change.
event: message
data: {
"id": "a43b5c6d-7e8f-901a-234b-567c890d1e2f",
"progress": 0,
"status": "PENDING"
}
event: message
data: {
"id": "a43b5c6d-7e8f-901a-234b-567c890d1e2f",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"preceding_tasks": 0,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000001000,
"expires_at": 1715725401000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "warning",
"issue_count": 1,
"error_count": 0,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"evaluated_at": 1700000001000
},
"consumed_credits": 0
}
Parameters
- Name
- id
- Type
- path
- Description
The task ID from the create response.
Returns
A stream of Analyze Printability task objects as Server-Sent Events.
Each event holds the full task object, in the same shape the Get endpoint
returns. While the task is PENDING or IN_PROGRESS, its output fields
are empty (null, [], or {}), and finished_at is 0. Meshy sends
the printability field only after the task is SUCCEEDED.
The Analyze Printability task object
An Analyze Printability task object describes one analysis of a 3D model. It holds the status, the progress, and the printability result when the task succeeds.
The Analyze Printability Task Object
{
"id": "0193bfc5-ee4f-73f8-8525-44b398884ce9",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"preceding_tasks": 0,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000001000,
"expires_at": 1715725401000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "warning",
"issue_count": 1,
"error_count": 0,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"evaluated_at": 1700000001000
},
"consumed_credits": 0
}
The Analyze Printability Task Object (wall thickness checked)
{
"id": "0193bfc5-ee4f-73f8-8525-44b398884ce9",
"type": "print-analyze",
"status": "SUCCEEDED",
"progress": 100,
"preceding_tasks": 0,
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000012000,
"expires_at": 1715725412000,
"task_error": null,
"printability": {
"_version": "v1",
"status": "error",
"issue_count": 2,
"error_count": 1,
"warning_count": 1,
"metrics": {
"is_watertight": true,
"volume": 1.316167354292668,
"non_manifold_edges": 0,
"degenerate_faces": 43242,
"holes": 0
},
"intended_print": {
"printer_type": "sla",
"height_mm": 100,
"longest_side_mm": 118,
"wall_thickness_mm": 0.8,
"dimensions_mm": [118, 72.41, 99.87]
},
"thin_walls": {
"thin_area_ratio": 0.083,
"has_thin_walls": true,
"status": "error"
},
"evaluated_at": 1700000012000
},
"consumed_credits": 0
}
- Name
- id
- Type
- string
- Description
The task ID. Treat it as an opaque string, and don't rely on its format.
- Name
- type
- Type
- string
- Description
The task type, always
print-analyze.
- Name
- status
- Type
- string
- Description
The task status, one of
PENDING,IN_PROGRESS,SUCCEEDED,FAILED, orCANCELED.
- Name
- progress
- Type
- integer
- Description
How much of the task is done, as a percentage. It's
0until the task starts and100when it succeeds.
- Name
- preceding_tasks
- Type
- integer
- Description
The number of tasks ahead of this one in the queue. The value is meaningful only while the task is
PENDING.
- Name
- created_at
- Type
- timestamp
- Description
Time the task was created, in Unix milliseconds.
- Name
- started_at
- Type
- timestamp
- Description
Time the task started, in Unix milliseconds. It's
0until the task starts.
- Name
- finished_at
- Type
- timestamp
- Description
Time the task finished, in Unix milliseconds. It's
0until the task finishes.
- Name
- expires_at
- Type
- timestamp
- Description
Time the task's result expires, in Unix milliseconds. It's
0until the task finishes.
- Name
- task_error
- Type
- object
- Description
The error details when the task fails. It's
nullif the task hasn't failed. See Errors.- Name
message- Type
- string
- Description
A description of what went wrong.
- Name
- printability
- Type
- object
- Description
The result of the analysis. It isn't present until the task is
SUCCEEDED.- Name
_version- Type
- string
- Description
The schema version of the printability result. The value is
v1.
- Name
status- Type
- string
- Description
The overall verdict, one of:
healthy: no errors and no warningswarning: at least one warning, and no errorserror: at least one errorunknown: Meshy couldn't analyze the model
When Meshy checked wall thickness, this is the worse of the mesh checks and
thin_walls.status. From worst to best, the order iserror,warning,unknown, andhealthy.
- Name
issue_count- Type
- integer
- Description
The total number of issues, equal to
error_count + warning_count.
- Name
error_count- Type
- integer
- Description
The number of error-level issues. Meshy counts one error for each of these:
- The model isn't watertight and has more than 8 holes.
- The model has more than 8 holes.
- The volume is zero or less.
- The model has more than 50 non-manifold edges.
When Meshy checked wall thickness, walls that are too thin (
thin_walls.statusiserror) count as one more error.
- Name
warning_count- Type
- integer
- Description
The number of warning-level issues. Meshy counts one warning for each of these:
- The model isn't watertight and has 8 holes or fewer.
- The model has 1 to 8 holes.
- The model has 1 to 50 non-manifold edges.
- The model has degenerate faces.
- Name
metrics- Type
- object
- Description
The raw geometry measurements of the model.
- Name
is_watertight- Type
- boolean
- Description
truewhen the mesh has no boundary edges, that is, when it's closed.
- Name
volume- Type
- number
- Description
The model's volume, in cubic meters.
- Name
non_manifold_edges- Type
- integer
- Description
The number of non-manifold edges.
- Name
degenerate_faces- Type
- integer
- Description
The number of degenerate faces, which are faces with zero area or invalid faces.
- Name
holes- Type
- integer
- Description
The number of holes in the mesh, counted as boundary loops.
- Name
intended_print- Type
- object
- Description
The printer and size that the wall-thickness check used. Present only when Meshy checked wall thickness.
- Name
printer_type- Type
- string
- Description
The printer type,
fdm,sla, orfull_color.
- Name
height_mm- Type
- number
- Description
The print height, in millimeters, when the print is sized by height. Otherwise, it's
null.
- Name
longest_side_mm- Type
- number
- Description
The length of the print's longest side, in millimeters. When the print is sized by height, Meshy calculates it from the model's proportions.
- Name
wall_thickness_mm- Type
- number
- Description
The minimum wall thickness for
printer_type, in millimeters. Meshy reports thinner walls as too thin.
- Name
dimensions_mm- Type
- array
- Description
The print's
[width, depth, height], in millimeters. The height can differ fromheight_mmby a fraction of a millimeter. It'snullfor input other than GLB, or when Meshy can't determine the model's size.
- Name
thin_walls- Type
- object
- Description
The result of the wall-thickness check. Present only when Meshy checked wall thickness.
- Name
thin_area_ratio- Type
- number
- Description
The share of the surface thinner than
intended_print.wall_thickness_mm, from0to1. It'snullwhen Meshy couldn't measure the model.
- Name
has_thin_walls- Type
- boolean
- Description
trueif any part of the surface is too thin. Sharp corners alone can make ittrue, so usestatusto decide whether the walls need thickening. It'snullwhen Meshy couldn't measure the model.
- Name
status- Type
- string
- Description
The wall-thickness verdict, one of:
healthy: 5% or less of the surface is too thin.error: more than 5% of the surface is too thin. To thicken the walls, send this task'sidto Repair Printability asinput_task_id. If this task analyzed an.stl,.fbx, or.gltffile frommodel_url, send that file asmodel_urlinstead.unknown: Meshy couldn't measure the model. If the wall-thickness check itself fails, the task ends asFAILED.
- Name
evaluated_at- Type
- timestamp
- Description
Time Meshy computed the analysis, in Unix milliseconds.
- Name
- consumed_credits
- Type
- integer
- Description
The number of credits the task used. It's always
0, because analysis is free.