Relief API
Turn one photo into a bas-relief 3D model and a 16-bit depth map, for 3D printing, laser engraving, and CNC carving.
Create a Relief task
Creates a Relief task. The task turns a photo into a bas-relief model. When it succeeds, the task produces the model as a GLB file and an STL file, a 16-bit grayscale depth map, and a preview image. To get only the depth map, set should_generate_model to false.
The task runs in the background.
A Relief task can't be the input of another endpoint, such as Remesh, Convert, or Auto Split. Those requests return 403.
Request
# Simple request: a low relief, 60 mm on its longer side
curl https://api.meshy.ai/openapi/v1/relief \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"image_url": "<your publicly accessible image url or base64-encoded data URI>"
}'
# Advanced request: a deep 120 mm relief with a thicker base, curved from side to side
curl https://api.meshy.ai/openapi/v1/relief \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"image_url": "<your publicly accessible image url or base64-encoded data URI>",
"variant": "high",
"size_mm": 120,
"carving_depth_mm": 10,
"base_thickness_mm": 3,
"bend_mode": "convex",
"bend_angle": 90
}'
Response
{
"result": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20"
}
Parameters
- Name
- image_url
- Type
- string
- Required
- Description
The photo to turn into a relief, as a public URL or a data URI (
data:image/png;base64,...).The image must be a JPG, JPEG, PNG, or WebP file of at most 20 MB, and at least 32 × 32 pixels. Its longer side can be at most about 16 times its shorter side. Any other image returns
400. Meshy fills transparent areas with black before it builds the relief.
- Name
- variant
- Type
- string
- default low
- Description
The relief style. It shapes the depth map and sets the default
carving_depth_mm.Available values:
high: deeper carving, for 3D-printed pieces.low: shallow carving, for laser engraving, CNC carving, and thin plaques.
Sending
nullor""is the same as leaving it out. Any other value returns400.
- Name
- should_generate_model
- Type
- boolean
- default true
- Description
Whether to build the relief model. Set it to
falsefor a depth-map-only task, with no model and no preview image. Meshy still checks the size, carving, base, bend, and resolution parameters, but doesn't use them. It doesn't change the credit cost.
- Name
- size_mm
- Type
- number
- default 60
- Description
The length of the photo's longer side on the model, measured flat before any bend, from
20to250millimeters. Withremove_base, the model can be smaller.
- Name
- carving_mode
- Type
- string
- default emboss
- Description
Whether the subject stands out from the plate or is cut into it.
Available values:
emboss: the nearer parts of the photo stand out.engrave: the depth is inverted, so the nearer parts are cut in.
The depth map is the same in both modes.
- Name
- carving_depth_mm
- Type
- number
- default 6 (high), 3 (low)
- Description
How deep the relief is carved, from
0to60millimeters. Withremove_baseset totrue,0leaves an empty model. The task still succeeds and costs 20 credits, and its GLB and STL files have no geometry.
- Name
- remove_base
- Type
- boolean
- default false
- Description
Whether to cut away the background and build no base plate. When it's
true,removal_thresholdsets what counts as background. Meshy checksremoval_thresholdeither way.
remove_base = true- Name
- removal_threshold
- Type
- number
- default 0.01
- Description
The depth below which Meshy cuts the background away, from
0.01to1, where the depth map runs from0to1. A high value can cut away the whole relief and leave an empty model, which still succeeds and is charged.
- Name
- base_thickness_mm
- Type
- number
- default 1, or 0 with remove_base
- Description
The thickness of the base plate, from
0.1to10millimeters. Whenremove_baseistrue, leave it out or send0.
- Name
- bend_mode
- Type
- string
- default off
- Description
Whether to bend the relief, and which way. When it isn't
off,bend_axisandbend_angleshape the bend. Meshy checks them either way.Available values:
off: a flat relief.convex: the front bulges outward.concave: the front curves inward.
bend_mode = convex or concave- Name
- bend_axis
- Type
- string
- default xz
- Description
Which edges the bend curls.
Available values:
xz: the left and right edges.yz: the top and bottom edges.
- Name
- bend_angle
- Type
- number
- default 60
- Description
The arc the bend spans, from
0to360degrees. Below1, the relief stays flat.
- Name
- mesh_resolution
- Type
- integer
- default 1024
- Description
The number of mesh points along the photo's longer side, from
512to2048. A higher value keeps finer detail and makes larger files. At the default1024, the GLB file is about 40 to 50 MB and the STL file about 80 to 105 MB. A square photo gives the larger sizes. At2048, they are about 150 MB and 300 MB. A bend makes them larger: the STL file can reach about 800 MB at2048.
Returns
202 Accepted, with the ID of the new Relief task in result.
Failure modes
- Name
400 - Bad Request- Description
The request can't run. The error message says which problem it found. For example:
- Missing parameter:
image_urlwasn't sent. - Invalid parameter: A parameter has the wrong type, is outside its range, or isn't one of its available values. For example,
variantisn'thighorlow, ormesh_resolutionisn't an integer from512to2048. - Base thickness:
base_thickness_mmisn't0withremove_baseset totrue, or is below0.1without it. - Unreachable URL: Meshy can't download the
image_urlimage, for example because the URL returns404or times out. - Invalid image: The image isn't a JPG, JPEG, PNG, or WebP file, is over 20 MB, is smaller than 32 × 32 pixels, has too many pixels, or can't be read.
- Extreme aspect ratio: The image's longer side is more than about 16 times its shorter side.
Fix the request, then send it again. Meshy doesn't charge for it. See Errors.
- Missing parameter:
- Name
401 - Unauthorized- Description
The API key is missing or invalid. Check the
Authorizationheader.
- Name
402 - Payment Required- Description
For example:
- Insufficient credits: The account doesn't have enough credits for this task, or the account reached a credit limit. Check your credit balance, then retry.
- Free plan: Creating a task requires a paid plan. Upgrade your plan in your subscription settings, then retry.
- Name
403 - Forbidden- Description
Content moderation blocked the image. Meshy doesn't charge for the request. Send a different image.
- Name
429 - Too Many Requests- Description
One of these limits was reached:
- You sent too many requests. Wait, then retry. See Rate limits.
- Too many of your tasks are queued or running. Wait for some to finish, then retry.
- On an unlimited plan with no credits left, you reached the number of tasks that can run without credits. Wait for a task to finish, or add credits.
If a safety check declines the image while the task runs, the task fails with task_error.type set to invalid_input and task_error.code set to provider_content_refused. Meshy refunds the task's credits. Send a different image. See Errors.
Get a Relief task
Returns a Relief task by its ID.
Request
curl https://api.meshy.ai/openapi/v1/relief/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
{
"id": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20",
"type": "relief",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.glb?Expires=***",
"stl": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.stl?Expires=***"
},
"depth_map_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/depth.png?Expires=***",
"thumbnail_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/preview.png?Expires=***",
"progress": 100,
"status": "SUCCEEDED",
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000060000,
"expires_at": 1700259260000,
"task_error": null,
"consumed_credits": 20
}
Parameters
- Name
- id
- Type
- path
- Description
The task ID from the create response.
Returns
The Relief task object.
Delete a Relief task
Permanently deletes a Relief task, including its model, depth map, and data. You can't undo a delete.
Request
curl --request DELETE \
--url https://api.meshy.ai/openapi/v1/relief/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20 \
-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 or FAILED, then delete it.
Deleting a SUCCEEDED task doesn't refund its credits. A FAILED task was already refunded when it failed.
Returns
200 OK when the task is deleted, or 409 Conflict when the task is
IN_PROGRESS.
List Relief tasks
Returns a list of your Relief tasks.
Request
curl https://api.meshy.ai/openapi/v1/relief?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
[
{
"id": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20",
"type": "relief",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.glb?Expires=***",
"stl": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.stl?Expires=***"
},
"depth_map_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/depth.png?Expires=***",
"thumbnail_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/preview.png?Expires=***",
"progress": 100,
"status": "SUCCEEDED",
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000060000,
"expires_at": 1700259260000,
"task_error": null,
"consumed_credits": 20
}
]
Parameters
- Name
- page_num
- Type
- integer
- Description
The page number to return. Starts at and defaults to
1.
- Name
- page_size
- Type
- integer
- Description
The number of tasks per page, up to
100. Defaults to10. Meshy treats a value from101to255as100, and a larger value returns400.
- Name
- sort_by
- Type
- string
- Description
The sort order.
Available values:
+created_at: oldest first-created_at: newest first
Returns
A paginated list of Relief task objects.
Stream a Relief task
Streams a Relief task's updates as Server-Sent Events (SSE).
Request
curl -N https://api.meshy.ai/openapi/v1/relief/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/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 (other task fields omitted here for brevity;
// each frame is the full task object).
event: message
data: {
"id": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20",
"progress": 0,
"status": "PENDING"
}
event: message
data: {
"id": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20",
"type": "relief",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.glb?Expires=***",
"stl": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.stl?Expires=***"
},
"depth_map_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/depth.png?Expires=***",
"thumbnail_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/preview.png?Expires=***",
"progress": 100,
"status": "SUCCEEDED",
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000060000,
"expires_at": 1700259260000,
"task_error": null,
"consumed_credits": 20
}
Parameters
- Name
- id
- Type
- path
- Description
The task ID from the create response.
Returns
A stream of Relief task objects as Server-Sent Events.
Each message event holds the full task object, the same one Get a Relief task returns. While the task is PENDING or IN_PROGRESS, the fields that change between events are progress, status, started_at, and preceding_tasks (present only while tasks are ahead of this one). model_urls, depth_map_url, and thumbnail_url get their values when the task reaches SUCCEEDED. A depth-map-only task keeps model_urls {} and an empty thumbnail_url.
An error event holds only status_code and message, so check the event name before you read status.
The Relief task object
A Relief task object describes one relief made from a photo. model_urls, depth_map_url, and thumbnail_url are always present, and empty until the task succeeds.
The Relief Task Object
{
"id": "0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20",
"type": "relief",
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.glb?Expires=***",
"stl": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/model.stl?Expires=***"
},
"depth_map_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/depth.png?Expires=***",
"thumbnail_url": "https://assets.meshy.ai/***/tasks/0199c3d2-5a7e-7b14-9e2f-3c8d1a6b4f20/output/preview.png?Expires=***",
"progress": 100,
"status": "SUCCEEDED",
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000060000,
"expires_at": 1700259260000,
"task_error": null,
"consumed_credits": 20
}
Depth map only
{
"id": "0199c3d2-6b8f-7c25-8f3a-4d9e2b7c5a31",
"type": "relief",
"model_urls": {},
"depth_map_url": "https://assets.meshy.ai/***/tasks/0199c3d2-6b8f-7c25-8f3a-4d9e2b7c5a31/output/depth.png?Expires=***",
"thumbnail_url": "",
"progress": 100,
"status": "SUCCEEDED",
"created_at": 1699999999000,
"started_at": 1700000000000,
"finished_at": 1700000030000,
"expires_at": 1700259230000,
"task_error": null,
"consumed_credits": 20
}
- 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
relief.
- Name
- model_urls
- Type
- object
- Description
Download URLs for the relief model. The files can be large;
mesh_resolutionlists typical sizes.- Name
glb- Type
- string
- Description
The GLB file, without texture. Its units are meters. Absent for a depth-map-only task.
- Name
stl- Type
- string
- Description
The same model as a binary STL file. Its units are millimeters, so it opens at the relief's real size, with Z up. Absent for a depth-map-only task.
- Name
- depth_map_url
- Type
- string
- Description
Download URL for the 16-bit grayscale depth map the relief is built from. Brighter pixels are higher. The values are relative heights, not millimeters. Laser engraving and CNC software can use it as a height map. The file is about 1 to 2 MB. Empty if there is none.
- Name
- thumbnail_url
- Type
- string
- Description
Download URL for a preview image of the relief model. Empty if none was rendered, including for a depth-map-only task.
- 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
- status
- Type
- string
- Description
The task status, one of
PENDING,IN_PROGRESS,SUCCEEDED, orFAILED.
- Name
- preceding_tasks
- Type
- integer
- Description
The number of tasks ahead of this one in the queue. The field is left out when the value is
0, so it appears only while tasks are ahead of this one.
- 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. See Errors.
- Name
- consumed_credits
- Type
- integer
- Description
The number of credits the task used:
20, or0for aFAILEDtask, which Meshy refunds.