lowpoly retires Oct 30, 2026. Please switch models before these dates to avoid request errors. See all deprecations

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.


POST/openapi/v1/print/analyze

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

POST
/openapi/v1/print/analyze
# 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 status SUCCEEDED, 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 uses input_task_id.

    From an http or https URL, the model must be a .glb, .gltf, .obj, .fbx, or .stl file 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 .stl file as an http or https URL.

    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's expires_at. Reading the task again doesn't renew it. For a model you made with Meshy, send input_task_id instead, which works while Meshy keeps the source task (see Asset retention). To use the model after that, download it before expires_at and 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 uses fdm.

    Available values:

    • fdm: filament, 1.0 mm minimum wall
    • sla: resin, 0.8 mm minimum wall
    • full_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 1 to 1000. A value outside the range returns 400. Send this or intended_print_longest_side_mm, not both.

    It works only with GLB input. For a model_url that isn't a .glb file, send intended_print_longest_side_mm instead.

  • Name
    intended_print_longest_side_mm
    Type
    number
    Description

    The length of the print's longest side, in millimeters, from 1 to 1000. A value outside the range returns 400. It works with every input format.

If you send printer_type without a size, Meshy uses this print size:

  • .glb file or any input_task_id: 150 mm tall
  • .stl file: the file's own longest side, read as millimeters
  • .obj, .fbx, or .gltf file: 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_id nor model_url was sent.
    • Invalid UUID: input_task_id isn't a valid UUID.
    • Invalid model URL: model_url is malformed, uses an unsupported scheme, or has an unsupported file extension.
    • Model file too large: The model_url file is over 400 MB from an http or https URL, or over 100 MB as a data URI.
    • Too many faces: The model_url file 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_url file is an ASCII FBX over 100 MB. Send it as binary FBX or GLB.
    • Unreadable model file: The model_url file 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_url file 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_url returned 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 send input_task_id while Meshy keeps the source task.
    • Task not succeeded: The input_task_id task is still pending, in progress, or failed.
    • Invalid print size: intended_print_height_mm or intended_print_longest_side_mm is outside 1 to 1000, or the request has both.
    • Unknown printer type: printer_type isn't fdm, sla, or full_color.
    • Height on a non-GLB model: The request has intended_print_height_mm and a model_url that isn't a .glb file. Send intended_print_longest_side_mm instead.
    • 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_mm instead. For a .glb model_url and some input_task_id tasks, Meshy finds this only after the task starts, and the task ends as FAILED instead.
    • STL size unusable: The request has printer_type without a size, and Meshy can't read the .stl file's own longest side, or it's outside 1 to 1,000 mm. Send intended_print_longest_side_mm.

    Fix the request, then send it again. See Errors.

  • Name
    401 - Unauthorized
    Description

    The API key is missing or invalid. Check the Authorization header.

  • Name
    403 - Forbidden
    Description

    input_task_id is a bas-relief model, which this endpoint can't analyze. The message is This 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_id is a supported task that's yours or in one of your workspaces, or send the model as model_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/openapi/v1/print/analyze/:id

Get an Analyze Printability task

Returns an Analyze Printability task by its ID.

Request

GET
/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f
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/openapi/v1/print/analyze/:id

Delete an Analyze Printability task

Permanently deletes an Analyze Printability task, including its cached result. You can't undo a delete.

Request

DELETE
/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f
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.


GET/openapi/v1/print/analyze

List Analyze Printability tasks

Returns a list of your Analyze Printability tasks.

Request

GET
/openapi/v1/print/analyze
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.


GET/openapi/v1/print/analyze/:id/stream

Stream an Analyze Printability task

Streams an Analyze Printability task's updates as Server-Sent Events (SSE).

Request

GET
/openapi/v1/print/analyze/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream
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, or CANCELED.

  • Name
    progress
    Type
    integer
    Description

    How much of the task is done, as a percentage. It's 0 until the task starts and 100 when 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 0 until the task starts.

  • Name
    finished_at
    Type
    timestamp
    Description

    Time the task finished, in Unix milliseconds. It's 0 until the task finishes.

  • Name
    expires_at
    Type
    timestamp
    Description

    Time the task's result expires, in Unix milliseconds. It's 0 until the task finishes.

  • Name
    task_error
    Type
    object
    Description

    The error details when the task fails. It's null if 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 warnings
      • warning: at least one warning, and no errors
      • error: at least one error
      • unknown: 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 is error, warning, unknown, and healthy.

    • 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.status is error) 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

        true when 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, or full_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 from height_mm by a fraction of a millimeter. It's null for 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, from 0 to 1. It's null when Meshy couldn't measure the model.

      • Name
        has_thin_walls
        Type
        boolean
        Description

        true if any part of the surface is too thin. Sharp corners alone can make it true, so use status to decide whether the walls need thickening. It's null when 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's id to Repair Printability as input_task_id. If this task analyzed an .stl, .fbx, or .gltf file from model_url, send that file as model_url instead.
        • unknown: Meshy couldn't measure the model. If the wall-thickness check itself fails, the task ends as FAILED.
    • 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.