# Meshy API > Meshy is an AI-powered 3D model generation platform. The Meshy API is a RESTful API that allows you to programmatically generate 3D models, textures, images, rig characters, and animate them. - API Base URL: `https://api.meshy.ai/openapi/` - Documentation: https://docs.meshy.ai - Status Page: https://status.meshy.ai > **For agents:** For single-fetch full content (all docs pages concatenated), see https://docs.meshy.ai/llms-full.txt. For tool-calling access, install the Meshy MCP server — see https://docs.meshy.ai/api/ai. ## Instructions for Large Language Models When generating code that integrates with the Meshy API, follow these guidelines: ### 1. Authentication All requests require a Bearer token in the `Authorization` header: ``` Authorization: Bearer msy_YOUR_API_KEY ``` API keys are created at https://www.meshy.ai/settings/api and have the format `msy_`. **Tip:** For tool-calling access from MCP-compatible agents (Claude Code, Cursor, Windsurf, Claude Desktop, Codex CLI, etc.), install the Meshy MCP server instead of calling this REST API directly: ``` claude mcp add meshy -- npx -y @meshy-ai/meshy-mcp-server -e MESHY_API_KEY=msy_YOUR_API_KEY ``` See https://docs.meshy.ai/api/ai for the full install matrix (8 clients) and tool reference. ### 2. Asynchronous Task Model Meshy uses an asynchronous execution model. All generation endpoints return a task ID, not the result directly. You retrieve results via one of three mechanisms: - **Polling** — GET the task endpoint until `status` is terminal (shown in the examples below) - **SSE streaming** — connect to `//:id/stream` for real-time updates (see section 3) - **Webhooks** — register a URL to receive a POST when the task completes (see https://docs.meshy.ai/api/webhooks.md) **Correct pattern:** ```python import requests, time, os headers = {"Authorization": f"Bearer {os.environ['MESHY_API_KEY']}"} # Step 1: Create a task response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json={"mode": "preview", "prompt": "a monster mask"}, ) task_id = response.json()["result"] # Step 2: Poll until completion while True: task = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{task_id}", headers=headers, ).json() if task["status"] == "SUCCEEDED": break if task["status"] == "FAILED": raise Exception(task["task_error"]["message"]) time.sleep(5) # Step 3: Download result model_url = task["model_urls"]["glb"] ``` **WRONG pattern** (expecting synchronous result): ```python # WRONG - the POST does not return a model response = requests.post("https://api.meshy.ai/openapi/v2/text-to-3d", ...) model = response.json()["model_urls"] # WRONG ``` ### 3. SSE Streaming (Alternative to Polling) All task endpoints support Server-Sent Events streaming at `//:id/stream`: ```python import requests, json headers = { "Authorization": f"Bearer {API_KEY}", "Accept": "text/event-stream" } response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{task_id}/stream", headers=headers, stream=True ) for line in response.iter_lines(): if line and line.startswith(b"data:"): data = json.loads(line.decode("utf-8")[5:]) print(data["status"], data.get("progress")) if data["status"] in ["SUCCEEDED", "FAILED", "CANCELED"]: break response.close() ``` ### 4. Task Statuses All tasks follow the same lifecycle: `PENDING` -> `IN_PROGRESS` -> `SUCCEEDED` | `FAILED` | `CANCELED` ### 5. Timestamps All timestamps in the API are Unix epoch milliseconds (not seconds). For example, `1693569600000` represents September 1, 2023 12:00:00 PM UTC. ### 6. Model Output Formats 3D model outputs are available in multiple formats: GLB, FBX, OBJ, USDZ. Access them via `model_urls.glb`, `model_urls.fbx`, etc. Not all formats are always available; omitted properties mean that format was not generated. ### 7. Asset Retention Generated assets are retained for a maximum of **3 days** for non-Enterprise customers. Download and store models locally if you need them longer. ### 8. Rate Limits | Tier | Requests/Second | Queue Tasks | Priority | |------|-----------------|-------------|----------| | Pro | 20 | 10 | Default | | Studio | 20 | 20 | Higher | | Enterprise | 100 | 50+ | Highest | Exceeding limits returns `429 Too Many Requests`. ### 9. Choosing the Right AI Model - Use `"latest"` or `"meshy-6"` for the best quality (default). - Use `"meshy-5"` for the previous generation model. - `"latest"` always resolves to the newest model (currently Meshy 6). ### 10. Common Mistakes to Avoid - **Don't call CORS-restricted endpoints from browser JavaScript.** The API blocks CORS requests. Use a server-side proxy. - **Don't forget `enable_pbr: true`** if you need metallic/roughness/normal maps. - **Don't set both `texture_prompt` and `texture_image_url`** — if both are provided, `texture_prompt` takes precedence. - **Don't assume model format availability.** Check that the URL key exists in `model_urls` before downloading. --- ## Complete Code Example: Text to 3D (Preview + Refine) ```python import requests, os, time headers = {"Authorization": f"Bearer {os.environ['MESHY_API_KEY']}"} # 1. Create preview task preview_resp = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json={ "mode": "preview", "prompt": "a monster mask", "should_remesh": True, }, ) preview_resp.raise_for_status() preview_task_id = preview_resp.json()["result"] # 2. Poll preview task while True: task = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{preview_task_id}", headers=headers, ).json() if task["status"] == "SUCCEEDED": break if task["status"] == "FAILED": raise Exception(task["task_error"]["message"]) time.sleep(5) # 3. Download preview model with open("preview_model.glb", "wb") as f: f.write(requests.get(task["model_urls"]["glb"]).content) # 4. Create refine task (texturing) refine_resp = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json={ "mode": "refine", "preview_task_id": preview_task_id, "enable_pbr": True, }, ) refine_resp.raise_for_status() refine_task_id = refine_resp.json()["result"] # 5. Poll refine task while True: task = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{refine_task_id}", headers=headers, ).json() if task["status"] == "SUCCEEDED": break if task["status"] == "FAILED": raise Exception(task["task_error"]["message"]) time.sleep(5) # 6. Download refined (textured) model with open("refined_model.glb", "wb") as f: f.write(requests.get(task["model_urls"]["glb"]).content) ``` ## Complete Code Example: Image to 3D ```python import requests, os, time headers = {"Authorization": f"Bearer {os.environ['MESHY_API_KEY']}"} response = requests.post( "https://api.meshy.ai/openapi/v1/image-to-3d", headers=headers, json={ "image_url": "https://example.com/photo.jpg", "should_texture": True, "enable_pbr": True, }, ) response.raise_for_status() task_id = response.json()["result"] while True: task = requests.get( f"https://api.meshy.ai/openapi/v1/image-to-3d/{task_id}", headers=headers, ).json() if task["status"] == "SUCCEEDED": break if task["status"] == "FAILED": raise Exception(task["task_error"]["message"]) time.sleep(5) with open("model.glb", "wb") as f: f.write(requests.get(task["model_urls"]["glb"]).content) ``` --- --- # API Reference # Quickstart Source: https://docs.meshy.ai/api/quick-start # Quickstart This is the API reference for programmatically interacting with Meshy. > **Note:** **Using an AI coding assistant?** See our [AI Integration](/api/ai) page — install the Meshy MCP server for tool-calling access from Claude Code, Cursor, Windsurf, and other MCP-compatible tools, or point a plain chat agent at [`llms.txt`](/llms.txt). --- The Meshy API provides a simple interface to generate 3D models and textures from text prompts and images. Follow this guide to get started quickly. ## Create an API Key [Create an API key in the API settings page here](https://www.meshy.ai/settings/api), which you'll use to securely [authenticate your requests](/api/authentication). The API key's format is `msy-`. ![Generate API Key](https://cdn.meshy.ai/docs-assets/api/quick-start/generate-api-key.webp) Once you've generated an API key, store it somewhere in a secure location. ### Test Mode API Key During development and testing, you can use our test mode API key to explore the API without consuming your credits: ```javascript msy_dummy_api_key_for_test_mode_12345678 ``` This special API key has the following characteristics: - It can be used to make requests to all Meshy API endpoints - No credits are consumed when using this key - All valid requests will return the same sample task results, regardless of the input parameters - The response data structure will match the production API exactly - Perfect for testing your API integration before switching to your real API key > **Note:** The test mode API key is for development purposes only. For production use, please use your own API key. ## Make Your First "Text to 3D" API Request In this example, we will generate a 3D model from a text prompt using the [`text-to-3d` endpoint](/api/text-to-3d). The process involves two stages: the preview stage and the refine stage. In the preview stage, a base mesh is generated with no texture applied, allowing you to evaluate the geometry. In the refine stage, the preview mesh is textured based on the text prompt. We will show you how to make these requests in a Python script. ### Preview Meshy provides a set of REST API endpoints. You can use them with any HTTP client of your choice. Regardless of which API you call, the API key is always passed as a header named `Authorization`. Please remember to export your API key as an environment variable named `MESHY_API_KEY` before using this script. The key parameters to the preview request are `mode`, which is always `"preview"`, and `prompt`, a description of the model you need. In this example, we have also specified `should_remesh`, but it is optional. **api_request.py** ```python import requests import os import time headers = { "Authorization": f"Bearer {os.environ['MESHY_API_KEY']}" } # 1. Generate a preview model and get the task ID generate_preview_request = { "mode": "preview", "prompt": "a monster mask", "should_remesh": True, } generate_preview_response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=generate_preview_request, ) generate_preview_response.raise_for_status() preview_task_id = generate_preview_response.json()["result"] print("Preview task created. Task ID:", preview_task_id) ``` This completes the preview API call. Please bear in mind that Meshy API adopts an asynchronous execution model, meaning that when you create a task, the API endpoint only returns a task ID. You must then poll the task status endpoint with this ID to check if the task has finished. **api_request.py** ```python # 2. Poll the preview task status until it's finished preview_task = None while True: preview_task_response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{preview_task_id}", headers=headers, ) preview_task_response.raise_for_status() preview_task = preview_task_response.json() if preview_task["status"] == "SUCCEEDED": print("Preview task finished.") break print("Preview task status:", preview_task["status"], "| Progress:", preview_task["progress"], "| Retrying in 5 seconds...") time.sleep(5) ``` Once the task has finished, you will be able to access the model URLs from its response. Let's download the model from the `model_urls` field in the response. **api_request.py** ```python # 3. Download the preview model in glb format preview_model_url = preview_task["model_urls"]["glb"] preview_model_response = requests.get(preview_model_url) preview_model_response.raise_for_status() with open("preview_model.glb", "wb") as f: f.write(preview_model_response.content) print("Preview model downloaded.") ``` If everything works out so far, your `preview_model.glb` should look similar to this. It will not be an exact match, due to the intrinsic randomness in the AI pipeline. ![Preview model](https://cdn.meshy.ai/docs-assets/api/quick-start/preview-model.webp) ### Refine Let's proceed to the refine stage. To initiate the refine request, provide the preview task ID as an input parameter. **api_request.py** ```python # 4. Generate a refined model and get the task ID generate_refined_request = { "mode": "refine", "preview_task_id": preview_task_id, } generate_refined_response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=generate_refined_request, ) generate_refined_response.raise_for_status() refined_task_id = generate_refined_response.json()["result"] print("Refined task created. Task ID:", refined_task_id) # 5. Poll the refined task status until it's finished refined_task = None while True: refined_task_response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{refined_task_id}", headers=headers, ) refined_task_response.raise_for_status() refined_task = refined_task_response.json() if refined_task["status"] == "SUCCEEDED": print("Refined task finished.") break print("Refined task status:", refined_task["status"], "| Progress:", refined_task["progress"], "| Retrying in 5 seconds...") time.sleep(5) # 6. Download the refined model in glb format refined_model_url = refined_task["model_urls"]["glb"] refined_model_response = requests.get(refined_model_url) refined_model_response.raise_for_status() with open("refined_model.glb", "wb") as f: f.write(refined_model_response.content) print("Refined model downloaded.") ``` The 3D model `refined_model.glb` is now fully textured ✨. ![Refined model](https://cdn.meshy.ai/docs-assets/api/quick-start/refined-model.webp) ### Put It Together Here is the complete code for using the Text to 3D API. **api_request.py** ```python import requests import os import time headers = { "Authorization": f"Bearer {os.environ['MESHY_API_KEY']}" } # 1. Generate a preview model and get the task ID generate_preview_request = { "mode": "preview", "prompt": "a monster mask", "should_remesh": True, } generate_preview_response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=generate_preview_request, ) generate_preview_response.raise_for_status() preview_task_id = generate_preview_response.json()["result"] print("Preview task created. Task ID:", preview_task_id) # 2. Poll the preview task status until it's finished preview_task = None while True: preview_task_response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{preview_task_id}", headers=headers, ) preview_task_response.raise_for_status() preview_task = preview_task_response.json() if preview_task["status"] == "SUCCEEDED": print("Preview task finished.") break print("Preview task status:", preview_task["status"], "| Progress:", preview_task["progress"], "| Retrying in 5 seconds...") time.sleep(5) # 3. Download the preview model in glb format preview_model_url = preview_task["model_urls"]["glb"] preview_model_response = requests.get(preview_model_url) preview_model_response.raise_for_status() with open("preview_model.glb", "wb") as f: f.write(preview_model_response.content) print("Preview model downloaded.") # 4. Generate a refined model and get the task ID generate_refined_request = { "mode": "refine", "preview_task_id": preview_task_id, } generate_refined_response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=generate_refined_request, ) generate_refined_response.raise_for_status() refined_task_id = generate_refined_response.json()["result"] print("Refined task created. Task ID:", refined_task_id) # 5. Poll the refined task status until it's finished refined_task = None while True: refined_task_response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{refined_task_id}", headers=headers, ) refined_task_response.raise_for_status() refined_task = refined_task_response.json() if refined_task["status"] == "SUCCEEDED": print("Refined task finished.") break print("Refined task status:", refined_task["status"], "| Progress:", refined_task["progress"], "| Retrying in 5 seconds...") time.sleep(5) # 6. Download the refined model in glb format refined_model_url = refined_task["model_urls"]["glb"] refined_model_response = requests.get(refined_model_url) refined_model_response.raise_for_status() with open("refined_model.glb", "wb") as f: f.write(refined_model_response.content) print("Refined model downloaded.") ``` Copy and paste the code into a Python script and run it. **Run the script** ```bash python api_request.py ``` You should see output in your terminal like the following: ![Run the script](https://cdn.meshy.ai/docs-assets/api/quick-start/run-script.webp) ## Next Steps - You can find the complete API reference in the "API Endpoints" section, which provides detailed information about each API. - Explore details about [Pricing](/api/pricing), [Rate Limits](/api/rate-limits), and how to troubleshoot [common errors](/api/errors). - Don't forget to check out our [Changelog](/api/changelog) regularly for updates and bug fixes. - Have feedback or facing issues? Join our [Discord](https://discord.com/invite/KgD5yVM9Y4) community - we'd love to hear from you! --- # Authentication Source: https://docs.meshy.ai/api/authentication # Authentication Using the Meshy API requires authentication. This guide will show you how to create an account and API keys. --- ## API Keys ### Creating a Meshy Account Meshy API requires you to have a Meshy account to create and manage API keys. If a request is made to the API without an API key, the API will respond with an invalid credentials error. You can create a Meshy account by visiting the [Meshy official website](https://www.meshy.ai/) and sign up. ### Creating API Keys Once you have created a Meshy account, you can create API keys by visiting the [API settings page](https://www.meshy.ai/settings/api). You can create multiple API keys for different purposes. For example, you can create one API key for your iOS app and another for your web app. The usage of each API key is tracked separately, and you can revoke them at any time. To create an API key, click on the `Create API Key` button on the API page, and then enter a name for your API key. Once you have created an API key, you will be shown the API key value. You can copy the API key value and store it in a secure location. **You will not be able to see this API key value again.** ### Using API Keys Once you have created an API key, you can use it to authenticate your requests to the Meshy API. You can pass your API key to the API in the `Authorization` header, an example header is shown below. ```json { "Authorization": "Bearer msy_sOmEbOgUsApIkEyFoReXaMpLe1234567890" } ``` > **Note:** The `Bearer `   prefix in the header value is mandatory to interact with the Meshy API programatically. > You can learn more about it at [IETF RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750) --- ## Security We take security very seriously at Meshy, and we work hard to ensure that Meshy API is secure. We hope your data and your users' data is safe with us. Here are some high-level guidelines to help you keep your data and requests safe when using Meshy API, but please also make sure to follow the guidelines practiced at your team or workplace. ### Transport Layer Security While your data is encrypted at rest once it's stored in Meshy, Meshy API uses and enforces [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security), to encrypt data in transit. It means that all requests to and from Meshy API are sent over HTTPS, and any request made over HTTP will get an `301 Moved Permanently` status code. Although not recommended, in some cases, if you have to talk to HTTP, you need to explicity tell your HTTP client to follow HTTP to HTTPS redirections. Here are some examples: ```bash # use `-L` to follow HTTP to HTTPS redirections curl -L -X 'POST' \ https://api.meshy.ai/openapi/v1/text-to-texture ``` ```python import requests # use `allow_redirects=True` to follow HTTP to HTTPS redirections response = requests.post("https://api.meshy.ai/openapi/v1/text-to-texture", allow_redirects=True) ``` ```javascript // use `followRedirects: true` to follow HTTP to HTTPS redirections const response = await fetch("https://api.meshy.ai/openapi/v1/text-to-texture", { redirect: "follow", }); ``` ### API Key Safety > **Note:** Please note that even Meshy team members cannot view or recover revoked API keys for you! Once minted, API keys are **not** visible in the dashboard anymore, so please download and keep it safe and securely since anyone who obtains it can use it to talk to Meshy API on your behalf. If you believe your API key has been compromised, you can revoke it at any time from the dashboard, once revoked, it will no longer be valid. ### Security Disclosure If you believe you've discovered a security issue in Meshy API, please [get in touch](mailto:support@meshy.ai?subject=%5BSupport%5D%20Enter%20your%20question%20or%20problem%E2%80%A6&body=How%20can%20we%20assist%20you%3F%20Please%20provide%20any%20relevant%20details%20that%20will%20help%20us%20respond%20to%20your%20inquiry.) with us. We appreciate your responsible disclosure and will make every effort to acknowledge your contributions. --- # Errors Source: https://docs.meshy.ai/api/errors # Errors In this guide, we will talk about what happens when something goes wrong while you work with the Meshy API. --- ## Status Codes Meshy leverages conventional HTTP response codes to indicate the success or failure of an API request. Generally, codes in the `2xx` range indicate success; codes in the `4xx` range indicate an error that failed given the information provided (e.g., a required parameter was missing, an invalid model was provided, etc.); codes in the `5xx` range indicate an internal error with Meshy's servers, which should be rare. But if you do see one, please check on our [status page](https://status.meshy.ai) for more information and contact us via [Discord](https://discord.com/invite/KgD5yVM9Y4) for help. Here is a list of the different categories of status codes returned by the Meshy API. Use these to understand if a request was successful. - `2xx` A 2xx status code indicates a successful response. - `200 - OK` By default if everything worked as expected a 200 status code will be returned. - `202 - Accepted` Your request has been accepted for processing, but the processing has not been completed. This is a non-committal response from Meshy API. For example, a request to create a new Text to Texture task will return a 202 status code. - `4xx` A 4xx status code indicates a client error — this means it's a _you_ problem. - `400 - Bad Request` The request was unacceptable, often due to missing a mandatory parameter or one of the parameters was malformed. - `401 - Unauthorized` No valid API key provided or the API key provided is not authorized to access the Meshy API endpoint. - `403 - Forbidden` Access to the requested resource is forbidden. This might happen if you try to access the Meshy API directly from client-side JavaScript code, as Cross-Origin Resource Sharing (CORS) requests from browsers are not permitted. Consider using a server-side proxy for such requests. For more details, see the [MDN CORS guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS/Errors). - `402 - Payment Required` Insufficient funds in the account associated with the provided API key. - `404 - Not Found` The requested resource doesn't exist. For example, when you try to retrieve a task by its ID but provided an invalid ID, you will get a 404 status code. - `429 - Too Many Requests` Too many requests hit the Meshy API too quickly. Please refer to the [Rate Limits](/api/rate-limits) guide for details. - `5xx` A 5xx status code indicates a server error, we hope you won't be seeing these - but if you do, please contact us for help! --- ## Error Response Whenever a request is unsuccessful, the Meshy API will return an error response with an error type and message. You can use this information to understand better what has gone wrong and how to fix it. Most of the error messages should be helpful and actionable, they also share a common structure: - `message` · *string* A short description message of the error. **Example Response with 400 - Bad Request status code** ```bash { "message": "Invalid model file extension: .3dm" } ``` --- ## Task Failure When a task's status becomes `FAILED`, the `task_error` field in the task response will contain information about what went wrong. ### Common Failure Reasons The error messages in `task_error.message` are simplified for security. Here are the common failure scenarios: - `The server is busy. Please try again later.` This error occurs when: * **Timeout**: The task exceeded its maximum processing time. * **Server backlog**: The processing servers are temporarily overloaded. **Recommended action**: Wait a few minutes and retry the task. If the issue persists, check the [status page](https://status.meshy.ai) for any ongoing incidents. - `The input file or parameters could not be processed. Please check your input and try again.` This error occurs when: * **Unprocessable content**: The input file or parameters failed validation during processing. **Recommended action**: Check that your input files are valid and parameters are correct, then retry. - `Internal server error.` This is a generic error that may occur due to: * **Model processing failure**: The input model or image could not be processed correctly. * **Generation failure**: The 3D generation pipeline encountered an unexpected issue. * **File corruption**: The input or intermediate files were corrupted during processing. **Recommended action**: Verify your input files are valid and try again. If the issue persists, contact support via [Discord](https://discord.com/invite/KgD5yVM9Y4) with your task ID. ### Best Practices for Handling Task Failures 1. **Implement retry logic**: For transient errors like server busy or timeout, implement exponential backoff retry logic. 2. **Monitor task status**: Poll the task status endpoint to detect failures early. 3. **Log task IDs**: Always log the task ID for debugging purposes. 4. **Validate inputs**: Ensure your input images and models meet the format requirements before submission. **Example Task Response with FAILED status** ```bash { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "status": "FAILED", "task_error": { "message": "The server is busy. Please try again later." }, "created_at": 1692771347514, "started_at": 1692771347514, "finished_at": 1692771397514 } ``` --- # Pricing Source: https://docs.meshy.ai/api/pricing # Pricing Simple and flexible pricing. --- Meshy API for generation is a pay-before-you-go product. You need to purchase API usage based on your application's need before using Meshy API. You can purchase API usage from the [API settings page](https://www.meshy.ai/settings/api). For volume API pricing and custom contracts, please [contact sales](https://share.hsforms.com/1MiMAkL-dSVejYLqOA4V10grx1uq). The Meshy API pricing is based on credits. Here's a detailed breakdown of the API pricing: | API | Price per call | | --- | --- | | Text to 3D (Preview) - Mesh Generation | Meshy-6 models and low poly models: 20 credits
Other models: 5 credits | | Text to 3D (Refine) - Texture Generation | 10 credits (texture generation) | | Image to 3D | Meshy-6 models and low poly models: 20 credits (without texture), 30 credits (with texture)
Other models: 5 credits (without texture), 15 credits (with texture) | | Multi Image to 3D | Meshy-6 models: 20 credits (without texture), 30 credits (with texture)
Other models: 5 credits (without texture), 15 credits (with texture) | | Retexture | 10 credits (texture generation) | | Remesh | 5 credits | | Auto-Rigging | 5 credits | | Animation | 3 credits | | Text to Image | nano-banana: 3 credits, nano-banana-pro: 9 credits | | Image to Image | nano-banana: 3 credits, nano-banana-pro: 9 credits | | 3D Print (Multi-Color) | 10 credits | The API is subject to change in the future. If you need more API usage with a lower price, please [contact sales by filling out this form](https://www.meshy.ai/contact). --- # Rate Limits Source: https://docs.meshy.ai/api/rate-limits # Rate Limits Rate limits are restrictions that our API imposes on the number of times a user or client can access our services within a specified period of time. --- ## Why Limits We've put rate limits in place on our API to help create the best experience for everyone. Here's why they're important: - To keep our service safe and sound! Think of rate limits as friendly bouncers - they make sure nobody can overwhelm our API with too many requests at once. This helps protect our service from potential misuse and keeps everything running smoothly. - To make sure everyone gets their fair share. Just like sharing toys in a playground, we want to make sure all our users have equal access to the API. By gently limiting how many requests each user can make, we ensure nobody has to wait too long for their turn. - To keep performance zippy and reliable. By managing the overall flow of requests, we can maintain fast response times and stable service for all our wonderful users. It's like making sure a highway doesn't get too crowded - traffic flows better when we prevent congestion! --- ## How Limits Work Rate limits are measured in 2 ways: - **Requests per Second**: This is the number of network requests your can make per second. - **Queue Tasks**: This is the number of concurrent generation tasks your can run in queue at any given time. Queue tasks include Text to 3D, Image to 3D, Text to Texture, and Remesh endpoints. Other endpoints like Upload and Balance are not included in this limit. The limits are applied on a per-account basis. This means that the limits are shared across all of your API keys. Besides rate limits, task processing priority will also affect the speed of your tasks. Each user tier has specific rate limits and priority levels designed to match their needs. Here are the current limits by tier: | User Tier | Requests per Second | Queue Tasks | Priority Level | | --- | --- | --- | --- | | Pro | 20 | 10 | Default | | Studio | 20 | 20 | Higher than Pro | | Enterprise | 100 | Default to 50, can be customized | Highest | If you exceed these limits, you'll receive a `429 Too Many Requests` response from our API. There are two types of hits that can trigger this, each with a different response: - **Request Hit**: This happens when you make too many requests per second. You'll receive a `429 Too Many Requests` response with a `RateLimitExceeded` message. - **Queue Hit**: This happens when you have too many concurrent generation tasks running. You'll receive a `429 Too Many Requests` response with a `NoMoreConcurrentTasks` message. --- # Asset Retention Source: https://docs.meshy.ai/api/asset-retention # Asset Retention Asset Retention is the amount of time that Meshy retains your generated assets. --- Please note that any models generated through our API will only be retained for a maximum of **3 days**. After this period, the models will be automatically deleted from our servers. If you're not an Enterprise customer, we kindly ask for your understanding and recommend downloading and storing your models locally if you need them for a longer duration. Enterprise customers can retain their models indefinitely. --- # Webhooks Source: https://docs.meshy.ai/api/webhooks # Webhooks Webhooks allow you to receive real-time updates from Meshy when your API tasks are completed or change status. Once configured, Meshy will POST event payloads in json format to the URLs you specify. --- ## Why Create Webhooks Using webhooks has several advantages, especially with regards to checking on API task statuses automatically. Webhooks require less effort and costs than continuously polling the API to get task status updates. Webhooks also allow near real-time updates and ultimately scale better than API polling. This also enables you to better manage your rate limits, especially if you are polling constantly. --- ## Setup & Configuration To enable webhooks, navigate to the API settings page when logged in to the Meshy web application. Find the "Webhooks" section below your API Keys and click the "Create Webhook" button. Provide your desired https URL to receive webhooks from and enable the webhook to automatically receive task updates from Meshy. You may have a maximum of 5 active webhooks per Meshy account. When a webhook is enabled, all API task status updates will be automatically sent to the payload URL. For security purposes, we only allow sending webhooks to https URLs at this time. If you would like to configure local testing, see the following section. --- ## Webhook Delivery Requirements For your webhook to function normally and continue receiving events: - Your server must respond with an **HTTP status code below 400** (e.g., `200 OK`, `202 Accepted`). - Any response with a status code `>= 400` will be treated as a failed delivery. - Multiple consecutive failures may: - Cause progress updates to be delayed or arrive out of order - Automatically disable your webhook after repeated attempts (see Auto-Disable Policy) **Tip:** Always return a success response after you validate and store the webhook payload, even if further processing happens asynchronously. --- ## Forwarding Webhooks for Local Testing If you would like to test your webhook code locally, which typically is at an http address, you can use a webhook proxy URL to forward webhooks to your computer or codespace. The below are recommended steps using smee.io, but you may use any service you'd like to generate a webhook proxy URL. ### Get a webhook proxy URL: 1. In your browser, navigate to https://smee.io/ 2. Click "Start a new channel" 3. Copy the full URL under "Webhook Proxy URL". You will use this URL in the following setup steps. ### Forward webhooks: 1. If you don't already have smee-client installed, run the following command in your terminal. ```text npm install --global smee-client ``` 2. To receive forwarded webhooks from smee.io, run the following command in your terminal. Replace `WEBHOOK_PROXY_URL` with your webhook proxy URL from earlier. ```text smee --url WEBHOOK_PROXY_URL --path /webhook --port 3000 ``` You should see output that looks like this, where `WEBHOOK_PROXY_URL` is your webhook proxy URL: ```text Forwarding WEBHOOK_PROXY_URL to http://127.0.0.1:3000/webhook Connected WEBHOOK_PROXY_URL ``` 3. Keep this running while you test out your webhook. When you want to stop forwarding webhooks, enter Ctrl+C. Note that the path is /webhook and the port is 3000. These values may come in handy when you want to set up your own code to receive webhook deliveries later on. ### Create a webhook: You may now use the webhook proxy URL to create a new webhook in the Meshy API settings page. --- ## Sample Response When a task status changes, Meshy will POST a webhook payload to your configured URL. The payload contains the task object in JSON format. For a complete description of all task object properties and example payloads, see: - [Text to 3D Task Object](/api/text-to-3d#example-text-to-3d-task-object) - [Image to 3D Task Object](/api/image-to-3d#example-image-to-3d-task-object) - [Multi-Image to 3D Task Object](/api/multi-image-to-3d#example-multi-image-to-3d-task-object) - [Remesh Task Object](/api/remesh#example-remesh-task-object) - [Retexture Task Object](/api/retexture#example-retexture-task-object) - [Rigging Task Object](/api/rigging#example-rigging-task-object) - [Animation Task Object](/api/animation#example-animation-task-object) --- # AI Integration Source: https://docs.meshy.ai/api/ai # AI Integration Meshy exposes two channels for AI agents and coding assistants: the Meshy MCP server for tool-calling, and `llms.txt` / `llms-full.txt` for docs ingestion. If you are integrating Meshy from Claude Code, Cursor, Windsurf, Codex, or any other MCP-compatible tool, install the MCP server below. If you are integrating from a plain chat agent with no MCP support, point it at [`https://docs.meshy.ai/llms.txt`](/llms.txt) instead. --- ## What is MCP The [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open standard that lets AI assistants call external tools and retrieve structured context. The Meshy MCP server wraps the Meshy REST API as a set of tools your agent can invoke — generate a model, check a task, download the result — without hand-writing HTTP code. The MCP server is open source and published on npm as [`@meshy-ai/meshy-mcp-server`](https://www.npmjs.com/package/@meshy-ai/meshy-mcp-server). Source: [github.com/meshy-dev/meshy-mcp-server](https://github.com/meshy-dev/meshy-mcp-server). > **Note:** You need a Meshy API key. Create one at [https://www.meshy.ai/settings/api](https://www.meshy.ai/settings/api). The MCP server reads it from the `MESHY_API_KEY` environment variable. --- ## Quick Install **add-mcp** ```bash # Detects installed AI clients and configures Meshy for each npx add-mcp meshy -- npx -y @meshy-ai/meshy-mcp-server -e MESHY_API_KEY=msy_YOUR_API_KEY ``` **Claude Code** ```bash claude mcp add meshy -- npx -y @meshy-ai/meshy-mcp-server -e MESHY_API_KEY=msy_YOUR_API_KEY ``` **Cursor** ```json // .cursor/mcp.json { "mcpServers": { "meshy": { "command": "npx", "args": ["-y", "@meshy-ai/meshy-mcp-server"], "env": { "MESHY_API_KEY": "msy_YOUR_API_KEY" } } } } ``` **Windsurf** ```json // ~/.codeium/windsurf/mcp_config.json { "mcpServers": { "meshy": { "command": "npx", "args": ["-y", "@meshy-ai/meshy-mcp-server"], "env": { "MESHY_API_KEY": "msy_YOUR_API_KEY" } } } } ``` **Claude Desktop** ```json // ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) // %APPDATA%\Claude\claude_desktop_config.json (Windows) { "mcpServers": { "meshy": { "command": "npx", "args": ["-y", "@meshy-ai/meshy-mcp-server"], "env": { "MESHY_API_KEY": "msy_YOUR_API_KEY" } } } } ``` **Codex** ```bash codex mcp add meshy -- npx -y @meshy-ai/meshy-mcp-server -e MESHY_API_KEY=msy_YOUR_API_KEY ``` **VS Code** ```json // .vscode/mcp.json (workspace) or User settings > MCP Servers { "servers": { "meshy": { "command": "npx", "args": ["-y", "@meshy-ai/meshy-mcp-server"], "env": { "MESHY_API_KEY": "msy_YOUR_API_KEY" } } } } ``` **Other** ```json // Generic stdio MCP config. Consult your client's docs for the exact file. { "mcpServers": { "meshy": { "command": "npx", "args": ["-y", "@meshy-ai/meshy-mcp-server"], "env": { "MESHY_API_KEY": "msy_YOUR_API_KEY" } } } } ``` --- ## Available Tools The MCP server exposes the Meshy REST API as tools, grouped by capability. ### 3D Generation - `meshy_text_to_3d` — create a 3D model from a text prompt - `meshy_image_to_3d` — create a 3D model from one image - `meshy_multi_image_to_3d` — create a 3D model from multiple images of the same object - `meshy_text_to_3d_refine` — add texture to a preview mesh ### Post-Processing - `meshy_remesh` — change topology and/or polycount of an existing model - `meshy_retexture` — apply a new texture to an existing model - `meshy_rig` — add a skeleton to a 3D humanoid character - `meshy_animate` — apply an animation to a rigged character ### Image Generation - `meshy_text_to_image` — 2D image from text - `meshy_image_to_image` — 2D image from a reference image ### Task Management - `meshy_get_task_status` — check task status and download URLs - `meshy_list_tasks` — list recent tasks, optionally filtered by type/status - `meshy_cancel_task` — cancel a pending or in-progress task - `meshy_download_model` — fetch a completed model file and save locally ### Workspace - `meshy_list_models` — list all models in the authenticated user's workspace ### 3D Printing - `meshy_send_to_slicer` — detect installed slicers and launch the model in one (runs locally on your machine; no Meshy API call) - `meshy_analyze_printability` — **currently returns a manual print-readiness checklist** (wall thickness, overhangs, manifold mesh, etc.). Will be upgraded to automated analysis once the Meshy printability API is available. - `meshy_process_multicolor` — convert a textured model into a multi-color 3MF file for printing ### Account - `meshy_check_balance` — query remaining credits > **Note:** Tool names and behaviors may evolve. The authoritative list lives in the [MCP server source](https://github.com/meshy-dev/meshy-mcp-server/tree/main/src/tools). --- ## Example Prompts Drop these into your MCP-enabled chat as a starting point. ``` Generate a 3D fox from the prompt "a cartoon fox sitting", preview it, then texture it with PBR maps. Download the final GLB to ./outputs. ``` ``` Take the image at https://example.com/sculpture.jpg and convert it into a riggable 3D character. Use `should_remesh: true` and 50k target polycount. ``` ``` What's my current Meshy credit balance? ``` ``` List my last 10 successful text-to-3d tasks and download the top 3 as GLB into ./downloads/. ``` --- ## llms.txt and llms-full.txt If your agent doesn't support MCP, or you want to ingest the Meshy docs into a prompt directly, point it at our plain-text surfaces: - [`llms.txt`](/llms.txt) — compact index + integration instructions (the correct async-polling pattern, auth rules, rate limits, model choice, common mistakes). - [`llms-full.txt`](/llms-full.txt) — every API page concatenated in a single file for single-fetch ingestion. - Per-page Markdown: append `.md` to any endpoint URL. Example: [`https://docs.meshy.ai/api/text-to-3d.md`](/api/text-to-3d.md). All three are regenerated every time the docs site builds, so they never drift from the HTML docs. --- ## FAQ ### Is the MCP server stateless? Yes. Your `MESHY_API_KEY` is used per request and never persisted on the server side. ### Does MCP cost the same as the REST API? Yes — every MCP tool call maps to a single REST call and consumes credits at the exact same rate. See [Pricing](/api/pricing) for the full matrix. ### What are the rate limits? The MCP server shares the same rate-limit plane as the REST API. See [Rate Limits](/api/rate-limits) for per-tier limits. ### What Meshy data can the MCP access? Only what the `MESHY_API_KEY` can access via REST. Scopes and permissions are identical. ### How do I report issues? File an issue at [github.com/meshy-dev/meshy-mcp-server](https://github.com/meshy-dev/meshy-mcp-server/issues). --- # Changelog Source: https://docs.meshy.ai/api/changelog # Changelog See all of the latest features and updates to the Meshy API and plugins. --- ## April 2026 ### `Apr 21` - Added `input_task_id` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) endpoints. Reference a completed Text to Image or Image to Image task's output directly instead of providing `image_url` / `image_urls`. When both are supplied, `input_task_id` takes priority. ### `Apr 20` - Added `hd_texture` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task), and [Retexture](/api/retexture#create-a-retexture-task) endpoints. When enabled, the base color texture is generated at 4K (4096×4096) resolution for higher detail. Only supported for `meshy-6` and `latest`. Defaults to `false`. - The PBR bundle returned when `enable_pbr` is `true` now includes an `emission` map under `texture_urls` for `meshy-6` and `latest` tasks across [Image to 3D](/api/image-to-3d), [Multi-Image to 3D](/api/multi-image-to-3d), [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task), and [Retexture](/api/retexture). No request change is required. ### `Apr 14` - Added `decimation_mode` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task), and [Remesh](/api/remesh#create-a-remesh-task) endpoints. Sets the adaptive decimation polycount level: `1` (ultra), `2` (high), `3` (medium), or `4` (low). ### `Apr 12` - Restructured API documentation: added parameter grouping with dependent fields, inline defaults, required/deprecated badges, expandable sub-navigation, and split Multi-Image, Rigging, and Animation into separate pages. --- ## March 2026 ### `Apr 2` - Added `3mf` format support to `target_formats` parameter across all endpoints ([Image to 3D](/api/image-to-3d), [Text to 3D](/api/text-to-3d), [Remesh](/api/remesh), [Retexture](/api/retexture)). Note: 3MF is opt-in only and must be explicitly requested. - New [Multi-Color Print API](/api/multi-color-print): Convert 3D models to multi-color 3MF format for 3D printing. Supports 1-16 color palettes with configurable precision. 10 credits per task. ### `Mar 20` - Retired the Meshy-4 AI model. All API requests using `meshy-4` are no longer supported. Please migrate to `meshy-6` or `latest`. - Added `auto_size` and `origin_at` parameters to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D](/api/text-to-3d), and [Remesh](/api/remesh#create-a-remesh-task) endpoints. When `auto_size` is enabled, the service uses AI vision to estimate real-world height and resize the model automatically. `origin_at` sets the origin position (`bottom` or `center`). In the Remesh API, `auto_size` is mutually exclusive with `resize_height`. ### `Mar 17` - Added optional `target_formats` parameter to [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D](/api/text-to-3d), and [Retexture](/api/retexture#create-a-retexture-task) endpoints. Specify which 3D formats to generate (e.g., `["glb", "fbx"]`) to reduce task completion time. --- ## February 2026 ### `Feb 28` - Added `remove_lighting` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task), and [Retexture](/api/retexture#create-a-retexture-task) APIs. Removes highlights and shadows from the base color texture for cleaner results under custom lighting. Only supported for `meshy-6` and `latest`. Defaults to `true`. - The [Retexture](/api/retexture#create-a-retexture-task) and [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task) APIs now support `meshy-6` as an `ai_model` value for full Meshy 6 texturing. ### `Feb 25` - Added `image_enhancement` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) APIs for users who want to opt out of input image optimization and preserve the exact appearance of their input. Only supported for `meshy-6` and `latest`. Defaults to `true`. ### `Feb 20` - Added `model_type` parameter to the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) API for generating low-poly meshes optimized for cleaner polygons. --- ## January 2026 ### `Jan 27` - Added detailed [Failure Modes](/api/errors#task-failure) documentation for all API endpoints, including common HTTP error codes (400, 401, 402, 404, 422, 429) and task failure reasons. This helps developers better understand and handle API errors. ### `Jan 26` - The [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) API now supports Meshy-6 for full mesh generation. The `ai_model` parameter now accepts `meshy-6` and `latest` resolves to Meshy 6. ### `Jan 22` - Deprecated `art_style` for the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) API (Meshy-6). The parameter was designed for legacy models (Meshy-4 / Meshy-5) and will be removed in a future release. - Deprecated `enable_pbr` for the [Text to 3D](/api/text-to-3d) and [Image to 3D](/api/image-to-3d) APIs when `ai_model` is `meshy-4`. This parameter will be removed in a future release. - Updated the default value of `should_remesh` parameter for Meshy-6 in the [Text to 3D](/api/text-to-3d) and [Image to 3D](/api/image-to-3d) APIs. The parameter now defaults to `false` for `meshy-6`, and `true` for other models if not specified. ### `Jan 19` - The `latest` option for `ai_model` in the [Text to 3D (Preview)](/api/text-to-3d#create-a-text-to-3d-preview-task) and [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) APIs now resolves to Meshy 6. ### `Jan 12` - Added a new `model_type` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) API for generating low-poly meshes optimized for cleaner polygons. --- ## December 2025 ### `Dec 31` - Launched the [API Playground](https://www.meshy.ai/api-playground), a dedicated space for developers to explore API parameters and test requests directly on the Meshy website. - Introduced the [Text to Image API](/api/text-to-image) and [Image to Image API](/api/image-to-image), enabling AI-powered image generation from text prompts and image editing from reference images. Both APIs support the `nano-banana` and `nano-banana-pro` models, with optional multi-view generation. ### `Dec 22` - The `video_url` field in the [Text to 3D](/api/text-to-3d) API response is now deprecated and will be removed in a future release. ### `Dec 04` - Added a new `pose_mode` parameter to the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task), [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) APIs. This parameter accepts `a-pose`, `t-pose`, or an empty string (default). The `is_a_t_pose` parameter is now deprecated in favor of `pose_mode`. --- ## November 2025 ### `Nov 24` - The [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) APIs add an optional `save_pre_remeshed_model` parameter and expose `model_urls.pre_remeshed_glb` when a pre-remesh backup is requested. ### `Nov 06` - The [Text to 3D Refine API](/api/text-to-3d#create-a-text-to-3d-refine-task) now supports `ai_model = latest`, which resolves to Meshy 6 Preview. - The [Image to 3D API](/api/image-to-3d#create-an-image-to-3d-task) now defaults to Meshy-6-preview texturing when `ai_model = latest` and `should_texture = true`. - The [Multi-Image to 3D API](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) now supports `ai_model = latest`, running Meshy-6-preview for texturing by default while mesh generation remains Meshy-5. - The [Retexture API](/api/retexture) adds a `latest` option for `ai_model` (Meshy-6-preview) and now defaults to it when omitted. ### `Nov 04` - The [Remesh API](/api/remesh#create-a-remesh-task) now preserves textures for uploaded models. - The [Retexture API](/api/retexture) now preserves textures for uploaded models when the `enable_original_uv` option is enabled. --- ## October 2025 ### `Oct 28` - Added the `x-api-version` response header to indicate the current API server version. ### `Oct 20` - Added an optional `convert_format_only` boolean parameter to the [Remesh API](/api/remesh#create-a-remesh-task) to support converting the format of the input model file only. - Added `rigged_character_glb_url` to the response of [The Rigging Task Object](/api/rigging#the-rigging-task-object). ### `Oct 01` - Remove `text-to-voxel` APIs --- ## September 2025 ### `Sep 23` - Added a `latest` option for `ai_model` in the [Text to 3D](/api/text-to-3d#create-a-text-to-3d-preview-task) API to use Meshy 6 Preview. - Temporary 50% discount in place for Meshy-6-preview generation tasks to 10 credits that will last until Sep 30, 2025. After the discount period, the cost of Meshy-6-preview tasks will return to the normal 20 credits. ### `Sep 18` - Updated [API pricing](/api/pricing) for [Text to 3D](/api/text-to-3d) and [Image to 3D](/api/image-to-3d) to reflect different costs for Meshy 6 and other models. ### `Sep 16` - Added a `latest` option for `ai_model` in the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) API to use Meshy 6 Preview. ### `Sep 4` - Expanded `model_url` input support to `.glb`, `.gltf`, `.obj`, `.fbx`, `.stl` for [Remesh](/api/remesh#create-a-remesh-task) and [Retexture](/api/retexture). --- ## August 2025 ### `Aug 18` - Added an optional `is_a_t_pose` parameter to the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task), [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) APIs to generate models in an A/T pose. ### `Aug 13` - Meshy 5 is now stable for [Text to 3D](/api/text-to-3d) and [Image to 3D](/api/image-to-3d) (`ai_model`: `meshy-5`), delivering improved quality and consistency. --- ## July 2025 ### `Jul 31` - Support PBR texture maps in API via `enable_pbr` parameter for latest `meshy-5` model for [Text to 3D](/api/text-to-3d), [Image to 3D](/api/image-to-3d), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), and [Retexture](/api/retexture) endpoints. --- ## June 2025 ### `Jun 25 ` - Added the [Retexture API](/api/retexture), which allows users to retexture 3D models based on Meshy's latest foundation AI models. ### `Jun 19` - Added deletion APIs for [Text to 3D](/api/text-to-3d), [Image to 3D](/api/image-to-3d), [Remesh](/api/remesh), [Rigging](/api/rigging), and [Animation](/api/animation). - Added the `ai_model` parameter to the [Text to 3D Refine API](/api/text-to-3d#create-a-text-to-3d-refine-task). ### `Jun 17` - Added documentation for [Webhooks](/api/webhooks). ### `Jun 10` - The [Remesh API](/api/remesh#create-a-remesh-task) now supports base64-encoded GLB format models in the `model_url` parameter via Data URI. --- ## May 2025 ### `May 20` - Added an optional `moderation` parameter to the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task), [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task), [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task), and [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task) APIs. When enabled, input content is automatically screened for potentially harmful content before generation. ### `May 15` - Introduced the Auto-rigging & Animation API, enabling users to automatically rig and animate 3D models. [Learn more about Rigging](/api/rigging) and [Animation](/api/animation). --- ## April 2025 ### `Apr 29` - Introduced the [Multi-Image to 3D API](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), allowing generation of 3D models from 1 to 4 input images using the `meshy-5` AI model. - Added the `meshy-5` AI model option to the [Text to 3D](/api/text-to-3d) and [Image to 3D](/api/image-to-3d) APIs. The `latest` tag now also resolves to `meshy-5`. ### `Apr 17` - Added the `texture_image_url` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task) APIs, allowing users to guide the texture generation process with an image. --- ## March 2025 ### `Mar 28` - Added the `latest` parameter to the [Text to 3D](/api/text-to-3d##create-a-text-to-3d-preview-task) and [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) APIs, enabling access to our upcoming advanced AI models for improved generation quality. ### `Mar 14` - The [Text to Texture API](/api/text-to-texture#create-a-text-to-texture-task) now supports base64-encoded models in the `model_url` parameter via Data URI, similar to the `image_url` in the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) API. ### `Mar 06` - Updated pricing for API generation tasks: - Text to 3D (Preview): Increased from 2 to 5 credits per call - Text to 3D (Refine): Increased from 5 to 10 credits per call - Image to 3D: Now 5 credits without texture, 15 credits with texture - Text to Texture: Increased from 5 to 10 credits per call - Text to Voxel: Remains at 5 credits per call --- ## February 2025 ### `Feb 18` - Added a test mode API key `msy_dummy_api_key_for_test_mode_12345678` that allows developers to test API integration without consuming credits. All valid requests using this key will return the same sample task results. ### `Feb 13` - **Breaking Changes**: - Free tier task creation will end on `March 20, 2025`. After that, all API task requests will require a paid subscription. To keep your access smooth, we recommend upgrading before the deadline. - Use coupon code `APIACCESS` to enjoy a `40%` discount. Thank you for being with us! - Added Server-Sent Events (SSE) streaming endpoints for real-time task updates: - [Text to 3D Stream API](/api/text-to-3d#stream-a-text-to-3d-task) - [Image to 3D Stream API](/api/image-to-3d#stream-an-image-to-3d-task) - [Remesh Stream API](/api/remesh#stream-a-remesh-task) - [Text to Texture Stream API](/api/text-to-texture#stream-a-text-to-texture-task) ### `Feb 6` - Added the `texture_prompt` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task) APIs, allowing users to guide the texture generation process with a text prompt. --- ## January 2025 ### `Jan 23` - Added endpoints for listing tasks to the [Text to 3D](/api/text-to-3d#list-text-to-3d-tasks), [Image to 3D](/api/image-to-3d#list-image-to-3d-tasks), [Remesh](/api/remesh#list-remesh-tasks) and [Text to Texture](/api/text-to-texture#list-text-to-texture-tasks) APIs. ### `Jan 14` - Deprecated the legacy Text to 3D and Image to 3D APIs powered by Meshy-3 AI models. ### `Jan 07` - Added the `symmetry_mode` parameter to the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) and [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) APIs, allowing for configurable symmetry settings. --- ## December 2024 ### `Dec 19` - Added the [Remesh APIs](/api/remesh), which allow users to remesh and export existing 3D models generated by other Meshy APIs into various formats. - Updated the polycount limits for our APIs to a range of 100-300,000 for Premium users. ### `Dec 12` - Deprecated the `model_url` property in all response objects. - Separated legacy Meshy-3 API from the latest Meshy-4 API. ### `Dec 10` - Added an `enable_pbr` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Text to 3D Refine](/api/text-to-3d#create-a-text-to-3d-refine-task) APIs. - Added a `should_texture` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) API. - Deprecated the `pbr` option in `art_style` parameter for the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) API when using the `meshy-4` AI model. - Deprecated the `low-poly` option in `art_style` parameter for the [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) API. ### `Dec 5` - Added a [Get Balance API](/api/balance) to allow users to retrieve their credit balance. - Added a `should_remesh` parameter to the [Image to 3D](/api/image-to-3d#create-an-image-to-3d-task) and [Text to 3D Preview](/api/text-to-3d#create-a-text-to-3d-preview-task) APIs. ### `Dec 3` - External APIs now use the `/openapi` prefix. Legacy paths remain supported, but we recommend switching to the new paths. --- ## November 2024 ### `Nov 14` - The [Image to 3D API](/api/image-to-3d#create-an-image-to-3d-task) now supports base64-encoded images. --- --- # Text to 3D API Source: https://docs.meshy.ai/api/text-to-3d # Text to 3D API Text to 3D API is a feature that allows you to integrate Meshy's Text to 3D capabilities into your own application. In this section, you'll find all the information you need to get started with this API. The workflow of Text to 3D involves two stages: the preview stage and the refine stage. In the preview stage, a base mesh is generated with no texture applied, allowing you to evaluate the geometry. In the refine stage, the preview mesh is textured based on the text prompt. --- ## POST /openapi/v2/text-to-3d -- Create a Text to 3D Preview Task This endpoint allows you to create a new Text to 3D Preview task. Refer to [The Text to 3D Task Object](#the-text-to-3d-task-object) to see which properties are included with Text to 3D task object. ### Parameters - `mode` · *string* · **required** This field should be set to "preview" when creating a preview task. - `prompt` · *string* · **required** Describe what kind of object the 3D model is. Maximum 600 characters. - `model_type` · *string* · default: `standard` Specify the type of 3D mesh generation. Available values: * `standard`: Regular high-detail 3D mesh generation. * `lowpoly`: Generates low-poly mesh optimized for cleaner polygons. > **Note:** When `lowpoly` is selected, `ai_model`, `topology`, `target_polycount`, `should_remesh` are ignored. - `ai_model` · *string* · default: `latest` ID of the model to use. Available values: `meshy-5`, `meshy-6`, `latest` (Meshy 6). - `should_remesh` · *boolean* · default: `false (meshy-6), true (others)` Controls whether to enable the remesh phase. When set to `false`, the API will directly return the highest-precision triangular mesh. **Only when `should_remesh` is set:** - `topology` · *string* · default: `triangle` Specify the topology of the generated model. Available values: * `quad`: Generate a quad-dominant mesh. * `triangle`: Generate a decimated triangle mesh. - `target_polycount` · *integer* · default: `30,000` Specify the target number of polygons in the generated model. The actual number of polygons may deviate from the target depending on the complexity of the geometry. The valid value range varies depending on the user tier: * 100 to 300,000 (inclusive) - `decimation_mode` · *integer* Enable adaptive decimation by setting a polycount level. When set, `target_polycount` is ignored. Available values: * `1`: Adaptive — ultra polycount. * `2`: Adaptive — high polycount. * `3`: Adaptive — medium polycount. * `4`: Adaptive — low polycount. - `symmetry_mode` · *string* · default: `auto` The `symmetry_mode` field controls symmetry behavior during the model generation process. The valid values are: * `off`: Disables symmetry. * `auto`: Automatically determines and applies symmetry based on input geometry. * `on`: Enforces symmetry during generation. - `pose_mode` · *string* · default: `""` Specify the pose mode for the generated model. Available values: * `a-pose`: Generate the model in an A pose. * `t-pose`: Generate the model in a T pose. * `""` (empty string): No specific pose applied. - `is_a_t_pose` · *boolean* · default: `false` · **deprecated** Use `pose_mode` instead. Whether to generate the model in an A/T pose. - `art_style` · *string* · default: `realistic` · **deprecated** Not supported by Meshy-6. Requests using Meshy-6 will ignore `art_style`, and some combinations may cause errors. Available values: `realistic`, `sculpture`. > **Note:** `enable_pbr` should be set to `false` when using Sculpture style, as Sculpture style generates its own set of PBR maps. - `moderation` · *boolean* · default: `false` When set to `true`, the input content will automatically be screened for potentially harmful content. If harmful content is detected, the task will not proceed to generation. The text from `prompt` will be screened. - `target_formats` · *string[]* Specifies which 3D file formats to include in the output. Only the requested formats will be generated and returned, which can reduce task completion time. When omitted, all supported formats are included. Available values: `glb`, `obj`, `fbx`, `stl`, `usdz`, `3mf` > **Note:** When omitted, all formats except `3mf` are generated. `3mf` is only included when explicitly specified. - `auto_size` · *boolean* · default: `false` When set to `true`, the service uses AI vision to automatically estimate the real-world height of the object and resize the model accordingly. The origin will default to `bottom` unless `origin_at` is explicitly set. **Only when `auto_size` is set:** - `origin_at` · *string* · default: `bottom` Position of the origin when `auto_size` is enabled. Available values: `bottom`, `center`. ### Returns The `result` property of the response contains the task `id` of the newly created Text to 3D task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: A required parameter (e.g., `prompt`, `mode`) is missing. * **Invalid parameter**: `art_style` is not one of the allowed values. * **Prompt too long**: The `prompt` exceeds the character limit. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Simple preview with required params only curl https://api.meshy.ai/openapi/v2/text-to-3d \ -H 'Authorization: Bearer ${YOUR_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "mode": "preview", "prompt": "a monster mask" }' # Preview with remesh and A-pose curl https://api.meshy.ai/openapi/v2/text-to-3d \ -H 'Authorization: Bearer ${YOUR_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "mode": "preview", "prompt": "a futuristic robot warrior", "should_remesh": true, "target_polycount": 100000, "pose_mode": "a-pose", "target_formats": ["glb"] }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Simple preview with required params only const payload = { mode: 'preview', prompt: 'a monster mask', }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v2/text-to-3d', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // Preview with remesh and A-pose const advancedPayload = { mode: 'preview', prompt: 'a futuristic robot warrior', should_remesh: true, target_polycount: 100000, pose_mode: 'a-pose', target_formats: ['glb'], }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v2/text-to-3d', advancedPayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Simple preview with required params only payload = { "mode": "preview", "prompt": "a monster mask", } response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # Preview with remesh and A-pose advanced_payload = { "mode": "preview", "prompt": "a futuristic robot warrior", "should_remesh": True, "target_polycount": 100000, "pose_mode": "a-pose", "target_formats": ["glb"], } response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=advanced_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## POST /openapi/v2/text-to-3d -- Create a Text to 3D Refine Task This endpoint allows you to create a new Text to 3D Refine task. ### Parameters - `mode` · *string* · **required** This field should be set to "refine" when creating a refine task. - `preview_task_id` · *string* · **required** The corresponding preview task id. The status of the given preview task must be `SUCCEEDED`. - `enable_pbr` · *boolean* · default: `false` Generate PBR Maps (metallic, roughness, normal) in addition to the base color. An emission map is also included when `ai_model` is `meshy-6` or `latest`. - `hd_texture` · *boolean* · default: `false` Generate the base color texture at 4K (4096×4096) resolution for higher detail. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. PBR maps are always generated at 2K. - `texture_prompt` · *string* Provide an additional text prompt to guide the texturing process. Maximum 600 characters. - `texture_image_url` · *string* Provide a 2d image to guide the texturing process. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide the image: - **Publicly accessible URL**: A URL that is accessible from the public internet - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,` > **Note:** Image texturing may not work optimally if there are substantial geometry differences between the original asset and uploaded image. Only one of `texture_image_url` or `texture_prompt` may be used to guide the texturing process. If both parameters are provided, then `texture_prompt` will be used to texture the model by default. - `ai_model` · *string* · default: `latest` ID of the model to use for refining. Available values: `meshy-5`, `meshy-6`, `latest` (Meshy 6). - `moderation` · *boolean* · default: `false` When set to `true`, the input content will automatically be screened for potentially harmful content. If harmful content is detected, the task will not proceed to generation. Both the text from `texture_prompt` and the image from `texture_image_url` will be screened. - `remove_lighting` · *boolean* · default: `true` Removes highlights and shadows from the base color texture, producing a cleaner result that works better under custom lighting setups. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `target_formats` · *string[]* Specifies which 3D file formats to include in the output. Only the requested formats will be generated and returned, which can reduce task completion time. When omitted, all supported formats are included. Available values: `glb`, `obj`, `fbx`, `stl`, `usdz`, `3mf` > **Note:** When omitted, all formats except `3mf` are generated. `3mf` is only included when explicitly specified. - `auto_size` · *boolean* · default: `false` When set to `true`, the service uses AI vision to automatically estimate the real-world height of the object and resize the model accordingly. The origin will default to `bottom` unless `origin_at` is explicitly set. **Only when `auto_size` is set:** - `origin_at` · *string* · default: `bottom` Position of the origin when `auto_size` is enabled. Available values: `bottom`, `center`. ### Returns The `result` property of the response contains the task `id` of the newly created Text to 3D task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Invalid task ID**: The `preview_task_id` is invalid or does not exist. * **Task not ready**: The preview task has not succeeded yet. * **Model mismatch**: The preview task's AI model is incompatible with the requested refine model. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `404 - Not Found` The preview task specified by `preview_task_id` was not found. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Basic refine task curl https://api.meshy.ai/openapi/v2/text-to-3d \ -H 'Authorization: Bearer ${YOUR_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "mode": "refine", "preview_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "enable_pbr": true }' # Refine with auto-size and GLB format curl https://api.meshy.ai/openapi/v2/text-to-3d \ -H 'Authorization: Bearer ${YOUR_API_KEY}' \ -H 'Content-Type: application/json' \ -d '{ "mode": "refine", "preview_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb"], "auto_size": true }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Basic refine task const payload = { mode: 'refine', preview_task_id: '018a210d-8ba4-705c-b111-1f1776f7f578', enable_pbr: true, }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v2/text-to-3d', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // Refine with auto-size and GLB format const advancedPayload = { mode: 'refine', preview_task_id: '018a210d-8ba4-705c-b111-1f1776f7f578', target_formats: ['glb'], auto_size: true, }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v2/text-to-3d', advancedPayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Basic refine task payload = { "mode": "refine", "preview_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "enable_pbr": True, } response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # Refine with auto-size and GLB format advanced_payload = { "mode": "refine", "preview_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb"], "auto_size": True, } response = requests.post( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, json=advanced_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v2/text-to-3d/:id -- Retrieve a Text to 3D Task This endpoint allows you to retrieve a Text to 3D task given a valid task `id`. Refer to [The Text to 3D Task Object](#the-text-to-3d-task-object) to see which properties are included with Text to 3D task object. This endpoint works for both preview and refine tasks. ### Parameters - `id` · *path* Unique identifier for the Text to 3D task to retrieve. ### Returns The response contains the Text to 3D task object. Check [The Text to 3D Task Object](#the-text-to-3d-task-object) section for details. ### Examples
Mode Sample Model
Preview Preview model
Refine Refined model
**cURL** ```bash curl https://api.meshy.ai/openapi/v2/text-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v2/text-to-3d/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v2/text-to-3d/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-3d-preview", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "mtl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.mtl?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "prompt": "a monster mask", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## DELETE /openapi/v2/text-to-3d/:id -- Delete a Text to 3D Task This endpoint permanently deletes a Text to 3D task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the Text to 3D task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v2/text-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v2/text-to-3d/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v2/text-to-3d/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v2/text-to-3d -- List Text to 3D Tasks This endpoint allows you to retrieve a list of Text to 3D tasks. ### Parameters - `page_num` · *integer* · default: `1` Page number for pagination. - `page_size` · *integer* · default: `10` Page size limit. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Text to 3D Task Objects](#the-text-to-3d-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v2/text-to-3d?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v2/text-to-3d?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v2/text-to-3d", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-3d-preview", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "mtl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.mtl?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "prompt": "a monster mask", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ] ``` --- ## GET /openapi/v2/text-to-3d/:id/stream -- Stream a Text to 3D Task This endpoint streams real-time updates for a Text to 3D task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Text to 3D task to stream. ### Returns Returns a stream of [The Text to 3D Task Objects](#the-text-to-3d-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v2/text-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v2/text-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v2/text-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 50, "status": "IN_PROGRESS" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-3d-preview", "progress": 100, "status": "SUCCEEDED", "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***" }, "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## The Text to 3D Task Object The Text to 3D Task object is a work unit that Meshy keeps track of to generate a 3D model from a **text** input. There are two stages of the Text to 3D API, `preview` and `refine`. Preview stage is for generating a mesh-only 3D model, and refine stage is for generating a textured 3D model based on the preview stage's result. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the Text to 3D task. Possible values are `text-to-3d-preview` for preview stage tasks and `text-to-3d-refine` for refine stage tasks. - `model_urls` · *object* Downloadable URL to the textured 3D model file generated by Meshy. The property for a format will be omitted if the format is not generated instead of returning an empty string. - `glb` · *string* Downloadable URL to the GLB file. - `fbx` · *string* Downloadable URL to the FBX file. - `usdz` · *string* Downloadable URL to the USDZ file. - `obj` · *string* Downloadable URL to the OBJ file. - `mtl` · *string* Downloadable URL to the MTL file. - `stl` · *string* Downloadable URL to the STL file. - `3mf` · *string* Downloadable URL to the 3MF file. Only present when `3mf` was requested via `target_formats`. - `prompt` · *string* This is unmodified `prompt` that was used to create the task. - `negative_prompt` · *string* · **deprecated** Maintained for backward compatibility. This field has no functional impact on generated models. - `art_style` · *string* · **deprecated** The unmodified `art_style` that was used to create the preview task. Not supported by Meshy-6. - `texture_richness` · *string* · **deprecated** Maintained for backward compatibility. This field has no functional impact on generated models. - `texture_prompt` · *string* Additional text prompt provided to guide the texturing process during the refine stage. - `texture_image_url` · *string* Downloadable URL to the texture image that was used to guide the texturing process. - `thumbnail_url` · *string* Downloadable URL to the thumbnail image of the model file. - `video_url` · *string* · **deprecated** Downloadable URL to the preview video. Will be removed in a future release. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `texture_urls` · *array* An array of texture URL objects that are generated from the task. Normally this only contains **one** texture URL object. Each texture URL has the following properties: - `base_color` · *string* Downloadable URL to the base color map image. - `metallic` · *string* Downloadable URL to the metallic map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `normal` · *string* Downloadable URL to the normal map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `roughness` · *string* Downloadable URL to the roughness map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `emission` · *string* Downloadable URL to the emission map image. > **Note:** If the task is created with `enable_pbr: false`, or `ai_model` is `meshy-5`, this property will be omitted. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Text to 3D Task Object** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-3d-preview", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "mtl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.mtl?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***" }, "prompt": "a monster mask", "texture_prompt": "green slimy skin with scales and warts", "texture_image_url": "", "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "progress": 100, "seed": 1234, "started_at": 1692771667037, "created_at": 1692771650657, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- # Image to 3D API Source: https://docs.meshy.ai/api/image-to-3d # Image to 3D API Image to 3D API is a feature that allows you to integrate Meshy's Image to 3D capabilities into your own application. In this section, you'll find all the information you need to get started with this API. --- ## POST /openapi/v1/image-to-3d -- Create an Image to 3D Task This endpoint allows you to create a new Image to 3D task. Refer to [The Image to 3D Task Object](#the-image-to-3d-task-object) to see which properties are included with Image to 3D task object. ### Parameters > **Note:** Only one of `input_task_id` or `image_url` is **required**. If both are provided, `input_task_id` takes priority. - `input_task_id` · *string* · **required** The ID of a completed image-generation task whose output should be used as the input image. This task must be one of the following tasks: Text to Image or Image to Image. In addition, it must have been run via the API, have a status of `SUCCEEDED`, and produce exactly one image. - `image_url` · *string* · **required** Provide an image for Meshy to use in model creation. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide the image: - **Publicly accessible URL**: A URL that is accessible from the public internet. - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,`. - `model_type` · *string* · default: `standard` Specify the type of 3D mesh generation. Available values: * `standard`: Regular high-detail 3D mesh generation. * `lowpoly`: Generates low-poly mesh optimized for cleaner polygons. > **Note:** When `lowpoly` is selected, `ai_model`, `topology`, `target_polycount`, `should_remesh`, `save_pre_remeshed_model` are ignored. - `ai_model` · *string* · default: `latest` ID of the model to use. Available values: `meshy-5`, `meshy-6`, `latest` (Meshy 6). - `should_texture` · *boolean* · default: `true` Determines if textures are generated. Setting it to `false` skips the texture phase, providing a mesh without textures. **Only when `should_texture` is set:** - `enable_pbr` · *boolean* · default: `false` Generate PBR Maps (metallic, roughness, normal) in addition to the base color. An emission map is also included when `ai_model` is `meshy-6` or `latest`. - `hd_texture` · *boolean* · default: `false` Generate the base color texture at 4K (4096×4096) resolution for higher detail. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. PBR maps are always generated at 2K. - `texture_prompt` · *string* Provide a text prompt to guide the texturing process. Maximum 600 characters. - `texture_image_url` · *string* Provide a 2d image to guide the texturing process. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide the image: - **Publicly accessible URL**: A URL that is accessible from the public internet - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,` > **Note:** Image texturing may not work optimally if there are substantial geometry differences between the original asset and uploaded image. Only one of `texture_image_url` or `texture_prompt` may be used to guide the texturing process. If both parameters are provided, then `texture_prompt` will be used to texture the model by default. Texturing via either text or image will cost 10 credits per task. - `should_remesh` · *boolean* · default: `false (meshy-6), true (others)` Controls whether to enable the remesh phase. When set to `false`, the API returns the highest-precision triangular mesh. **Only when `should_remesh` is set:** - `topology` · *string* · default: `triangle` Specify the topology of the generated model. Available values: * `quad`: Generate a quad-dominant mesh. * `triangle`: Generate a decimated triangle mesh. - `target_polycount` · *integer* · default: `30,000` Specify the target number of polygons in the generated model. The actual number of polygons may deviate from the target depending on the complexity of the geometry. The valid value range varies depending on the user tier: * 100 to 300,000 (inclusive) - `decimation_mode` · *integer* Enable adaptive decimation by setting a polycount level. When set, `target_polycount` is ignored. Available values: * `1`: Adaptive — ultra polycount. * `2`: Adaptive — high polycount. * `3`: Adaptive — medium polycount. * `4`: Adaptive — low polycount. - `save_pre_remeshed_model` · *boolean* · default: `false` When set to `true`, Meshy also stores an extra GLB file before the remesh phase completes. - `symmetry_mode` · *string* · default: `auto` The `symmetry_mode` field controls symmetry behavior during the model generation process. The valid values are: * `off`: Disables symmetry. * `auto`: Automatically determines and applies symmetry based on input geometry. * `on`: Enforces symmetry during generation. - `pose_mode` · *string* · default: `""` Specify the pose mode for the generated model. Available values: * `a-pose`: Generate the model in an A pose. * `t-pose`: Generate the model in a T pose. * `""` (empty string): No specific pose applied. - `is_a_t_pose` · *boolean* · default: `false` · **deprecated** Use `pose_mode` instead. Whether to generate the model in an A/T pose. - `image_enhancement` · *boolean* · default: `true` Optimizes the input image for better results. Set to `false` to preserve the exact appearance of the input image without any style processing. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `remove_lighting` · *boolean* · default: `true` Removes highlights and shadows from the base color texture, producing a cleaner result that works better under custom lighting setups. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `moderation` · *boolean* · default: `false` When set to `true`, the input content will automatically be screened for potentially harmful content. If harmful content is detected, the task will not proceed to generation. The content from the `image_url`, `texture_image_url`, and `texture_prompt` inputs will be screened. - `target_formats` · *string[]* Specifies which 3D file formats to include in the output. Only the requested formats will be generated and returned, which can reduce task completion time. When omitted, all supported formats are included. Available values: `glb`, `obj`, `fbx`, `stl`, `usdz`, `3mf` > **Note:** When omitted, all formats except `3mf` are generated. `3mf` is only included when explicitly specified. - `auto_size` · *boolean* · default: `false` When set to `true`, the service uses AI vision to automatically estimate the real-world height of the object and resize the model accordingly. The origin will default to `bottom` unless `origin_at` is explicitly set. **Only when `auto_size` is set:** - `origin_at` · *string* · default: `bottom` Position of the origin when `auto_size` is enabled. Available values: `bottom`, `center`. ### Returns The `result` property of the response contains the task `id` of the newly created Image to 3D task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: Either `image_url` or `input_task_id` must be provided. * **Invalid input task**: The `input_task_id` must refer to a `SUCCEEDED` Text to Image or Image to Image task that produces exactly one image. * **Invalid image format**: The provided `image_url` is not a supported format (.jpg, .jpeg, .png). * **Unreachable URL**: The `image_url` could not be downloaded (404 or timeout). * **Invalid Data URI**: The base64 string is malformed. * **Invalid parameter combination**: `enable_pbr` is only supported when `should_texture` is true. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Simple request with required params curl https://api.meshy.ai/openapi/v1/image-to-3d \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "image_url": "" }' # With remesh, PBR, and A-pose curl https://api.meshy.ai/openapi/v1/image-to-3d \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "image_url": "", "enable_pbr": true, "should_remesh": true, "target_polycount": 100000, "should_texture": true, "pose_mode": "a-pose", "target_formats": ["glb"] }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Simple request with required params const payload = { image_url: "", }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/image-to-3d', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // With remesh, PBR, and A-pose const advancedPayload = { image_url: "", enable_pbr: true, should_remesh: true, target_polycount: 100000, should_texture: true, pose_mode: "a-pose", target_formats: ["glb"], }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/image-to-3d', advancedPayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Simple request with required params payload = { "image_url": "", } response = requests.post( "https://api.meshy.ai/openapi/v1/image-to-3d", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # With remesh, PBR, and A-pose advanced_payload = { "image_url": "", "enable_pbr": True, "should_remesh": True, "target_polycount": 100000, "should_texture": True, "pose_mode": "a-pose", "target_formats": ["glb"], } response = requests.post( "https://api.meshy.ai/openapi/v1/image-to-3d", headers=headers, json=advanced_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v1/image-to-3d/:id -- Retrieve an Image to 3D Task This endpoint allows you to retrieve an Image to 3D task given a valid task `id`. Refer to [The Image to 3D Task Object](#the-image-to-3d-task-object) to see which properties are included with Image to 3D task object. ### Parameters - `id` · *path* Unique identifier for the Image to 3D task to retrieve. ### Returns The response contains the Image to 3D task object. Check [The Image to 3D Task Object](#the-image-to-3d-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/image-to-3d/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/image-to-3d/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## DELETE /openapi/v1/image-to-3d/:id -- Delete an Image to 3D Task This endpoint permanently deletes an Image to 3D task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the Image to 3D task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/image-to-3d/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/image-to-3d/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/image-to-3d -- List Image to 3D Tasks This endpoint allows you to retrieve a list of Image to 3D tasks. ### Parameters #### Optional attributes - `page_num` · *integer* Page number for pagination. Starts and defaults to `1`. - `page_size` · *integer* Page size limit. Defaults to `10` items. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Image to 3D Task Objects](#the-image-to-3d-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/image-to-3d?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/image-to-3d?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/image-to-3d", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ] ``` --- ## GET /openapi/v1/image-to-3d/:id/stream -- Stream an Image to 3D Task This endpoint streams real-time updates for an Image to 3D task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Image to 3D task to stream. ### Returns Returns a stream of [The Image to 3D Task Objects](#the-image-to-3d-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## The Image to 3D Task Object The Image to 3D Task object is a work unit that Meshy keeps track of to generate a 3D model from an **image** input. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the Image to 3D task. The value is `image-to-3d`. - `model_urls` · *object* Downloadable URL to the textured 3D model file generated by Meshy. The property for a format will be omitted if the format is not generated instead of returning an empty string. - `glb` · *string* Downloadable URL to the GLB file. - `fbx` · *string* Downloadable URL to the FBX file. - `obj` · *string* Downloadable URL to the OBJ file. - `usdz` · *string* Downloadable URL to the USDZ file. - `mtl` · *string* Downloadable URL to the MTL file, returned alongside OBJ exports when textures are present. - `stl` · *string* Downloadable URL to the STL file. - `3mf` · *string* Downloadable URL to the 3MF file. Only present when `3mf` was requested via `target_formats`. - `pre_remeshed_glb` · *string* Downloadable URL to the original GLB output before remeshing. > **Note:** Available only when the task was created with both `should_remesh: true` and `save_pre_remeshed_model: true`. - `thumbnail_url` · *string* Downloadable URL to the thumbnail image of the model file. - `texture_prompt` · *string* The text prompt that was used to guide the texturing process. - `texture_image_url` · *string* Downloadable URL to the texture image that was used to guide the texturing process. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `expires_at` · *timestamp* Timestamp of when the task result expires, in milliseconds. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `texture_urls` · *array* An array of texture URL objects that are generated from the task. Normally this only contains **one** texture URL object. Each texture URL has the following properties: - `base_color` · *string* Downloadable URL to the base color map image. - `metallic` · *string* Downloadable URL to the metallic map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `normal` · *string* Downloadable URL to the normal map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `roughness` · *string* Downloadable URL to the roughness map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `emission` · *string* Downloadable URL to the emission map image. > **Note:** If the task is created with `enable_pbr: false`, or `ai_model` is `meshy-5`, this property will be omitted. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Image to 3D Task Object** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "texture_image_url": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" }, } ``` --- # Multi-Image to 3D API Source: https://docs.meshy.ai/api/multi-image-to-3d # Multi-Image to 3D API Multi-Image to 3D API is a feature that allows you to integrate Meshy's Multi-Image to 3D capabilities into your own application. In this section, you'll find all the information you need to get started with this API. --- ## POST /openapi/v1/multi-image-to-3d -- Create a Multi-Image to 3D Task This endpoint allows you to create a new Multi-Image to 3D task. Refer to [The Multi-Image to 3D Task Object](#the-multi-image-to-3d-task-object) to see which properties are included with Multi-Image to 3D task object. ### Parameters > **Note:** Only one of `input_task_id` or `image_urls` is **required**. If both are provided, `input_task_id` takes priority. - `input_task_id` · *string* · **required** The ID of a completed image-generation task whose output (1-4 images) should be used as the input. This task must be one of the following tasks: Text to Image, Image to Image, Text to Image Multi-View, or Image to Image Multi-View. In addition, it must have been run via the API and have a status of `SUCCEEDED`. - `image_urls` · *array* · **required** Provide 1 to 4 images for Meshy to use in model creation. We currently support `.jpg`, `.jpeg`, and `.png` formats. All images should depict the same object from different angles for best results. There are two ways to provide each image: - **Publicly accessible URL**: A URL that is accessible from the public internet. - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,`. - `ai_model` · *string* · default: `latest` ID of the model to use. Available values: `meshy-5`, `meshy-6`, `latest` (Meshy 6). - `should_texture` · *boolean* · default: `true` Determines if textures are generated. Setting it to `false` skips the texture phase, providing a mesh without textures. **Only when `should_texture` is set:** - `enable_pbr` · *boolean* · default: `false` Generate PBR Maps (metallic, roughness, normal) in addition to the base color. An emission map is also included when `ai_model` is `meshy-6` or `latest`. - `hd_texture` · *boolean* · default: `false` Generate the base color texture at 4K (4096×4096) resolution for higher detail. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. PBR maps are always generated at 2K. - `texture_prompt` · *string* Provide a text prompt to guide the texturing process. Maximum 600 characters. - `texture_image_url` · *string* Provide a 2d image to guide the texturing process. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide the image: - **Publicly accessible URL**: A URL that is accessible from the public internet - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,` > **Note:** Image texturing may not work optimally if there are substantial geometry differences between the original asset and uploaded image. Only one of `texture_image_url` or `texture_prompt` may be used to guide the texturing process. If both parameters are provided, then `texture_prompt` will be used to texture the model by default. - `should_remesh` · *boolean* · default: `false (meshy-6), true (others)` Controls whether to enable the remesh phase. When set to `false`, the API returns the highest-precision triangular mesh. **Only when `should_remesh` is set:** - `topology` · *string* · default: `triangle` Specify the topology of the generated model. Available values: * `quad`: Generate a quad-dominant mesh. * `triangle`: Generate a decimated triangle mesh. - `target_polycount` · *integer* · default: `30,000` Specify the target number of polygons in the generated model. The actual number of polygons may deviate from the target depending on the complexity of the geometry. The valid value range varies depending on the user tier: * 100 to 300,000 (inclusive) - `decimation_mode` · *integer* Enable adaptive decimation by setting a polycount level. When set, `target_polycount` is ignored. Available values: * `1`: Adaptive — ultra polycount. * `2`: Adaptive — high polycount. * `3`: Adaptive — medium polycount. * `4`: Adaptive — low polycount. - `save_pre_remeshed_model` · *boolean* · default: `false` When set to `true`, Meshy also stores an extra GLB file before the remesh phase completes. - `symmetry_mode` · *string* · default: `auto` The `symmetry_mode` field controls symmetry behavior during the model generation process. The valid values are: * `off`: Disables symmetry. * `auto`: Automatically determines and applies symmetry based on input geometry. * `on`: Enforces symmetry during generation. - `pose_mode` · *string* · default: `""` Specify the pose mode for the generated model. Available values: * `a-pose`: Generate the model in an A pose. * `t-pose`: Generate the model in a T pose. * `""` (empty string): No specific pose applied. - `is_a_t_pose` · *boolean* · default: `false` · **deprecated** Use `pose_mode` instead. Whether to generate the model in an A/T pose. - `image_enhancement` · *boolean* · default: `true` Optimizes the input images for better results. Set to `false` to preserve the exact appearance of the input images without any style processing. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `remove_lighting` · *boolean* · default: `true` Removes highlights and shadows from the base color texture, producing a cleaner result that works better under custom lighting setups. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `moderation` · *boolean* · default: `false` When set to `true`, the input content will automatically be screened for potentially harmful content. If harmful content is detected, the task will not proceed to generation. Each image from `image_urls` and the text from `texture_prompt` will be screened. - `target_formats` · *string[]* Specifies which 3D file formats to include in the output. Only the requested formats will be generated and returned, which can reduce task completion time. Available values: `glb`, `obj`, `fbx`, `stl`, `usdz`, `3mf` > **Note:** When omitted, all formats except `3mf` are generated. `3mf` is only included when explicitly specified. - `auto_size` · *boolean* · default: `false` When set to `true`, the service uses AI vision to automatically estimate the real-world height of the object and resize the model accordingly. The origin will default to `bottom` unless `origin_at` is explicitly set. **Only when `auto_size` is set:** - `origin_at` · *string* · default: `bottom` Position of the origin when `auto_size` is enabled. Available values: `bottom`, `center`. ### Returns The `result` property of the response contains the task `id` of the newly created Multi-Image to 3D task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: Either `image_urls` or `input_task_id` must be provided. * **Invalid input task**: The `input_task_id` must refer to a `SUCCEEDED` Text to Image, Image to Image, or multi-view variant task. * **Invalid image count**: `image_urls` must contain between 1 and 4 images. * **Invalid image format**: One or more images in `image_urls` are not supported formats. * **Unreachable URL**: One or more `image_urls` could not be downloaded. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Simple request curl https://api.meshy.ai/openapi/v1/multi-image-to-3d \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "image_urls": [ "", "" ] }' # With PBR texturing and GLB format curl https://api.meshy.ai/openapi/v1/multi-image-to-3d \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "image_urls": [ "", "" ], "should_texture": true, "enable_pbr": true, "target_formats": ["glb"] }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Simple request const payload = { image_urls: [ "", "" ], }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/multi-image-to-3d', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // With PBR texturing and GLB format const advancedPayload = { image_urls: [ "", "" ], should_texture: true, enable_pbr: true, target_formats: ["glb"], }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/multi-image-to-3d', advancedPayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests # Simple request payload = { "image_urls": [ "", "" ], } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Simple request response = requests.post( "https://api.meshy.ai/openapi/v1/multi-image-to-3d", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # With PBR texturing and GLB format advanced_payload = { "image_urls": [ "", "" ], "should_texture": True, "enable_pbr": True, "target_formats": ["glb"], } response = requests.post( "https://api.meshy.ai/openapi/v1/multi-image-to-3d", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v1/multi-image-to-3d/:id -- Retrieve a Multi-Image to 3D Task This endpoint allows you to retrieve a Multi-Image to 3D task given a valid task `id`. Refer to [The Multi-Image to 3D Task Object](#the-multi-image-to-3d-task-object) to see which properties are included with Multi-Image to 3D task object. ### Parameters - `id` · *path* Unique identifier for the Multi-Image to 3D task to retrieve. ### Returns The response contains the Multi-Image to 3D task object. Check [The Multi-Image to 3D Task Object](#the-multi-image-to-3d-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/multi-image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/multi-image-to-3d/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/multi-image-to-3d/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "multi-image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## DELETE /openapi/v1/multi-image-to-3d/:id -- Delete a Multi-Image to 3D Task This endpoint permanently deletes a Multi-Image to 3D task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the Multi-Image to 3D task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/multi-image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/multi-image-to-3d/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/multi-image-to-3d/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/multi-image-to-3d -- List Multi-Image to 3D Tasks This endpoint allows you to retrieve a list of Multi-Image to 3D tasks. ### Parameters #### Optional attributes - `page_num` · *integer* Page number for pagination. Starts and defaults to `1`. - `page_size` · *integer* Page size limit. Defaults to `10` items. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Multi-Image to 3D Task Objects](#the-multi-image-to-3d-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/multi-image-to-3d?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/multi-image-to-3d?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/multi-image-to-3d", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "multi-image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ] ``` --- ## GET /openapi/v1/multi-image-to-3d/:id/stream -- Stream a Multi-Image to 3D Task This endpoint streams real-time updates for a Multi-Image to 3D task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Multi-Image to 3D task to stream. ### Returns Returns a stream of [The Multi-Image to 3D Task Objects](#the-multi-image-to-3d-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/multi-image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/multi-image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/multi-image-to-3d/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```text // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "multi-image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## The Multi-Image to 3D Task Object The Multi-Image to 3D Task object is a work unit that Meshy keeps track of to generate a 3d model from multiple images (between 1 to 4 inclusive). The images should be of the same object, ideally from different views or angles. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the Multi-Image to 3D task. The value is `multi-image-to-3d`. - `model_urls` · *object* Downloadable URL to the textured 3D model file generated by Meshy. The property for a format will be omitted if the format is not generated instead of returning an empty string. - `glb` · *string* Downloadable URL to the GLB file. - `fbx` · *string* Downloadable URL to the FBX file. - `obj` · *string* Downloadable URL to the OBJ file. - `usdz` · *string* Downloadable URL to the USDZ file. - `mtl` · *string* Downloadable URL to the MTL file, returned alongside OBJ exports when textures are present. - `stl` · *string* Downloadable URL to the STL file. - `3mf` · *string* Downloadable URL to the 3MF file. Only present when `3mf` was requested via `target_formats`. - `pre_remeshed_glb` · *string* Downloadable URL to the original GLB output before remeshing. > **Note:** Available only when the task was created with both `should_remesh: true` and `save_pre_remeshed_model: true`. - `thumbnail_url` · *string* Downloadable URL to the thumbnail image of the model file. - `texture_prompt` · *string* The text prompt that was used to guide the texturing process. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `expires_at` · *timestamp* Timestamp of when the task result expires, in milliseconds. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `texture_urls` · *array* An array of texture URL objects that are generated from the task. Normally this only contains **one** texture URL object. Each texture URL has the following properties: - `base_color` · *string* Downloadable URL to the base color map image. - `metallic` · *string* Downloadable URL to the metallic map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `normal` · *string* Downloadable URL to the normal map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `roughness` · *string* Downloadable URL to the roughness map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `emission` · *string* Downloadable URL to the emission map image. > **Note:** If the task is created with `enable_pbr: false`, or `ai_model` is `meshy-5`, this property will be omitted. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Multi-Image to 3D Task Object** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "multi-image-to-3d", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***", "pre_remeshed_glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/pre_remeshed_model.glb?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "texture_prompt": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" }, } ``` --- # Remesh API Source: https://docs.meshy.ai/api/remesh # Remesh API The Remesh API allows you to remesh and export existing 3D models generated by other Meshy APIs (like Image to 3D or Text to 3D) into various formats. This section provides details on how to use the Remesh API. --- ## POST /openapi/v1/remesh -- Create a Remesh Task This endpoint creates a new remesh task. ### Parameters > **Note:** Only one of `input_task_id` or `model_url` is **required**. If both are provided, `input_task_id` takes priority. - `input_task_id` · *string* · **required** The ID of the completed Image to 3D or Text to 3D task you wish to remesh. This task must be one of the following tasks: Text to 3D Preview, Text to 3D Refine, Image to 3D or Retexture. In addition, it must have a status of `SUCCEEDED`. - `model_url` · *string* · **required** Please provide a 3D model for Meshy to remesh via a publicly accessible URL or data URI. Supported formats: `.glb`, `.gltf`, `.obj`, `.fbx`, `.stl`. For Data URIs, use the MIME type: `application/octet-stream`. - `target_formats` · *string[]* · default: `["glb"]` A list of target formats for the remeshed model. When omitted, only GLB is generated. Available values: `glb`, `fbx`, `obj`, `usdz`, `blend`, `stl`, `3mf`. - `topology` · *string* · default: `triangle` Specify the topology of the generated model. Available values: * `quad`: Generate a quad-dominant mesh. * `triangle`: Generate a decimated triangle mesh. - `target_polycount` · *integer* · default: `30,000` Specify the target number of polygons in the generated model. The actual number of polygons may deviate from the target depending on the complexity of the geometry. The valid value range varies depending on the user tier: * 100 to 300,000 (inclusive) - `decimation_mode` · *integer* Enable adaptive decimation by setting a polycount level. When set, `target_polycount` is ignored. Available values: * `1`: Adaptive — ultra polycount. * `2`: Adaptive — high polycount. * `3`: Adaptive — medium polycount. * `4`: Adaptive — low polycount. - `resize_height` · *number* · default: `0` Resize the model to a certain height measured in meters. - `auto_size` · *boolean* · default: `false` When set to `true`, the service uses AI vision to automatically estimate the real-world height of the object and resize the model accordingly. The origin will default to `bottom` unless `origin_at` is explicitly set. > **Note:** `auto_size` and `resize_height` are mutually exclusive. **Only when `auto_size` is set:** - `origin_at` · *string* · default: `bottom` Position of the origin. Available values: `bottom`, `center`. - `convert_format_only` · *boolean* If `true`, the service will only change the format of the input model file, ignoring other inputs like `topology`, `resize_height`, and `target_polycount`. > **Note:** `target_formats` must be provided if `convert_format_only` is set to `true`. ### Returns The `result` property of the response contains the `id` of the newly created remesh task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: Either `model_url` or `input_task_id` must be provided. * **Invalid input task**: The `input_task_id` must refer to a successful task from a supported model. * **Invalid model format**: The `model_url` points to a file with an unsupported extension. * **Unreachable URL**: The `model_url` could not be downloaded. * **Invalid topology**: The `topology` parameter is invalid. * **Mutually exclusive parameters**: `auto_size` and `resize_height` cannot both be set. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Basic remesh with custom formats and resize curl https://api.meshy.ai/openapi/v1/remesh \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb", "fbx"], "topology": "quad", "target_polycount": 50000, "resize_height": 1.0, "origin_at": "bottom" }' # Quad remesh with auto-size curl https://api.meshy.ai/openapi/v1/remesh \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb", "fbx"], "topology": "quad", "target_polycount": 50000, "auto_size": true }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Basic remesh with custom formats and resize const payload = { input_task_id: "018a210d-8ba4-705c-b111-1f1776f7f578", target_formats: ["glb", "fbx"], topology: "quad", target_polycount: 50000, resize_height: 1.0, origin_at: "bottom" }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/remesh', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // Quad remesh with auto-size const autoSizePayload = { input_task_id: "018a210d-8ba4-705c-b111-1f1776f7f578", target_formats: ["glb", "fbx"], topology: "quad", target_polycount: 50000, auto_size: true }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/remesh', autoSizePayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Basic remesh with custom formats and resize payload = { "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb", "fbx"], "topology": "quad", "target_polycount": 50000, "resize_height": 1.0, "origin_at": "bottom" } response = requests.post( "https://api.meshy.ai/openapi/v1/remesh", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # Quad remesh with auto-size auto_size_payload = { "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "target_formats": ["glb", "fbx"], "topology": "quad", "target_polycount": 50000, "auto_size": True } response = requests.post( "https://api.meshy.ai/openapi/v1/remesh", headers=headers, json=auto_size_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "0193bfc5-ee4f-73f8-8525-44b398884ce9" } ``` --- ## GET /openapi/v1/remesh/:id -- Retrieve a Remesh Task This endpoint retrieves a remesh task by its ID. ### Parameters - `id` · *path* The ID of the remesh task to retrieve. ### Returns The Remesh Task object. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/remesh/a43b5c6d-7e8f-901a-234b-567c890d1e2f \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = 'a43b5c6d-7e8f-901a-234b-567c890d1e2f'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/remesh/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "a43b5c6d-7e8f-901a-234b-567c890d1e2f" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/remesh/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "remesh", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.usdz?Expires=***", "blend": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.blend?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.stl?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null, } ``` --- ## DELETE /openapi/v1/remesh/:id -- Delete a Remesh Task This endpoint permanently deletes a remesh task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the remesh task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/remesh/a43b5c6d-7e8f-901a-234b-567c890d1e2f \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = 'a43b5c6d-7e8f-901a-234b-567c890d1e2f' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/remesh/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "a43b5c6d-7e8f-901a-234b-567c890d1e2f" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/remesh/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/remesh -- List Remesh Tasks This endpoint allows you to retrieve a list of Remesh tasks. ### Parameters - `page_num` · *integer* · default: `1` Page number for pagination. - `page_size` · *integer* · default: `10` Page size limit. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Remesh Task Objects](#the-remesh-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/remesh?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/remesh?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/remesh", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "remesh", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.usdz?Expires=***", "blend": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.blend?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.stl?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null } ] ``` --- ## GET /openapi/v1/remesh/:id/stream -- Stream a Remesh Task This endpoint streams real-time updates for a Remesh task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Remesh task to stream. ### Returns Returns a stream of [The Remesh Task Objects](#the-remesh-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/remesh/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/remesh/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/remesh/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "progress": 0, "status": "PENDING" } event: message data: { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "remesh", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.usdz?Expires=***", "blend": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.blend?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.stl?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null, } ``` --- ## The Remesh Task Object The Remesh Task object represents a work unit that Meshy uses to remesh and export an existing 3D model into various formats. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the Remesh task. The value is `remesh`. - `model_urls` · *object* Downloadable URL to the textured 3D model file generated by Meshy. The property for a format will be omitted if the format is not generated instead of returning an empty string. - `glb` · *string* Downloadable URL to the GLB file. - `fbx` · *string* Downloadable URL to the FBX file. - `obj` · *string* Downloadable URL to the OBJ file. - `usdz` · *string* Downloadable URL to the USDZ file. - `blend` · *string* Downloadable URL to the Blender file. - `stl` · *string* Downloadable URL to the STL file. - `3mf` · *string* Downloadable URL to the 3MF file. Only present when `3mf` was requested via `target_formats`. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Remesh Task Object** ```json { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "remesh", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.usdz?Expires=***", "blend": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.blend?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.stl?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "preceding_tasks": 0, "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": { "message": "" } } ``` --- # Rigging API Source: https://docs.meshy.ai/api/rigging # Rigging API The Rigging API allows you to programmatically add a skeleton (armature) to 3D humanoid models, binding the mesh to it so they are ready for animation. For applying animations to a rigged character, see the [Animation API](/api/animation). Please note that programmatic rigging currently only works well with standard humanoid (bipedal) assets with clearly defined limbs and body structure at this time. --- ## POST /openapi/v1/rigging -- Create a Rigging Task This endpoint allows you to create a new rigging task for a given 3D model. Upon successful completion, it provides a rigged character in standard formats and optionally basic walking/running animations. Currently, auto-rigging is not suitable for the following models: - Untextured meshes - Non-humanoid assets - Humanoid assets with unclear limb and body structure > **Note:** When using `input_task_id`, models with more than **300,000 faces** are not supported for rigging. Please use the [Remesh API](/api/remesh) to reduce the face count before rigging. > **Note:** When using `model_url`, the character's face must point toward the +Z axis (the standard glTF forward direction). Models facing other axes will fail pose estimation. ### Parameters > **Note:** Only one of `input_task_id` or `model_url` is **required**. If both are provided, `input_task_id` takes priority. - `input_task_id` · *string* · **required** The input task that needs to be rigged. We currently support textured humanoid models. - `model_url` · *string* · **required** Please provide a 3D model for Meshy to rig via a publicly accessible URL or Data URI. We currently support textured humanoid GLB files (`.glb` format). - `height_meters` · *number* · default: `1.7` The approximate height of the character model in meters. This aids in scaling and rigging accuracy. It must be a positive number. - `texture_image_url` · *string* The model's UV-unwrapped base color texture image. Publicly accessible URL or Data URI. We currently support `.png` formats. ### Returns The `result` property of the response contains the task `id` of the newly created rigging task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: Either `model_url` or `input_task_id` must be provided. * **Invalid model format**: The `model_url` points to a file with an unsupported extension (only .glb supported). * **Unreachable URL**: The `model_url` could not be downloaded. * **Invalid input task**: The `input_task_id` does not refer to a valid API task. * **Face count exceeded**: The input model has more than 300,000 faces. Please use the [Remesh API](/api/remesh) to reduce the face count before rigging. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `422 - Unprocessable Entity` Pose estimation failed. The provided model may not be a valid humanoid character. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Rig a model from a URL curl https://api.meshy.ai/openapi/v1/rigging \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "model_url": "YOUR_MODEL_URL_OR_DATA_URI", "height_meters": 1.8 }' ``` ```javascript import axios from 'axios' // Rig a model from a URL const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; const payload = { model_url: "YOUR_MODEL_URL_OR_DATA_URI", height_meters: 1.8 }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/rigging', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests # Rig a model from a URL payload = { "model_url": "YOUR_MODEL_URL_OR_DATA_URI", "height_meters": 1.8 } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.post( "https://api.meshy.ai/openapi/v1/rigging", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018b314a-a1b5-716d-c222-2f1776f7f579" } ``` --- ## GET /openapi/v1/rigging/:id -- Retrieve a Rigging Task This endpoint allows you to retrieve a rigging task given a valid task `id`. Refer to [The Rigging Task Object](#the-rigging-task-object) to see which properties are included. ### Parameters - `id` · *path* Unique identifier for the rigging task to retrieve. ### Returns The response contains the Rigging Task object. Check [The Rigging Task Object](#the-rigging-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/rigging/018b314a-a1b5-716d-c222-2f1776f7f579 -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018b314a-a1b5-716d-c222-2f1776f7f579'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/rigging/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018b314a-a1b5-716d-c222-2f1776f7f579" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/rigging/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018b314a-a1b5-716d-c222-2f1776f7f579", "type": "rig", "status": "SUCCEEDED", "created_at": 1747032400453, "progress": 100, "started_at": 1747032401314, "finished_at": 1747032418417, "expires_at": 1747291618417, "task_error": { "message": "" }, "result": { "rigged_character_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Character_output.fbx?Expires=...", "rigged_character_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Character_output.glb?Expires=...", "basic_animations": { "walking_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin.glb?Expires=...", "walking_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin.fbx?Expires=...", "walking_armature_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin_armature.glb?Expires=...", "running_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin.glb?Expires=...", "running_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin.fbx?Expires=...", "running_armature_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin_armature.glb?Expires=..." } }, "preceding_tasks": 0 } ``` --- ## DELETE /openapi/v1/rigging/:id -- Delete a Rigging Task This endpoint permanently deletes a rigging task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the rigging task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/rigging/018b314a-a1b5-716d-c222-2f1776f7f579 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018b314a-a1b5-716d-c222-2f1776f7f579' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/rigging/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018b314a-a1b5-716d-c222-2f1776f7f579" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/rigging/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/rigging/:id/stream -- Stream a Rigging Task This endpoint streams real-time updates for a Rigging task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Rigging task to stream. ### Returns Returns a stream of [The Rigging Task Objects](#the-rigging-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/rigging/018b314a-a1b5-716d-c222-2f1776f7f579/stream -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/rigging/018b314a-a1b5-716d-c222-2f1776f7f579/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } task_id = "018b314a-a1b5-716d-c222-2f1776f7f579" response = requests.get( f'https://api.meshy.ai/openapi/v1/rigging/{task_id}/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data_str = line.decode('utf-8')[5:] try: data = json.loads(data_str) print(data) if data.get('status') in ['SUCCEEDED', 'FAILED', 'CANCELED']: break except json.JSONDecodeError: print(f"Failed to decode JSON: {data_str}") response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018b314a-a1b5-716d-c222-2f1776f7f579", "progress": 0, "status": "PENDING" } event: message data: { "id": "018b314a-a1b5-716d-c222-2f1776f7f579", "progress": 50, "status": "IN_PROGRESS" } event: message data: { // Example of a SUCCEEDED task stream item, mirroring The Rigging Task Object structure "id": "018b314a-a1b5-716d-c222-2f1776f7f579", "type": "rig", "status": "SUCCEEDED", "created_at": 1747032400453, "progress": 100, "started_at": 1747032401314, "finished_at": 1747032418417, "expires_at": 1747291618417, "task_error": { "message": "" }, "result": { "rigged_character_fbx_url": "https://assets.meshy.ai/.../Character_output.fbx?...", "rigged_character_glb_url": "https://assets.meshy.ai/.../Character_output.glb?...", "basic_animations": { "walking_glb_url": "https://assets.meshy.ai/.../Animation_Walking_withSkin.glb?...", "walking_fbx_url": "https://assets.meshy.ai/.../Animation_Walking_withSkin.fbx?...", "walking_armature_glb_url": "https://assets.meshy.ai/.../Animation_Walking_withSkin_armature.glb?...", "running_glb_url": "https://assets.meshy.ai/.../Animation_Running_withSkin.glb?...", "running_fbx_url": "https://assets.meshy.ai/.../Animation_Running_withSkin.fbx?...", "running_armature_glb_url": "https://assets.meshy.ai/.../Animation_Running_withSkin_armature.glb?..." } }, "preceding_tasks": 0 } ``` --- ## The Rigging Task Object The Rigging Task object represents the work unit for rigging a character. ### Properties - `id` · *string* Unique identifier for the task. - `type` · *string* Type of the Rigging task. The value is `rig`. - `status` · *string* Status of the task. Possible values: `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `progress` · *integer* Progress of the task (0-100). `0` if not started, `100` if succeeded. - `created_at` · *timestamp* Timestamp (milliseconds since epoch) when the task was created. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `started_at` · *timestamp* Timestamp (milliseconds since epoch) when the task started processing. `0` if not started. - `finished_at` · *timestamp* Timestamp (milliseconds since epoch) when the task finished. `0` if not finished. - `expires_at` · *timestamp* Timestamp (milliseconds since epoch) when the task result assets expire and may be deleted. - `task_error` · *object* Error object if the task failed, otherwise an object with an empty message string. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. Empty if task succeeded. - `result` · *object* Contains the output asset URLs if the task `SUCCEEDED`, `null` otherwise. - `rigged_character_fbx_url` · *string* Downloadable URL for the rigged character in FBX format. - `rigged_character_glb_url` · *string* Downloadable URL for the rigged character in GLB format. - `basic_animations` · *object (optional)* Contains URLs for default animations. (e.g. if `generate_basic_animations` was implicitly true or enabled by default). - `walking_glb_url` · *string* Downloadable URL for walking animation in GLB format (with skin). - `walking_fbx_url` · *string* Downloadable URL for walking animation in FBX format (with skin). - `walking_armature_glb_url` · *string* Downloadable URL for walking animation armature in GLB format. - `running_glb_url` · *string* Downloadable URL for running animation in GLB format (with skin). - `running_fbx_url` · *string* Downloadable URL for running animation in FBX format (with skin). - `running_armature_glb_url` · *string* Downloadable URL for running animation armature in GLB format. - `preceding_tasks` · *integer* The count of preceding tasks in the queue. Meaningful only if status is `PENDING`. **Example Rigging Task Object** ```json { "id": "018b314a-a1b5-716d-c222-2f1776f7f579", "type": "rig", "status": "SUCCEEDED", "created_at": 1747032400453, "progress": 100, "started_at": 1747032401314, "finished_at": 1747032418417, "expires_at": 1747291618417, "task_error": { "message": "" }, "result": { "rigged_character_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Character_output.fbx?Expires=...", "rigged_character_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Character_output.glb?Expires=...", "basic_animations": { "walking_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin.glb?Expires=...", "walking_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin.fbx?Expires=...", "walking_armature_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Walking_withSkin_armature.glb?Expires=...", "running_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin.glb?Expires=...", "running_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin.fbx?Expires=...", "running_armature_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018b314a-a1b5-716d-c222-2f1776f7f579/output/Animation_Running_withSkin_armature.glb?Expires=..." } }, "preceding_tasks": 0 } ``` --- # Animation API Source: https://docs.meshy.ai/api/animation # Animation API Endpoints for discovering available animations and applying them to rigged characters. --- ## POST /openapi/v1/animations -- Create an Animation Task This endpoint allows you to create a new task to apply a specific animation action to a previously rigged character. Includes post-processing options. ### Parameters - `rig_task_id` · *string* · **required** The `id` of a successfully completed rigging task (from `POST /openapi/v1/rigging`). The character from this task will be animated. - `action_id` · *integer* · **required** The identifier of the animation action to apply. See the [Animation Library Reference](/api/animation-library) for a complete list of available animations. - `post_process` · *object* Parameters for post-processing animation files. - `operation_type` · *string* · **required** The type of operation to perform. Available values: `change_fps`, `fbx2usdz`, `extract_armature`. - `fps` · *integer* · default: `30` The target frame rate. Applicable only when `operation_type` is `change_fps`. Allowed values: `24`, `25`, `30`, `60`. ### Returns The `result` property of the response contains the task `id` of the newly created animation task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: `rig_task_id` or `action_id` is missing. * **Invalid rig task**: The `rig_task_id` is invalid or refers to a failed/non-existent task. * **Invalid action ID**: The `action_id` does not correspond to a valid animation. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `404 - Not Found` The rigging task specified by `rig_task_id` was not found. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Animate a rigged model with required params only curl https://api.meshy.ai/openapi/v1/animations \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "rig_task_id": "018b314a-a1b5-716d-c222-2f1776f7f579", "action_id": 92 }' # With post-processing to change FPS curl https://api.meshy.ai/openapi/v1/animations \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "rig_task_id": "018b314a-a1b5-716d-c222-2f1776f7f579", "action_id": 92, "post_process": { "operation_type": "change_fps", "fps": 24 } }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Animate a rigged model with required params only const payload = { rig_task_id: "018b314a-a1b5-716d-c222-2f1776f7f579", action_id: 92 }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/animations', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // With post-processing to change FPS const advancedPayload = { rig_task_id: "018b314a-a1b5-716d-c222-2f1776f7f579", action_id: 92, post_process: { operation_type: "change_fps", fps: 24 } }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/animations', advancedPayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Animate a rigged model with required params only payload = { "rig_task_id": "018b314a-a1b5-716d-c222-2f1776f7f579", "action_id": 92 } response = requests.post( "https://api.meshy.ai/openapi/v1/animations", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # With post-processing to change FPS advanced_payload = { "rig_task_id": "018b314a-a1b5-716d-c222-2f1776f7f579", "action_id": 92, "post_process": { "operation_type": "change_fps", "fps": 24 } } response = requests.post( "https://api.meshy.ai/openapi/v1/animations", headers=headers, json=advanced_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018c425b-b2c6-727e-d333-3c1887i9h791" } ``` --- ## GET /openapi/v1/animations/:id -- Retrieve an Animation Task This endpoint allows you to retrieve an animation task given a valid task `id`. Refer to [The Animation Task Object](#the-animation-task-object) to see which properties are included. ### Parameters - `id` · *path* Unique identifier for the animation task to retrieve. ### Returns The response contains the Animation Task object. Check [The Animation Task Object](#the-animation-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/animations/018c425b-b2c6-727e-d333-3c1887i9h791 -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018c425b-b2c6-727e-d333-3c1887i9h791'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/animations/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018c425b-b2c6-727e-d333-3c1887i9h791" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/animations/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018c425b-b2c6-727e-d333-3c1887i9h791", "type": "animate", "status": "SUCCEEDED", "created_at": 1747032440896, "progress": 100, "started_at": 1747032441210, "finished_at": 1747032457530, "expires_at": 1747291657530, "task_error": { "message": "" }, "result": { "animation_glb_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018c425b-b2c6-727e-d333-3c1887i9h791/output/Animation_Reaping_Swing_withSkin.glb?Expires=...", "animation_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018c425b-b2c6-727e-d333-3c1887i9h791/output/Animation_Reaping_Swing_withSkin.fbx?Expires=...", "processed_usdz_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018c425b-b2c6-727e-d333-3c1887i9h791/output/processed.usdz?Expires=...", "processed_armature_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018c425b-b2c6-727e-d333-3c1887i9h791/output/processed_armature.fbx?Expires=...", "processed_animation_fps_fbx_url": "https://assets.meshy.ai/0630d47c-84b8-4d37-bc02-69e45d9272c1/tasks/018c425b-b2c6-727e-d333-3c1887i9h791/output/processed_60fps.fbx?Expires=..." }, "preceding_tasks": 0 } ``` --- ## DELETE /openapi/v1/animations/:id -- Delete an Animation Task This endpoint permanently deletes an animation task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the animation task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/animations/018b314a-a1b5-716d-c222-2f1776f7f579 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018b314a-a1b5-716d-c222-2f1776f7f579' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/animations/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018b314a-a1b5-716d-c222-2f1776f7f579" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/animations/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/animations/:id/stream -- Stream an Animation Task This endpoint streams real-time updates for an Animation task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Animation task to stream. ### Returns Returns a stream of [The Animation Task Objects](#the-animation-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/animations/018c425b-b2c6-727e-d333-3c1887i9h791/stream -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/animations/018c425b-b2c6-727e-d333-3c1887i9h791/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } task_id = "018c425b-b2c6-727e-d333-3c1887i9h791" response = requests.get( f'https://api.meshy.ai/openapi/v1/animations/{task_id}/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data_str = line.decode('utf-8')[5:] try: data = json.loads(data_str) print(data) if data.get('status') in ['SUCCEEDED', 'FAILED', 'CANCELED']: break except json.JSONDecodeError: print(f"Failed to decode JSON: {data_str}") response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018c425b-b2c6-727e-d333-3c1887i9h791", "progress": 0, "status": "PENDING" } event: message data: { "id": "018c425b-b2c6-727e-d333-3c1887i9h791", "progress": 50, "status": "IN_PROGRESS" } event: message data: { // Example of a SUCCEEDED task stream item, mirroring The Animation Task Object structure "id": "018c425b-b2c6-727e-d333-3c1887i9h791", "type": "animate", "status": "SUCCEEDED", "created_at": 1747032440896, "progress": 100, "started_at": 1747032441210, "finished_at": 1747032457530, "expires_at": 1747291657530, "task_error": { "message": "" }, "result": { "animation_glb_url": "https://assets.meshy.ai/.../Animation_Reaping_Swing_withSkin.glb?...", "animation_fbx_url": "https://assets.meshy.ai/.../Animation_Reaping_Swing_withSkin.fbx?...", "processed_usdz_url": "https://assets.meshy.ai/.../processed.usdz?...", "processed_armature_fbx_url": "https://assets.meshy.ai/.../processed_armature.fbx?...", "processed_animation_fps_fbx_url": "https://assets.meshy.ai/.../processed_60fps.fbx?..." }, "preceding_tasks": 0 } ``` --- ## The Animation Task Object The Animation Task object represents the work unit for applying an animation to a rigged character. ### Properties - `id` · *string* Unique identifier for the task. - `type` · *string* Type of the Animation task. The value is `animate`. - `status` · *string* Status of the task. Possible values: `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `progress` · *integer* Progress of the task (0-100). - `created_at` · *timestamp* Timestamp (milliseconds since epoch) when the task was created. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `started_at` · *timestamp* Timestamp (milliseconds since epoch) when the task started processing. `0` if not started. - `finished_at` · *timestamp* Timestamp (milliseconds since epoch) when the task finished. `0` if not finished. - `expires_at` · *timestamp* Timestamp (milliseconds since epoch) when the task result assets expire. - `task_error` · *object* Error object if the task failed, otherwise an object with an empty message string. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. Empty if task succeeded. - `result` · *object* Contains the output animation URLs if the task `SUCCEEDED`. - `animation_glb_url` · *string* Downloadable URL for the animation in GLB format. - `animation_fbx_url` · *string* Downloadable URL for the animation in FBX format. - `processed_usdz_url` · *string* Downloadable URL for the processed animation in USDZ format. - `processed_armature_fbx_url` · *string* Downloadable URL for the processed armature in FBX format. - `processed_animation_fps_fbx_url` · *string* Downloadable URL for the animation with changed FPS in FBX format (e.g., if `change_fps` operation was used). - `preceding_tasks` · *integer* The count of preceding tasks in the queue. Meaningful only if status is `PENDING`. **Example Animation Task Object** ```json { "id": "018c425b-b2c6-727e-d333-3c1887i9h791", "type": "animate", "status": "SUCCEEDED", "created_at": 1747032440896, "progress": 100, "started_at": 1747032441210, "finished_at": 1747032457530, "expires_at": 1747291657530, "task_error": { "message": "" }, "result": { "animation_glb_url": "https://assets.meshy.ai/.../Animation_Reaping_Swing_withSkin.glb?...", "animation_fbx_url": "https://assets.meshy.ai/.../Animation_Reaping_Swing_withSkin.fbx?...", "processed_usdz_url": "https://assets.meshy.ai/.../processed.usdz?...", "processed_armature_fbx_url": "https://assets.meshy.ai/.../processed_armature.fbx?...", "processed_animation_fps_fbx_url": "https://assets.meshy.ai/.../processed_60fps.fbx?..." }, "preceding_tasks": 0 } ``` --- # Retexture API Source: https://docs.meshy.ai/api/retexture export const sections = [ { title: "Create a Task", id: "create-a-retexture-task", }, { title: "Get a Task", id: "retrieve-a-retexture-task", }, { title: "List Tasks", id: "list-retexture-tasks", }, { title: "Stream a Task", id: "stream-a-retexture-task", }, { title: "Task Object", id: "the-retexture-task-object" }, ]; # Retexture API Retexture API is a feature that allows you to integrate Meshy's AI retexturing capabilities into your own application. In this section, you'll find all the information you need to get started with this API. --- ## POST /openapi/v1/retexture -- Create a Retexture Task This endpoint allows you to create a new Retexture task. Refer to [The Retexture Task Object](#the-retexture-task-object) to see which properties are included with Retexture task object. ### Parameters > **Note:** Only one of `input_task_id` or `model_url` is **required**. If both are provided, `input_task_id` takes priority. - `input_task_id` · *string* · **required** The ID of the completed Image to 3D or Text to 3D task you wish to retexture. This task must be one of the following tasks: Text to 3D Preview, Text to 3D Refine, Image to 3D or Remesh. In addition, it must have a status of `SUCCEEDED`. - `model_url` · *string* · **required** Provide a 3D model for Meshy to texture. Supported formats: `.glb`, `.gltf`, `.obj`, `.fbx`, `.stl`. There are two ways to provide the model: - **Publicly accessible URL**: A URL that is accessible from the public internet. - **Data URI**: A base64-encoded data URI of the model. Use MIME type `application/octet-stream`. Example: `data:application/octet-stream;base64,`. > **Note:** Only one of `text_style_prompt` or `image_style_url` is **required**. If both are provided, `image_style_url` takes priority. - `text_style_prompt` · *string* · **required** Describe your desired texture style of the object using text. Maximum 600 characters. - `image_style_url` · *string* · **required** Provide a 2d image to guide the texturing process. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide the image: - **Publicly accessible URL**: A URL that is accessible from the public internet - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,` > **Note:** Image texturing may not work optimally if there are substantial geometry differences between the original asset and uploaded image. - `ai_model` · *string* · default: `latest` ID of the AI model to use for retexturing. Available values: `meshy-5`, `meshy-6`, `latest` (Meshy 6). - `enable_original_uv` · *boolean* · default: `true` Use the original UV of the model instead of generating new UVs. When enabled, Meshy preserves existing textures from the uploaded model. If the model has no original UV, the quality of the output might not be as good. - `enable_pbr` · *boolean* · default: `false` Generate PBR Maps (metallic, roughness, normal) in addition to the base color. An emission map is also included when `ai_model` is `meshy-6` or `latest`. - `hd_texture` · *boolean* · default: `false` Generate the base color texture at 4K (4096×4096) resolution for higher detail. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. PBR maps are always generated at 2K. - `remove_lighting` · *boolean* · default: `true` Removes highlights and shadows from the base color texture, producing a cleaner result that works better under custom lighting setups. > **Note:** Only supported when `ai_model` is `meshy-6` or `latest`. - `target_formats` · *string[]* Specifies which 3D file formats to include in the output. Only the requested formats will be generated and returned, which can reduce task completion time. When omitted, all supported formats are included. Available values: `glb`, `obj`, `fbx`, `stl`, `usdz`, `3mf` > **Note:** When omitted, all formats except `3mf` are generated. `3mf` is only included when explicitly specified. ### Returns The `result` property of the response contains the task `id` of the newly created Retexture task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: Either `model_url` or `input_task_id` must be provided. * **Missing style**: Either `text_style_prompt` or `image_style_url` must be provided. * **Invalid input task**: The `input_task_id` must refer to a successful task from a supported model. * **Invalid model format**: The `model_url` points to a file with an unsupported extension. * **Unreachable URL**: The `model_url` or `image_style_url` could not be downloaded. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Retexture with text prompt curl https://api.meshy.ai/openapi/v1/retexture \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "model_url": "https://cdn.meshy.ai/model/example_model_2.glb", "text_style_prompt": "red fangs, Samurai outfit that fused with japanese batik style", "enable_original_uv": true, "enable_pbr": true }' # Retexture with image style and PBR curl https://api.meshy.ai/openapi/v1/retexture \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "model_url": "https://cdn.meshy.ai/model/example_model_2.glb", "image_style_url": "https://cdn.meshy.ai/image/example_image.jpg", "ai_model": "latest", "enable_pbr": true, "enable_original_uv": true }' ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; // Retexture with text prompt const payload = { model_url: 'https://cdn.meshy.ai/model/example_model_2.glb', text_style_prompt: 'red fangs, Samurai outfit that fused with japanese batik style', enable_original_uv: true, enable_pbr: true, }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/retexture', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } // Retexture with image style and PBR const imageStylePayload = { model_url: 'https://cdn.meshy.ai/model/example_model_2.glb', image_style_url: 'https://cdn.meshy.ai/image/example_image.jpg', ai_model: 'latest', enable_pbr: true, enable_original_uv: true, }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/retexture', imageStylePayload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } # Retexture with text prompt payload = { "model_url": "https://cdn.meshy.ai/model/example_model_2.glb", "text_style_prompt": "red fangs, Samurai outfit that fused with japanese batik style", "enable_original_uv": True, "enable_pbr": True } response = requests.post( "https://api.meshy.ai/openapi/v1/retexture", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) # Retexture with image style and PBR image_style_payload = { "model_url": "https://cdn.meshy.ai/model/example_model_2.glb", "image_style_url": "https://cdn.meshy.ai/image/example_image.jpg", "ai_model": "latest", "enable_pbr": True, "enable_original_uv": True } response = requests.post( "https://api.meshy.ai/openapi/v1/retexture", headers=headers, json=image_style_payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v1/retexture/:id -- Retrieve a Retexture Task This endpoint allows you to retrieve a Retexture task given a valid task `id`. Refer to [The Retexture Task Object](#the-retexture-task-object) to see which properties are included with Retexture task object. ### Parameters - `id` · *path* Unique identifier for the Retexture task to retrieve. ### Returns The response contains the Retexture task object. Check [The Retexture Task Object](#the-retexture-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/retexture/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/retexture/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/retexture/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "retexture", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "mtl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.mtl?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "text_style_prompt": "red fangs, Samurai outfit that fused with japanese batik style", "texture_image_url": "", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "task_error": { "message": "" } } ``` --- ## DELETE /openapi/v1/retexture/:id -- Delete a Retexture Task This endpoint permanently deletes a retexture task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the retexture task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/retexture/a43b5c6d-7e8f-901a-234b-567c890d1e2f \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = 'a43b5c6d-7e8f-901a-234b-567c890d1e2f' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/retexture/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "a43b5c6d-7e8f-901a-234b-567c890d1e2f" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/retexture/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/retexture -- List Retexture Tasks This endpoint allows you to retrieve a list of Retexture tasks. ### Parameters - `page_num` · *integer* · default: `1` Page number for pagination. - `page_size` · *integer* · default: `10` Page size limit. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Retexture Task Objects](#the-retexture-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/retexture?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/retexture?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/retexture", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "retexture", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***" }, "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "text_style_prompt": "red fangs, Samurai outfit that fused with japanese batik style", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ] ``` --- ## GET /openapi/v1/retexture/:id/stream -- Stream a Retexture Task This endpoint streams real-time updates for a Retexture task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Retexture task to stream. ### Returns Returns a stream of [The Retexture Task Objects](#the-retexture-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/retexture/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/retexture/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/retexture/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 50, "status": "IN_PROGRESS" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "retexture", "progress": 100, "status": "SUCCEEDED", "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "obj": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.obj?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***", "mtl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.mtl?Expires=***", "stl": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.stl?Expires=***" }, "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- ## The Retexture Task Object The Retexture Task object is a work unit that Meshy uses to generate a 3D texture from a either text or image inputs. The model has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the Retexture task. The value is `retexture`. - `model_urls` · *object* Downloadable URL to the textured 3D model file generated by Meshy. - `glb` · *string* Downloadable URL to the GLB file. - `fbx` · *string* Downloadable URL to the FBX file. - `obj` · *string* Downloadable URL to the OBJ file. - `usdz` · *string* Downloadable URL to the USDZ file. - `mtl` · *string* Downloadable URL to the MTL file, returned alongside OBJ exports when textures are present. - `stl` · *string* Downloadable URL to the STL file. - `3mf` · *string* Downloadable URL to the 3MF file. Only present when `3mf` was requested via `target_formats`. - `text_style_prompt` · *string* This is the text prompt that was used to create the texturing task. - `image_style_url` · *string* This is the image input that was used to create the texturing task. - `thumbnail_url` · *string* Downloadable URL to the thumbnail image of the model file. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `expires_at` · *timestamp* Timestamp of when the task result expires, in milliseconds. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `texture_urls` · *array* An array of texture URL objects that are generated from the task. Normally this only contains **one** texture URL object. Each texture URL has the following properties: - `base_color` · *string* Downloadable URL to the base color map image. - `metallic` · *string* Downloadable URL to the metallic map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `normal` · *string* Downloadable URL to the normal map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `roughness` · *string* Downloadable URL to the roughness map image. > **Note:** If the task is created with `enable_pbr: false`, this property will be omitted. - `emission` · *string* Downloadable URL to the emission map image. > **Note:** If the task is created with `enable_pbr: false`, or `ai_model` is `meshy-5`, this property will be omitted. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** This property only presents when the task status is `PENDING`. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Retexture Task Model** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "retexture", "model_urls": { "glb": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.glb?Expires=***", "fbx": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.fbx?Expires=***", "usdz": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/model.usdz?Expires=***" }, "text_style_prompt": "red fangs, Samurai outfit that fused with japanese batik style", "image_style_url": "https://assets.meshy.ai/***/image/example_image.jpg?Expires=***", "thumbnail_url": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/preview.png?Expires=***", "progress": 100, "started_at": 1692771667037, "created_at": 1692771650657, "expires_at": 1692771679037, "finished_at": 1692771669037, "status": "SUCCEEDED", "texture_urls": [ { "base_color": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0.png?Expires=***", "metallic": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_metallic.png?Expires=XXX", "normal": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_normal.png?Expires=XXX", "roughness": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_roughness.png?Expires=XXX", "emission": "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/texture_0_emission.png?Expires=XXX" } ], "preceding_tasks": 0, "task_error": { "message": "" } } ``` --- # Text to Image API Source: https://docs.meshy.ai/api/text-to-image # Text to Image API Text to Image API is a feature that allows you to integrate Meshy's AI image generation capabilities into your own application. Generate high-quality images from text prompts using our powerful AI models. --- ## POST /openapi/v1/text-to-image -- Create a Text to Image Task This endpoint allows you to create a new Text to Image task. Refer to [The Text to Image Task Object](#the-text-to-image-task-object) to see which properties are included with Text to Image task object. ### Parameters - `ai_model` · *string* · **required** ID of the model to use for image generation. Available values: * `nano-banana`: Standard model * `nano-banana-pro`: Pro model with enhanced quality - `prompt` · *string* · **required** A text description of the image you want to generate. Be descriptive for best results. - `generate_multi_view` · *boolean* · default: `false` When set to `true`, generates a multi-view image showing the subject from multiple angles. > **Note:** When `generate_multi_view` is `true`, the `aspect_ratio` parameter cannot be set. - `pose_mode` · *string* Specify the pose mode for character generation. When omitted, the image is generated without any pose presets. Available values: `a-pose`, `t-pose` - `aspect_ratio` · *string* · default: `1:1` Specify the aspect ratio of the generated image. Available values: * `1:1`: Square format * `16:9`: Widescreen landscape * `9:16`: Widescreen portrait * `4:3`: Standard landscape * `3:4`: Standard portrait ### Returns The `result` property of the response contains the task `id` of the newly created Text to Image task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: A required parameter (e.g., `ai_model`, `prompt`) is missing. * **Invalid parameter**: `ai_model` or `aspect_ratio` is not one of the allowed values. * **Conflict**: `generate_multi_view` and `aspect_ratio` cannot be used simultaneously. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Generate an image from a text prompt curl https://api.meshy.ai/openapi/v1/text-to-image \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "aspect_ratio": "16:9" }' ``` ```javascript import axios from 'axios' // Generate an image from a text prompt const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; const payload = { ai_model: "nano-banana", prompt: "A majestic dragon soaring through clouds at sunset", aspect_ratio: "16:9" }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/text-to-image', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests # Generate an image from a text prompt payload = { "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "aspect_ratio": "16:9" } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.post( "https://api.meshy.ai/openapi/v1/text-to-image", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v1/text-to-image/:id -- Retrieve a Text to Image Task This endpoint allows you to retrieve a Text to Image task given a valid task `id`. Refer to [The Text to Image Task Object](#the-text-to-image-task-object) to see which properties are included with Text to Image task object. ### Parameters - `id` · *path* Unique identifier for the Text to Image task to retrieve. ### Returns The response contains the Text to Image task object. Check [The Text to Image Task Object](#the-text-to-image-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/text-to-image/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/text-to-image/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/text-to-image/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-image", "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ``` --- ## DELETE /openapi/v1/text-to-image/:id -- Delete a Text to Image Task This endpoint permanently deletes a Text to Image task, including all associated images and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the Text to Image task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/text-to-image/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/text-to-image/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/text-to-image/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/text-to-image -- List Text to Image Tasks This endpoint allows you to retrieve a list of Text to Image tasks. ### Parameters - `page_num` · *integer* Page number for pagination. Starts and defaults to `1`. - `page_size` · *integer* Page size limit. Defaults to `10` items. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Text to Image Task Objects](#the-text-to-image-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/text-to-image?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/text-to-image?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/text-to-image", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-image", "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ] ``` --- ## GET /openapi/v1/text-to-image/:id/stream -- Stream a Text to Image Task This endpoint streams real-time updates for a Text to Image task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Text to Image task to stream. ### Returns Returns a stream of [The Text to Image Task Objects](#the-text-to-image-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/text-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/text-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/text-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```text // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-image", "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ``` --- ## The Text to Image Task Object The Text to Image Task object is a work unit that Meshy keeps track of to generate an image from a **text prompt** input. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* The type of image generation task. For Text to Image tasks, this will always be `text-to-image`. - `ai_model` · *string* The AI model used for this task. Possible values are `nano-banana` or `nano-banana-pro`. - `prompt` · *string* The text prompt that was used to generate the image. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `expires_at` · *timestamp* Timestamp of when the task result expires, in milliseconds. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `image_urls` · *array* An array of downloadable URLs to the generated images. When `generate_multi_view` is enabled, this array contains three image URLs representing different viewing angles. Otherwise, it contains a single image URL. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Text to Image Task Object** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "text-to-image", "ai_model": "nano-banana", "prompt": "A majestic dragon soaring through clouds at sunset", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "preceding_tasks": 0, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ], "task_error": { "message": "" } } ``` --- # Image to Image API Source: https://docs.meshy.ai/api/image-to-image # Image to Image API Image to Image API is a feature that allows you to integrate Meshy's AI image editing capabilities into your own application. Transform and edit existing images using reference images and text prompts with our powerful AI models. --- ## POST /openapi/v1/image-to-image -- Create an Image to Image Task This endpoint allows you to create a new Image to Image task. Refer to [The Image to Image Task Object](#the-image-to-image-task-object) to see which properties are included with Image to Image task object. ### Parameters - `ai_model` · *string* · **required** ID of the model to use for image generation. Available values: * `nano-banana`: Standard model * `nano-banana-pro`: Pro model with enhanced quality - `prompt` · *string* · **required** A text description of the transformation or edit you want to apply to the reference images. - `reference_image_urls` · *array* · **required** An array of 1 to 5 reference images to use for the image editing task. We currently support `.jpg`, `.jpeg`, and `.png` formats. There are two ways to provide each image: - **Publicly accessible URL**: A URL that is accessible from the public internet. - **Data URI**: A base64-encoded data URI of the image. Example of a data URI: `data:image/jpeg;base64,`. - `generate_multi_view` · *boolean* · default: `false` When set to `true`, generates a multi-view image showing the subject from multiple angles. ### Returns The `result` property of the response contains the task `id` of the newly created Image to Image task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: A required parameter (e.g., `ai_model`, `prompt`, `reference_image_urls`) is missing. * **Invalid image format**: One or more reference images are not supported formats. * **Unreachable URL**: One or more `reference_image_urls` could not be downloaded. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Transform a reference image with a text prompt curl https://api.meshy.ai/openapi/v1/image-to-image \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "reference_image_urls": [ "" ] }' ## Using Data URI example curl https://api.meshy.ai/openapi/v1/image-to-image \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "reference_image_urls": [ "data:image/png;base64,${YOUR_BASE64_ENCODED_IMAGE_DATA}" ] }' ``` ```javascript import axios from 'axios' // Transform a reference image with a text prompt const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; const payload = { ai_model: "nano-banana", prompt: "Transform this into a cyberpunk style artwork", // Using data URI example // reference_image_urls: ['data:image/png;base64,${YOUR_BASE64_ENCODED_IMAGE_DATA}'], reference_image_urls: [ "" ] }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/image-to-image', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests # Transform a reference image with a text prompt payload = { "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", # Using data URI example # "reference_image_urls": [f"data:image/png;base64,{YOUR_BASE64_ENCODED_IMAGE_DATA}"], "reference_image_urls": [ "" ] } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.post( "https://api.meshy.ai/openapi/v1/image-to-image", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "018a210d-8ba4-705c-b111-1f1776f7f578" } ``` --- ## GET /openapi/v1/image-to-image/:id -- Retrieve an Image to Image Task This endpoint allows you to retrieve an Image to Image task given a valid task `id`. Refer to [The Image to Image Task Object](#the-image-to-image-task-object) to see which properties are included with Image to Image task object. ### Parameters - `id` · *path* Unique identifier for the Image to Image task to retrieve. ### Returns The response contains the Image to Image task object. Check [The Image to Image Task Object](#the-image-to-image-task-object) section for details. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/image-to-image/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/image-to-image/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/image-to-image/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-image", "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ``` --- ## DELETE /openapi/v1/image-to-image/:id -- Delete an Image to Image Task This endpoint permanently deletes an Image to Image task, including all associated images and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the Image to Image task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/image-to-image/018a210d-8ba4-705c-b111-1f1776f7f578 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = '018a210d-8ba4-705c-b111-1f1776f7f578' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/image-to-image/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "018a210d-8ba4-705c-b111-1f1776f7f578" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/image-to-image/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/image-to-image -- List Image to Image Tasks This endpoint allows you to retrieve a list of Image to Image tasks. ### Parameters - `page_num` · *integer* Page number for pagination. Starts and defaults to `1`. - `page_size` · *integer* Page size limit. Defaults to `10` items. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The Image to Image Task Objects](#the-image-to-image-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/image-to-image?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/image-to-image?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/image-to-image", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-image", "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ] ``` --- ## GET /openapi/v1/image-to-image/:id/stream -- Stream an Image to Image Task This endpoint streams real-time updates for an Image to Image task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the Image to Image task to stream. ### Returns Returns a stream of [The Image to Image Task Objects](#the-image-to-image-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/image-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/image-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/image-to-image/018a210d-8ba4-705c-b111-1f1776f7f578/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```text // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "progress": 0, "status": "PENDING" } event: message data: { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-image", "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ] } ``` --- ## The Image to Image Task Object The Image to Image Task object is a work unit that Meshy keeps track of to generate an image from **reference images** and a **text prompt** input. The object has the following properties: ### Properties - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* The type of image generation task. For Image to Image tasks, this will always be `image-to-image`. - `ai_model` · *string* The AI model used for this task. Possible values are `nano-banana` or `nano-banana-pro`. - `prompt` · *string* The text prompt that was used to guide the image transformation. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`, `CANCELED`. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. > **Note:** A timestamp represents the number of milliseconds elapsed since January 1, 1970 UTC, following > the [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) standard. > For example, Friday, September 1, 2023 12:00:00 PM GMT is represented as `1693569600000`. This applies > to **all** timestamps in Meshy API. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `expires_at` · *timestamp* Timestamp of when the task result expires, in milliseconds. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `image_urls` · *array* An array of downloadable URLs to the generated images. When `generate_multi_view` is enabled, this array contains three image URLs representing different viewing angles. Otherwise, it contains a single image URL. - `task_error` · *object* Error object that contains the error message if the task failed. The `message` property should be empty if the task succeeded. See [Errors](/api/errors) for more details. - `message` · *string* Detailed error message. **Example Image to Image Task Object** ```json { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "type": "image-to-image", "ai_model": "nano-banana", "prompt": "Transform this into a cyberpunk style artwork", "status": "SUCCEEDED", "progress": 100, "created_at": 1692771650657, "started_at": 1692771667037, "finished_at": 1692771669037, "expires_at": 1692771679037, "preceding_tasks": 0, "image_urls": [ "https://assets.meshy.ai/***/tasks/018a210d-8ba4-705c-b111-1f1776f7f578/output/image.png?Expires=***" ], "task_error": { "message": "" } } ``` --- # Multi-Color Print API Source: https://docs.meshy.ai/api/multi-color-print # Multi-Color Print API Convert 3D models into multi-color 3MF format for 3D printing, with a configurable color palette of up to 16 colors. --- ## POST /openapi/v1/print/multi-color -- Create a Multi-Color 3D Print Task This endpoint creates a new multi-color 3D print task. The task converts a 3D model into a multi-color 3MF file suitable for 3D printing. ### Parameters - `input_task_id` · *string* · **required** The ID of a succeeded task to use as input. Supported task types: [Image to 3D](/api/image-to-3d), [Multi-Image to 3D](/api/multi-image-to-3d#create-a-multi-image-to-3d-task), [Text to 3D](/api/text-to-3d), [Remesh](/api/remesh), and [Retexture](/api/retexture). The task must have a status of `SUCCEEDED`. - `max_colors` · *integer* · default: `4` Maximum number of colors in the output palette. Valid range: `1` to `16`. - `max_depth` · *integer* · default: `4` Quadtree depth for color precision. Higher values produce finer color boundaries but increase file size. Valid range: `3` to `6`. ### Returns The `result` property of the response contains the `id` of the newly created 3D print task. ### Failure Modes - `400 - Bad Request` The request was unacceptable. Common causes: * **Missing parameter**: `input_task_id` must be provided. * **Invalid input task**: The `input_task_id` must refer to a successful task. * **Invalid max_colors**: Value must be between 1 and 16. * **Invalid max_depth**: Value must be between 3 and 6. - `401 - Unauthorized` Authentication failed. Please check your API key. - `402 - Payment Required` Insufficient credits to perform this task. - `429 - Too Many Requests` You have exceeded your rate limit. **cURL** ```bash # Convert a 3D model to multi-color 3MF for printing curl https://api.meshy.ai/openapi/v1/print/multi-color \ -X POST \ -H "Authorization: Bearer ${YOUR_API_KEY}" \ -H 'Content-Type: application/json' \ -d '{ "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "max_colors": 8, "max_depth": 5 }' ``` ```javascript import axios from 'axios' // Convert a 3D model to multi-color 3MF for printing const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; const payload = { input_task_id: "018a210d-8ba4-705c-b111-1f1776f7f578", max_colors: 8, max_depth: 5 }; try { const response = await axios.post( 'https://api.meshy.ai/openapi/v1/print/multi-color', payload, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests # Convert a 3D model to multi-color 3MF for printing payload = { "input_task_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "max_colors": 8, "max_depth": 5 } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.post( "https://api.meshy.ai/openapi/v1/print/multi-color", headers=headers, json=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": "0193bfc5-ee4f-73f8-8525-44b398884ce9" } ``` --- ## GET /openapi/v1/print/multi-color/:id -- Retrieve a Multi-Color 3D Print Task This endpoint retrieves a multi-color 3D print task by its ID. ### Parameters - `id` · *path* The ID of the 3D print task to retrieve. ### Returns The 3D Print Task object. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/print/multi-color/a43b5c6d-7e8f-901a-234b-567c890d1e2f \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = 'a43b5c6d-7e8f-901a-234b-567c890d1e2f'; const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/print/multi-color/${taskId}`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests task_id = "a43b5c6d-7e8f-901a-234b-567c890d1e2f" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( f"https://api.meshy.ai/openapi/v1/print/multi-color/{task_id}", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "print-multi-color", "model_urls": { "3mf": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.3mf?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null } ``` --- ## DELETE /openapi/v1/print/multi-color/:id -- Delete a Multi-Color 3D Print Task This endpoint permanently deletes a multi-color 3D print task, including all associated models and data. This action is irreversible. ### Path Parameters - `id` · *path* The ID of the multi-color 3D print task to delete. ### Returns Returns `200 OK` on success. **cURL** ```bash curl --request DELETE \ --url https://api.meshy.ai/openapi/v1/print/multi-color/a43b5c6d-7e8f-901a-234b-567c890d1e2f \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const taskId = 'a43b5c6d-7e8f-901a-234b-567c890d1e2f' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` } try { await axios.delete( `https://api.meshy.ai/openapi/v1/print/multi-color/${taskId}`, { headers } ) } catch (error) { console.error(error) } ``` ```python import requests task_id = "a43b5c6d-7e8f-901a-234b-567c890d1e2f" headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.delete( f"https://api.meshy.ai/openapi/v1/print/multi-color/{task_id}", headers=headers, ) response.raise_for_status() ``` **Response** ```json // Returns 200 Ok on success. ``` --- ## GET /openapi/v1/print/multi-color -- List Multi-Color 3D Print Tasks This endpoint allows you to retrieve a list of multi-color 3D print tasks. ### Parameters #### Optional attributes - `page_num` · *integer* Page number for pagination. Starts and defaults to `1`. - `page_size` · *integer* Page size limit. Defaults to `10` items. Maximum allowed is `50` items. - `sort_by` · *string* Field to sort by. Available values: * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. ### Returns Returns a paginated list of [The 3D Print Task Objects](#the-3d-print-task-object). **cURL** ```bash curl https://api.meshy.ai/openapi/v1/print/multi-color?page_size=10 \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; try { const response = await axios.get( `https://api.meshy.ai/openapi/v1/print/multi-color?page_size=10`, { headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/print/multi-color", headers=headers, params={"page_size": 10} ) response.raise_for_status() print(response.json()) ``` **Response** ```json [ { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "print-multi-color", "model_urls": { "3mf": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.3mf?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "preceding_tasks": 0, "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null } ] ``` --- ## GET /openapi/v1/print/multi-color/:id/stream -- Stream a Multi-Color 3D Print Task This endpoint streams real-time updates for a multi-color 3D print task using Server-Sent Events (SSE). ### Parameters - `id` · *path* Unique identifier for the multi-color 3D print task to stream. ### Returns Returns a stream of [The 3D Print Task Objects](#the-3d-print-task-object) as Server-Sent Events. For `PENDING` or `IN_PROGRESS` tasks, the response stream will only include necessary `progress` and `status` fields. **cURL** ```bash curl -N https://api.meshy.ai/openapi/v1/print/multi-color/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript const response = await fetch( 'https://api.meshy.ai/openapi/v1/print/multi-color/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream', { headers: { Authorization: `Bearer ${YOUR_API_KEY}` } } ); const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ''; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split('\n'); buffer = lines.pop(); for (const line of lines) { if (line.startsWith('data:')) { const data = JSON.parse(line.slice(5)); console.log(data); if (['SUCCEEDED', 'FAILED', 'CANCELED'].includes(data.status)) { reader.cancel(); } } } } ``` ```python import requests import json headers = { "Authorization": f"Bearer {YOUR_API_KEY}", "Accept": "text/event-stream" } response = requests.get( 'https://api.meshy.ai/openapi/v1/print/multi-color/a43b5c6d-7e8f-901a-234b-567c890d1e2f/stream', headers=headers, stream=True ) for line in response.iter_lines(): if line: if line.startswith(b'data:'): data = json.loads(line.decode('utf-8')[5:]) print(data) if data['status'] in ['SUCCEEDED', 'FAILED', 'CANCELED']: break response.close() ``` **Response Stream** ```javascript // Error event example event: error data: { "status_code": 404, "message": "Task not found" } // Message event examples illustrate task progress. // For PENDING or IN_PROGRESS tasks, the response stream will not include all fields. event: message data: { "id": "a43b5c6d-7e8f-901a-234b-567c890d1e2f", "progress": 0, "status": "PENDING" } event: message data: { "id": "a43b5c6d-7e8f-901a-234b-567c890d1e2f", "type": "print-multi-color", "model_urls": { "3mf": "https://assets.meshy.ai/***/tasks/a43b5c6d-7e8f-901a-234b-567c890d1e2f/output/model.3mf?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "preceding_tasks": 0, "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null } ``` --- ## The 3D Print Task Object - `id` · *string* Unique identifier for the task. While we use a k-sortable UUID for task ids as the implementation detail, you should **not** make any assumptions about the format of the id. - `type` · *string* Type of the 3D Print task. The value is `print-multi-color`. - `model_urls` · *object* Downloadable URL to the 3D model file generated by Meshy. The property for a format will be omitted if the format is not generated instead of returning an empty string. - `3mf` · *string* Downloadable URL to the multi-color 3MF file. - `progress` · *integer* Progress of the task. If the task is not started yet, this property will be `0`. Once the task has succeeded, this will become `100`. - `status` · *string* Status of the task. Possible values are one of `PENDING`, `IN_PROGRESS`, `SUCCEEDED`, `FAILED`. - `preceding_tasks` · *integer* The count of preceding tasks. > **Note:** The value of this field is meaningful only if the task status is `PENDING`. - `created_at` · *timestamp* Timestamp of when the task was created, in milliseconds. - `started_at` · *timestamp* Timestamp of when the task was started, in milliseconds. If the task is not started yet, this property will be `0`. - `finished_at` · *timestamp* Timestamp of when the task was finished, in milliseconds. If the task is not finished yet, this property will be `0`. - `task_error` · *object* Error information if the task has failed. This property is `null` if the task has not failed. See [Errors](/api/errors) for more details. - `message` · *string* Error message describing what went wrong. **The 3D Print Task Object** ```json { "id": "0193bfc5-ee4f-73f8-8525-44b398884ce9", "type": "print-multi-color", "model_urls": { "3mf": "https://assets.meshy.ai/***/tasks/0193bfc5-ee4f-73f8-8525-44b398884ce9/output/model.3mf?Expires=***" }, "progress": 100, "status": "SUCCEEDED", "preceding_tasks": 0, "created_at": 1699999999000, "started_at": 1700000000000, "finished_at": 1700000001000, "task_error": null } ``` --- # Balance API Source: https://docs.meshy.ai/api/balance # Balance API The Balance API allows you to retrieve the current credit balance for your account. This endpoint provides a simple way to check your available credits, which are used for various Meshy services. --- ## GET /openapi/v1/balance -- Get Balance This endpoint retrieves the current credit balance for the authenticated user. ### Returns Returns an object containing the current balance of credits. **cURL** ```bash curl https://api.meshy.ai/openapi/v1/balance \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios'; const headers = {Authorization: `Bearer ${YOUR_API_KEY}`}; try { const response = await axios.get('https://api.meshy.ai/openapi/v1/balance', {headers}); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/balance", headers=headers, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "balance": 1000 } ``` --- # Animation Library Source: https://docs.meshy.ai/api/animation-library # Animation Library Reference This page provides a comprehensive reference of all available animations in Meshy's [Animation API](/api/animation). Each animation is identified by a unique `action_id` that can be used when creating animation tasks. ## Available Animations Below is a complete list of animations available for use with the [Animation API](/api/animation). Use the `action_id` value when creating an animation task with the [`POST /openapi/v1/animations`](/api/animation#create-an-animation-task) endpoint. > The full list of available animations (with `action_id`, name, category, preview URL) is served as JSON at https://api.meshy.ai/web/public/animations/resources — fetch it directly to retrieve the current catalog. ## Usage Example To apply an animation to your rigged character, use the action_id in your API request: ```javascript const payload = { rig_task_id: "YOUR_RIGGING_TASK_ID", action_id: 92, // Double Combo Attack animation }; // Send this payload to the POST /openapi/v1/animations endpoint ``` For more details on how to create animation tasks, see the [Animation API documentation](/api/animation#create-an-animation-task). --- # Enterprise API Source: https://docs.meshy.ai/api/enterprise-api # Enterprise API Enterprise API is a feature that allows you to integrate Meshy's Enterprise capabilities into your own application. These API features are only available to users on our enterprise tier plan. In this section, you'll find all the information you need to get started with this API. --- ## GET /openapi/v1/showcases -- List Showcases This endpoint allows you to search and return community showcase models that are available for download. You may return up to 10 maximum models in a single request, and each request will cost 1 credit. ### Parameters #### Optional attributes - `page_size` · *integer* The number of showcase models to return. Must be a positive number between `1` and `10` inclusive. Note that it is possible that the request may return fewer than the requested number of matching models if there are not enough matches found. No models will be returned if no matches are found. Default is `3` models if `page_size` is not provided. - `sort_by` · *string* Method to sort the obtained search results. If not supplied, results will be sorted by creation time from most recent to earliest (`-created_at`). * `+created_at`: Sort by creation time in ascending order. * `-created_at`: Sort by creation time in descending order. * `+updated_at`: Sort by update time in ascending order. * `-updated_at`: Sort by update time in descending order. * `+downloads`: Sort by number of downloads in ascending order. * `-downloads`: Sort by number of downloads in descending order. - `search` · *string* Text to search for within community published (CC0) model names. If not provided, then top overall community models (based on `sort_by`) will be returned. - `format` · *string* Desired 3d model format for returned results. All models retrieved will be in the specified format. Must be one of the below optional values. If not provided, will be `glb` by default. * `glb`: glb format. * `fbx`: fbx format. * `obj`: obj format. * `usdz`: usdz format. - `showcase_type` · *string* Desired model type for returned results. All models retrieved will be in the specified type. Must be one of the below optional values. If not provided, will be `all` by default. * `all`: All showcase models. * `animated`: Animated showcase models. * `static`: Static showcase models. ### Returns - `id` · *string* The unique identifier for the showcase model. Although we use k-sortable UUID as the implementation detail for task id, you **should not** assume any format for the id. - `result_id` · *string* The unique identifier for the returned model result. This ID is linked to the model and can be used directly in other API tasks such as remesh. - `model_url` · *object* The URL of the downloadable 3D model with textures. Default returns glb format. - `conversion_status` · *string* The filetype conversion status of the returned models. * ``: Not converted (default glb). * `success`: Conversion successful. * `failed`: Conversion failed. - `community_url` · *string* The community browsing link of the showcase model. - `author` · *string* The author of the showcase model. - `topology` · *string* The topology of the showcase model (`quad` or `triangle`). - `name` · *string* The name of the showcase model. - `object_prompt` · *string* The description of the showcase model. - `categories` · *array* The categories of the showcase model. - `tags` · *array* The tags of the showcase model. - `mode` · *string* The mode of the showcase model. - `created_at` · *timestamp* The timestamp of the showcase model creation (milliseconds). - `updated_at` · *timestamp* The timestamp of the showcase model update (milliseconds). **cURL** ```bash curl "https://api.meshy.ai/openapi/v1/showcases?page_size=10&sort_by=-created_at&search=car&format=glb" \ -H "Authorization: Bearer ${YOUR_API_KEY}" ``` ```javascript import axios from 'axios' const headers = { Authorization: `Bearer ${YOUR_API_KEY}` }; const params = { page_size: 10, sort_by: "-created_at", search: "car", format: "glb" }; try { const response = await axios.get( 'https://api.meshy.ai/openapi/v1/showcases', { params, headers } ); console.log(response.data); } catch (error) { console.error(error); } ``` ```python import requests payload = { "page_size": 10, "sort_by": "+created_at", "search": "car", "format": "glb" } headers = { "Authorization": f"Bearer {YOUR_API_KEY}" } response = requests.get( "https://api.meshy.ai/openapi/v1/showcases", headers=headers, params=payload, ) response.raise_for_status() print(response.json()) ``` **Response** ```json { "result": [ { "id": "018a210d-8ba4-705c-b111-1f1776f7f578", "result_id": "018a210d-8ba4-705c-b111-1f1776f7f578", "model_url": "https://api.meshy.ai/v1/models/018a210d-8ba4-705c-b111-1f1776f7f578/model.glb", "conversion_status": "success", "community_url": "https://meshy.ai/showcase/018a210d-8ba4-705c-b111-1f1776f7f578", "author": "John Doe", "topology": "quad", "name": "Car", "object_prompt": "A car", "categories": ["vehicle"], "tags": ["car", "vehicle"], "mode": "3d", "created_at": 1717171717171, "updated_at": 1717171717171 } ] } ``` ---