API de Keycap de Creative Lab
Convierte una foto en un keycap personalizado a todo color para un teclado mecánico en dos etapas. Una tarea de prototipo genera una imagen del keycap terminado a partir de la foto. Una tarea de construcción convierte esa imagen en un modelo de keycap 3D con textura. Toma el ID de la tarea de prototipo como input_task_id y el ID candidato de la imagen como candidate_id.
POST /openapi/creative-lab/keycap/v1/prototypePOST /openapi/creative-lab/keycap/v1/build
Ambos endpoints POST requieren un plan de pago. Una solicitud desde una cuenta con plan gratuito devuelve 402.
Crear una tarea de prototipo de Keycap
Genera una imagen del keycap terminado a partir de una foto. El campo image_urls de la tarea contiene la imagen, y candidate_ids contiene su ID, con una entrada en cada uno. Si no te gusta el diseño, crea otra tarea de prototipo. Meshy cobra por cada tarea de prototipo por separado.
Para construir el keycap en 3D, pasa el ID de esta tarea al endpoint de construcción como input_task_id, con la entrada de candidate_ids como candidate_id. Para conocer los campos de la tarea, consulta El objeto de tarea de prototipo de Keycap.
Request
# Stage 1: generate a finished-keycap design render
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"image_url": "<your publicly accessible image url or base64-encoded data URI>"
}'
Response
{
"result": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef"
}
Parámetros
- Name
- image_url
- Type
- string
- Requerido
- Description
La foto que se convertirá en un diseño de keycap, como una URL pública o un data URI (
data:image/jpeg;base64,<tus datos de imagen codificados en base64>).La imagen debe ser un archivo JPG, JPEG, PNG o WebP de un máximo de 20 MB (20,000,000 bytes). Cada lado debe medir al menos 32 píxeles, y la imagen puede tener como máximo 178,956,970 píxeles en total. Una imagen fuera de estos límites devuelve
400.Meshy detecta el formato a partir de los datos de la imagen, no de la extensión del archivo en la URL. Una URL sin extensión funciona, y Meshy sigue las redirecciones HTTP. Meshy aplica la orientación EXIF, de modo que una foto de teléfono rotada sale como se ve.
Un data URI debe estar codificado en base64 con un tipo de imagen, como
data:image/png;base64,..., y la imagen decodificada debe ser JPEG, PNG o WebP. El límite de 20 MB se aplica a la imagen decodificada, por lo que el texto base64 puede ser aproximadamente un tercio más grande.
- Name
- name
- Type
- string
- Description
Un nombre para la tarea, de hasta 100 caracteres. Se devuelve en el campo
namede la tarea. Un nombre más largo devuelve400.
- Name
- remove_background
- Type
- boolean
- predeterminado false
- Description
Si se debe eliminar el fondo de la imagen del prototipo.
truedevuelve un PNG RGBA transparente, de modo que puedas colocar el keycap sobre cualquier fondo. Si Meshy no puede eliminar el fondo, devuelve la imagen con su fondo, y la tarea aún así se completa correctamente.El diseño de la parte superior que la construcción convierte en 3D conserva su fondo en cualquier caso. La construcción pinta la base del keycap a partir de la imagen en
image_urls, sin su fondo si enviastetrue. La construcción devuelve esa imagen comoprocess_image_urls.composite.
Valores devueltos
El campo result contiene el ID de la nueva tarea de prototipo. Obtén la tarea o transmítela hasta que status sea SUCCEEDED. Luego pasa el ID al endpoint de construcción como input_task_id, con la entrada de candidate_ids como candidate_id.
Modos de fallo
- Name
400 - Bad Request- Description
La solicitud no puede ejecutarse. Por ejemplo:
- Falta
image_url. - La imagen no es un archivo JPG, JPEG, PNG o WebP.
- La imagen es demasiado pequeña, supera los 20 MB, o supera el número máximo de píxeles.
- Meshy no puede descargar la imagen, por ejemplo porque la URL devuelve
404o se agota el tiempo de espera. - El data URI no es un base64 válido.
- La imagen fue marcada como NSFW.
El mensaje de error indica qué problema encontró. Corrige la solicitud y envíala de nuevo.
- Falta
- Name
401 - Unauthorized- Description
La clave de API falta o no es válida. Verifica el encabezado
Authorization.
- Name
402 - Payment Required- Description
Se aplica una de las siguientes situaciones:
- La cuenta no tiene suficientes créditos.
- La clave de API, el espacio de trabajo o el miembro alcanzó su límite de créditos.
- La cuenta está en el plan gratuito.
Revisa tus créditos y tu plan, y luego vuelve a intentarlo.
- Name
403 - Forbidden- Description
Tu equipo tiene activado el Filtrado de IP, y Meshy marcó la imagen por propiedad intelectual de terceros. Envía una imagen sobre la que tengas los derechos de uso.
- Name
429 - Too Many Requests- Description
Se alcanzó uno de estos límites:
- Enviaste más solicitudes de las que permite tu límite de tasa. Espera unos segundos y vuelve a intentarlo. Consulta Límites de tasa.
- Hay demasiadas tareas tuyas en cola o en ejecución. Espera a que terminen algunas y vuelve a intentarlo.
- En un plan ilimitado sin créditos restantes, alcanzaste el número de tareas que pueden ejecutarse sin créditos. Espera a que termine una tarea, o añade créditos.
- Name
500 - Internal Server Error- Description
Meshy encontró un error del servidor, por ejemplo porque la moderación de contenido o la verificación de propiedad intelectual no pudieron ejecutarse, o porque Meshy no pudo almacenar la imagen. Meshy no crea la tarea y reembolsa cualquier crédito que haya cobrado. Vuelve a intentar la solicitud.
Crear una tarea de construcción de Keycap
Genera el keycap 3D con textura a partir de una tarea de prototipo exitosa y uno de sus candidatos. Para conocer sus campos, consulta El objeto de tarea de construcción de Keycap.
Una tarea de construcción ejecuta cada paso. Genera un modelo 3D a partir del diseño y lo colorea. Luego asienta y recorta el modelo sobre la base del keycap en una pose predeterminada calibrada, de modo que no necesitas ajustarla manualmente. Por último, ensambla el keycap y exporta los archivos. Una construcción normalmente tarda de 3 a 7 minutos.
Request
# Stage 2: build the chosen candidate into a 3D keycap
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build \
-X POST \
-H "Authorization: Bearer ${YOUR_API_KEY}" \
-H 'Content-Type: application/json' \
-d '{
"input_task_id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
"candidate_id": "0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b",
"options": {
"base_model": "cherry-mx-1x1-r1",
"head_size_mm": 23,
"vertical_offset_mm": 0
}
}'
Response
{
"result": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af"
}
Parámetros
- Name
- input_task_id
- Type
- string
- Requerido
- Description
El ID de la tarea de prototipo a construir. Debe ser una tarea creada por tu cuenta con
POST /openapi/creative-lab/keycap/v1/prototype, con el estadoSUCCEEDED.Un ID que no corresponda a una de tus tareas de prototipo de Keycap de la API devuelve
404, incluido un prototipo creado en la aplicación web.
- Name
- candidate_id
- Type
- string
- Requerido
- Description
El candidato a construir, del array
candidate_idsde la tarea de prototipo. Un valor que no esté en ese array devuelve400.
- Name
- name
- Type
- string
- Description
Un nombre para la tarea, de hasta 100 caracteres. Se devuelve en el campo
namede la tarea. Un nombre más largo devuelve400.
options
Configuraciones de geometría opcionales. Cada campo tiene un valor predeterminado calibrado, así que envía solo los campos que quieras cambiar.
- Name
- base_model
- Type
- string
- predeterminado cherry-mx-1x1-r1
- Description
La base de keycap sobre la que construir. El único valor es
cherry-mx-1x1-r1, un keycap estándar de perfil Cherry MX de 1u. No se admiten tamaños personalizados, y cualquier otro valor devuelve400.
- Name
- head_size_mm
- Type
- number
- predeterminado 23
- Description
El tamaño de la cabeza a lo largo de su dimensión más larga, en milímetros, de
10a40. Meshy escala la cabeza para que su dimensión más larga coincida con este valor. Un valor fuera del rango devuelve400.Para un valor superior a aproximadamente
32.9, Meshy podría reducir el tamaño para que la cabeza se ajuste al límite de huella protectora de la base. La cabeza puede entonces resultar más pequeña de lo solicitado. El objeto de la tarea no devuelve el tamaño que aplicó Meshy. Para comprobarlo, mide la caja delimitadora de la mallakeycap-headen el modelo.
- Name
- vertical_offset_mm
- Type
- number
- predeterminado 0
- Description
El desplazamiento vertical que se aplica a la cabeza antes de que Meshy la asiente sobre la base, en milímetros, de
-5a5. Un valor fuera del rango devuelve400.
Devuelve
El campo result contiene el ID de la nueva tarea de construcción. Obtén la tarea o transmítela hasta que status sea SUCCEEDED. Luego descarga el archivo GLB desde model_urls.glb y el paquete OBJ desde model_urls.obj_zip.
Meshy exporta el archivo GLB y el paquete OBJ a escala real en milímetros. Ambos usan un sistema de coordenadas con el eje Y hacia arriba, con el frente del keycap orientado hacia +Z.
Modos de fallo
- Name
400 - Bad Request- Description
La solicitud no puede ejecutarse. Por ejemplo:
input_task_idfalta o no es un ID de tarea válido.- El estado de la tarea de prototipo no es
SUCCEEDED. Si todavía se está ejecutando, espera y vuelve a intentarlo. Si falló o fue cancelada, crea una nueva tarea de prototipo. - La tarea de prototipo tuvo éxito pero no tiene candidatos. Crea una nueva tarea de prototipo.
candidate_idfalta, o no está en elcandidate_idsde la tarea de prototipo. Envía un valor de ese array.- Un campo en
optionsestá fuera de rango, obase_modelno es un valor disponible.
El mensaje de error indica qué problema encontró.
- Name
401 - Unauthorized- Description
Falta la clave de API o no es válida. Revisa el encabezado
Authorization.
- Name
402 - Payment Required- Description
Se aplica uno de los siguientes casos:
- La cuenta no tiene suficientes créditos.
- La clave de API, el espacio de trabajo o el miembro alcanzó su límite de créditos.
- La cuenta está en el plan gratuito.
Revisa tus créditos y tu plan, luego vuelve a intentarlo.
- Name
404 - Not Found- Description
input_task_idno coincide con ninguna tarea de prototipo de Keycap que tu cuenta haya creado con la API. Un prototipo creado en la aplicación web también devuelve404. Envía el ID deresultde una respuesta de creación de prototipo.
- Name
429 - Too Many Requests- Description
Se alcanzó uno de estos límites:
- Enviaste más solicitudes de las que permite tu límite de tasa. Espera unos segundos y vuelve a intentarlo. Consulta Límites de tasa.
- Hay demasiadas tareas tuyas en cola o en ejecución. Espera a que algunas terminen y vuelve a intentarlo.
- En un plan ilimitado sin créditos restantes, alcanzaste el número de tareas que pueden ejecutarse sin créditos. Espera a que termine una tarea, o añade créditos.
- Name
500 - Internal Server Error- Description
Meshy no pudo crear la tarea debido a un error del servidor. Meshy reembolsa cualquier crédito que haya cobrado. Vuelve a intentar la solicitud.
Obtener una tarea de Keycap
Devuelve una tarea de prototipo o de build. La ruta debe coincidir con la etapa de la tarea. Una tarea de build solicitada a través de /prototype/:id devuelve 404, y lo mismo ocurre con una tarea de prototipo solicitada a través de /build/:id.
Para conocer los campos, consulta El objeto de tarea de prototipo de Keycap y El objeto de tarea de build de Keycap.
Request
# Prototype
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef \
-H "Authorization: Bearer ${YOUR_API_KEY}"
# Build
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Prototype Response
{
"id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
"type": "creative-lab-keycap-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142456000,
"started_at": 1753142460000,
"finished_at": 1753142516000,
"expires_at": 1753401716000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 12,
"image_urls": [
"https://assets.meshy.ai/***/design-1.png?Expires=***"
],
"candidate_ids": [
"0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
]
}
Build Response
{
"id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
"type": "creative-lab-keycap-build",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142600000,
"started_at": 1753142610000,
"finished_at": 1753143050000,
"expires_at": 1753402250000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 50,
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
"obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
},
"process_image_urls": {
"head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***",
"composite": "https://assets.meshy.ai/***/composite.png?Expires=***",
"base_canvas": "https://assets.meshy.ai/***/base-canvas.png?Expires=***"
}
}
Parámetros
- Name
- id
- Type
- path
- Description
El ID de la tarea proveniente de la respuesta de creación.
Devuelve
El objeto de tarea de prototipo o el objeto de tarea de build, según coincida con la etapa en la ruta.
Modos de falla
- Name
400 - Bad Request- Description
idno es un ID de tarea válido. Envía el IDresultde la respuesta de creación.
- Name
403 - Forbidden- Description
Tu equipo tiene activado el Filtrado de IP, y Meshy marcó la imagen de la tarea de prototipo por propiedad intelectual de terceros. Las tareas de build y los equipos en el plan Enterprise no reciben este error. Crea una tarea de prototipo a partir de una imagen sobre la que tengas derechos de uso.
- Name
404 - Not Found- Description
No hay ninguna tarea de Keycap con este ID que pertenezca a tu cuenta, o la etapa de la tarea no coincide con la ruta. Verifica el ID y usa
/prototypeo/buildsegún corresponda a la tarea.
- Name
500 - Internal Server Error- Description
Meshy no pudo ejecutar la verificación de propiedad intelectual. Vuelve a intentar la solicitud.
Eliminar una tarea de Keycap
Cancela una tarea de Keycap. Cancelar una tarea PENDING reembolsa sus créditos. Una tarea IN_PROGRESS se cancela sin reembolso, porque un worker ya la ha iniciado. Una tarea con un estado final (SUCCEEDED, FAILED o CANCELED) no se puede cancelar.
La ruta debe coincidir con la etapa de la tarea. Por ejemplo, DELETE en /prototype/:id con el ID de una tarea de build devuelve 404.
Request
curl --request DELETE \
--url https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response
// Returns 204 No Content on success (empty body).
Parámetros de ruta
- Name
- id
- Type
- path
- Description
El ID de la tarea a cancelar.
Devuelve
204 No Content con un cuerpo vacío.
Modos de fallo
- Name
400 - Bad Request- Description
Se aplica uno de los siguientes casos:
idno es un ID de tarea válido. Envía el IDresultde la respuesta de creación.- La tarea ya tiene un estado final (
SUCCEEDED,FAILEDoCANCELED), por lo que no se puede cancelar.
- Name
404 - Not Found- Description
Ninguna tarea de Keycap con este ID pertenece a tu cuenta, o la etapa de la tarea no coincide con la ruta. Verifica el ID y usa
/prototypeo/buildpara que coincida con la tarea.
- Name
500 - Internal Server Error- Description
Meshy encontró un error de servidor al cancelar la tarea, por lo que la tarea podría estar cancelada o no. Obtén la tarea para verificar su
statusantes de reintentar.
Transmitir una tarea de Keycap en streaming
Transmite las actualizaciones de una tarea de Keycap como Server-Sent Events (SSE). La ruta debe coincidir con la etapa de la tarea. Si no coincide, por ejemplo el ID de una tarea de build en /prototype/:id/stream, el stream envía un único evento error con status_code: 404 y se cierra.
Request
curl -N https://api.meshy.ai/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response Stream
// Error event example (wrong stage or task not found)
event: error
data: {
"status_code": 404,
"message": "Task not found"
}
// Message event examples illustrate task progress.
// Every frame is the full task object; fields not yet populated are null / empty.
// The following PENDING frame is shortened to the fields that change.
event: message
data: {
"id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
"progress": 0,
"status": "PENDING"
}
event: message
data: {
"id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
"type": "creative-lab-keycap-build",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142600000,
"started_at": 1753142610000,
"finished_at": 1753143050000,
"expires_at": 1753402250000,
"task_error": null,
"consumed_credits": 50,
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
"obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
},
"process_image_urls": {
"head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***"
}
}
Parámetros
- Name
- id
- Type
- path
- Description
El ID de la tarea proveniente de la respuesta de creación.
Devuelve
Un stream de objetos de tarea prototype o build. Cada evento contiene el objeto de tarea completo, tal como lo devuelve Obtener una tarea de Keycap. Mientras la tarea esté en PENDING o IN_PROGRESS, sus campos de salida siguen vacíos (null, [] o {}), y finished_at es null.
Si el filtrado de IP bloquea el resultado de la tarea, el stream envía en su lugar un evento error, con el status_code que devolvería una solicitud get.
Listar tareas de Keycap
Devuelve tus tareas de Keycap de una etapa, una página a la vez. La ruta selecciona la etapa. /prototype devuelve solo tareas de prototipo, y /build devuelve solo tareas de compilación.
Request
# List prototype tasks
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
# List build tasks
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build?page_size=10 \
-H "Authorization: Bearer ${YOUR_API_KEY}"
Response (List Prototype Tasks)
[
{
"id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
"type": "creative-lab-keycap-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142456000,
"started_at": 1753142460000,
"finished_at": 1753142516000,
"expires_at": 1753401716000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 12,
"image_urls": [
"https://assets.meshy.ai/***/design-1.png?Expires=***"
],
"candidate_ids": [
"0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
]
}
]
Parámetros de ruta
- Name
- stage
- Type
- path
- Requerido
- Description
La etapa a listar,
prototypeobuild.
Parámetros de consulta
- Name
- page_num
- Type
- integer
- predeterminado 1
- Description
La página a devolver, de
1a255.0devuelve la primera página. Un valor fuera del rango0a255devuelve400.
- Name
- page_size
- Type
- integer
- predeterminado 10
- Description
Número de tareas por página, hasta
100. Un valor de101a255devuelve 100 tareas, y0usa el valor predeterminado. Un valor fuera del rango0a255devuelve400.
- Name
- sort_by
- Type
- string
- predeterminado -created_at
- Description
El orden de clasificación.
Valores disponibles:
-created_at: más recientes primero+created_at: más antiguos primero
Devuelve
Un arreglo de objetos de tarea de prototipo o objetos de tarea de compilación, según la etapa en la ruta.
El objeto de tarea de prototipo de Keycap
Una tarea de prototipo genera una imagen del keycap terminado a partir de una foto. Para convertir el diseño en un keycap 3D, pasa el ID de la tarea al endpoint de build como input_task_id, junto con su entrada candidate_ids como candidate_id.
Propiedades
Example Keycap Prototype Task Object
{
"id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
"type": "creative-lab-keycap-prototype",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142456000,
"started_at": 1753142460000,
"finished_at": 1753142516000,
"expires_at": 1753401716000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 12,
"image_urls": [
"https://assets.meshy.ai/***/design-1.png?Expires=***"
],
"candidate_ids": [
"0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
]
}
- Name
- id
- Type
- string
- Description
El ID de la tarea. No dependas de su formato.
- Name
- type
- Type
- string
- Description
El tipo de tarea, siempre
creative-lab-keycap-prototype.
- Name
- name
- Type
- string
- Description
El
nameque enviaste al crear la tarea, o""si no enviaste ninguno.
- Name
- status
- Type
- string
- Description
El estado de la tarea.
Valores disponibles:
PENDING: esperando en la colaIN_PROGRESS: generando el resultadoSUCCEEDED: final, con el resultadoFAILED: final, con el motivo entask_errorCANCELED: final, sin resultado
- Name
- progress
- Type
- integer
- Description
Porcentaje del trabajo realizado, de
0a100. Es0hasta que la tarea comienza y100cuando tiene éxito.
- Name
- created_at
- Type
- timestamp
- Description
Momento en que se creó la tarea, en milisegundos Unix.
- Name
- started_at
- Type
- timestamp
- Description
Momento en que un worker comenzó la tarea, en milisegundos Unix.
nullhasta entonces.
- Name
- finished_at
- Type
- timestamp
- Description
Momento en que la tarea alcanzó un estado final, en milisegundos Unix.
nullhasta entonces.
- Name
- expires_at
- Type
- timestamp
- Description
Momento en que expira el resultado de la tarea, en milisegundos Unix. Son 3 días después de
finished_at, o 3 días después decreated_athasta que la tarea termine. Para cuentas Enterprise, que conservan los resultados de la API indefinidamente, es aproximadamente 100 años después. Consulta Retención de recursos.
- Name
- preceding_tasks
- Type
- integer
- Description
La posición de la tarea en la cola mientras está
PENDING.1significa que empieza a continuación.0después de que la tarea sale de la cola, y siempre0en los resultados de listas.
- Name
- task_error
- Type
- object
- Description
Por qué falló la tarea.
nulla menos questatusseaFAILED. Consulta Errores.
- Name
- consumed_credits
- Type
- integer
- Description
Número de créditos cobrados por la tarea, después de cualquier reembolso. Una solicitud que devuelve un error no se cobra. Una tarea fallida es
0, porque Meshy la reembolsa. Cancelar reembolsa una tarea solo mientras estáPENDING. Si Meshy no puede leer el cargo, una respuesta de get o stream omite el campo, y una solicitud de lista devuelve500. En ese caso, vuelve a intentar la solicitud.
- Name
- image_urls
- Type
- array of strings
- Description
URLs de descarga para la imagen del keycap terminado. El array tiene una URL después de que la tarea tiene éxito, y está vacío hasta entonces.
image_urls[i]muestra el candidato encandidate_ids[i].Estas URLs son para visualización. El endpoint de build toma una entrada de
candidate_ids, no una URL. Son URLs firmadas, así que recupéralas sin un encabezadoAuthorization. Permanecen válidas hastaexpires_at, y obtener la tarea de nuevo devuelve las mismas URLs.
- Name
- candidate_ids
- Type
- array of strings
- Description
IDs de los candidatos, en el mismo orden que
image_urls. Para construir un candidato, envía su ID comocandidate_iden la solicitud de build. No dependas del formato de estos IDs.
El objeto de la tarea de construcción de Keycap
Una tarea de construcción genera el keycap 3D con textura a partir de una tarea de prototipo exitosa y uno de sus candidatos. Genera el modelo 3D, lo colorea, lo asienta y lo recorta sobre la base del keycap, y luego ensambla y exporta el keycap.
Propiedades
Example Keycap Build Task Object
{
"id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
"type": "creative-lab-keycap-build",
"name": "",
"status": "SUCCEEDED",
"progress": 100,
"created_at": 1753142600000,
"started_at": 1753142610000,
"finished_at": 1753143050000,
"expires_at": 1753402250000,
"preceding_tasks": 0,
"task_error": null,
"consumed_credits": 50,
"model_urls": {
"glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
"obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
},
"process_image_urls": {
"head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***",
"composite": "https://assets.meshy.ai/***/composite.png?Expires=***",
"base_canvas": "https://assets.meshy.ai/***/base-canvas.png?Expires=***"
}
}
- Name
- id
- Type
- string
- Description
El ID de la tarea. No dependas de su formato.
- Name
- type
- Type
- string
- Description
El tipo de tarea, siempre
creative-lab-keycap-build.
- Name
- name
- Type
- string
- Description
El
nameque enviaste al crear la tarea, o""si no enviaste ninguno.
- Name
- status
- Type
- string
- Description
El estado de la tarea.
Valores disponibles:
PENDING: esperando en la colaIN_PROGRESS: generando el resultadoSUCCEEDED: final, con el resultadoFAILED: final, con el motivo entask_errorCANCELED: final, sin resultado
- Name
- progress
- Type
- integer
- Description
Porcentaje del trabajo completado, de
0a100. Es0hasta que la tarea comienza y100cuando tiene éxito.
- Name
- created_at
- Type
- timestamp
- Description
Momento en que se creó la tarea, en milisegundos Unix.
- Name
- started_at
- Type
- timestamp
- Description
Momento en que un worker comenzó la tarea, en milisegundos Unix.
nullhasta entonces.
- Name
- finished_at
- Type
- timestamp
- Description
Momento en que la tarea alcanzó un estado final, en milisegundos Unix.
nullhasta entonces.
- Name
- expires_at
- Type
- timestamp
- Description
Momento en que expira el resultado de la tarea, en milisegundos Unix. Es 3 días después de
finished_at, o 3 días después decreated_athasta que la tarea termine. Para cuentas Enterprise, que conservan los resultados de la API indefinidamente, es aproximadamente 100 años después. Consulta Retención de recursos.
- Name
- preceding_tasks
- Type
- integer
- Description
La posición de la tarea en la cola mientras está en
PENDING.1significa que comienza a continuación.0después de que la tarea sale de la cola, y siempre0en los resultados de listas.
- Name
- task_error
- Type
- object
- Description
Por qué falló la tarea.
nulla menos questatusseaFAILED. Consulta Errores.
- Name
- consumed_credits
- Type
- integer
- Description
Número de créditos cobrados por la tarea, después de cualquier reembolso. Una solicitud que devuelve un error no se cobra. Una tarea fallida es
0, porque Meshy la reembolsa. Cancelar reembolsa una tarea solo mientras está enPENDING. Si Meshy no puede leer el cargo, una respuesta de obtención o transmisión omite el campo, y una solicitud de lista devuelve500. En ese caso, reintenta la solicitud.
- Name
- model_urls
- Type
- object
- Description
URLs de descarga para el modelo 3D. Meshy exporta el archivo GLB y el paquete OBJ a escala real en milímetros, con el eje Y hacia arriba, con el frente del keycap mirando hacia +Z.
El modelo tiene mallas llamadas
keycap-headykeycap-base. Cuando Meshy recurre a un relleno de patrón para la base, el modelo también tiene una mallakeycap-base-interiorpara la cavidad del vástago. No asumas que el modelo tiene exactamente dos mallas.Estas son URLs firmadas, así que obténlas sin un encabezado
Authorization. Permanecen válidas hastaexpires_at, y obtener la tarea de nuevo antes de ese momento devuelve las mismas URLs. Una URL expirada no se puede renovar, así que descarga y almacena los archivos antes de ese momento.- Name
glb- Type
- string
- Description
URL de descarga para el archivo GLB con textura,
model.glb.
- Name
obj_zip- Type
- string
- Description
URL de descarga para el paquete OBJ, un archivo ZIP con
model.obj,model.mtl, y las texturas PNG que usamodel.mtl. Con una base de color sólido, la única textura eskeycap-head.png. Con una base con patrón, el archivo ZIP también tienekeycap-base.png.
- Name
- process_image_urls
- Type
- object
- Description
URLs de descarga para imágenes de los pasos de la construcción, organizadas por tipo. Al igual que
model_urls, son URLs firmadas, así que obténlas sin un encabezadoAuthorization. Permanecen válidas hastaexpires_at, y obtener la tarea de nuevo devuelve las mismas URLs.Puede tener estas claves:
head_design: la imagen de diseño del candidato elegido, que la construcción convirtió en 3D. Siempre presente.composite: la imagen del keycap terminado para el candidato elegido, a partir de la cual la construcción pintó la base. Puede faltar.base_canvas: la base del keycap pintada. Puede faltar.
Meshy puede agregar claves, así que ignora cualquier clave que no reconozcas.
Ejemplo de principio a fin
El ejemplo ejecuta todo el flujo:
- Crear una tarea de prototipo a partir de una foto.
- Consultar la tarea hasta que su
statusseaSUCCEEDED. - Elegir un candidato de
candidate_ids. - Crear una tarea de construcción con ese candidato.
- Consultar la tarea de construcción hasta que su
statusseaSUCCEEDED. - Descargar el archivo GLB y el paquete OBJ desde
model_urls.
El ejemplo elige el primer candidato. En tu aplicación, muestra las entradas de image_urls a tus usuarios y deja que elijan. El índice de una imagen elegida en image_urls es el índice de su ID en candidate_ids.
Complete flow
#!/usr/bin/env bash
set -euo pipefail
# Requires curl and jq. Point IMAGE_PATH at a local photo, or IMAGE_URL at a public one:
# export MESHY_API_KEY=msy_...
# export IMAGE_PATH=./portrait.jpg # or: export IMAGE_URL=https://...
: "${MESHY_API_KEY:?export MESHY_API_KEY first}"
if [[ -z "${IMAGE_PATH:-}" && -z "${IMAGE_URL:-}" ]]; then
echo "export IMAGE_PATH (local file) or IMAGE_URL (public url) first" >&2
exit 1
fi
BASE="https://api.meshy.ai/openapi/creative-lab/keycap/v1"
AUTH="Authorization: Bearer $MESHY_API_KEY"
# api METHOD URL [curl args...] -> prints the response body, non-zero on failure.
# Note we do not use -f/--fail: it discards the body, and the body is the only
# place the reason appears.
api() {
local method=$1 url=$2 out http_code body
shift 2
out=$(curl --silent --show-error --max-time 60 --write-out $'\n%{http_code}' \
-X "$method" "$url" -H "$AUTH" "$@") || return 1
http_code=${out##*$'\n'}
body=${out%$'\n'*}
if ((http_code >= 400)); then
echo "HTTP $http_code for $url: $body" >&2
return 1
fi
printf '%s' "$body"
}
# Each task gets its own 40-minute budget.
poll() {
local kind=$1 id=$2 delay=5 task_status deadline
deadline=$(($(date +%s) + 2400))
while :; do
if (($(date +%s) >= deadline)); then
echo "gave up waiting for $kind $id" >&2
return 1
fi
task_status=$(api GET "$BASE/$kind/$id" | jq -r '.status')
echo "$kind: $task_status"
case "$task_status" in
SUCCEEDED) return 0 ;;
FAILED | CANCELED) return 1 ;;
esac
sleep "$delay"
delay=$((delay * 2 > 30 ? 30 : delay * 2))
done
}
# Build the request body in a file. A base64 data URI must never go on the
# command line or into an exported variable - a photo of any real size will
# exceed the OS argument limit.
BODY=$(mktemp)
trap 'rm -f "$BODY"' EXIT
if [[ -n "${IMAGE_PATH:-}" ]]; then
# Declare the real type: the API accepts JPEG, PNG and WebP.
case "$(printf '%s' "${IMAGE_PATH##*.}" | tr 'A-Z' 'a-z')" in
png) MIME=image/png ;;
webp) MIME=image/webp ;;
*) MIME=image/jpeg ;;
esac
{
printf '{"image_url":"data:%s;base64,' "$MIME"
base64 <"$IMAGE_PATH" | tr -d '\n'
printf '"}'
} >"$BODY"
else
printf '{"image_url":"%s"}' "$IMAGE_URL" >"$BODY"
fi
# 1. Create the prototype task
PROTO_ID=$(api POST "$BASE/prototype" \
-H 'Content-Type: application/json' --data-binary @"$BODY" | jq -r '.result')
# 2. Wait for the design render
poll prototype "$PROTO_ID"
# 3. Pick a candidate (first one here; show image_urls to a user in production)
CANDIDATE_ID=$(api GET "$BASE/prototype/$PROTO_ID" | jq -r '.candidate_ids[0]')
# 4. Create the build task
jq -n --arg p "$PROTO_ID" --arg c "$CANDIDATE_ID" \
'{input_task_id: $p, candidate_id: $c}' >"$BODY"
BUILD_ID=$(api POST "$BASE/build" \
-H 'Content-Type: application/json' --data-binary @"$BODY" | jq -r '.result')
# 5. Wait for the model (a build usually takes 3-7 minutes)
poll build "$BUILD_ID"
# 6. Download the artifacts. These are signed URLs: no Authorization header,
# and they stay valid for 3 days after the task finishes.
TASK=$(api GET "$BASE/build/$BUILD_ID")
curl --silent --show-error --fail --max-time 900 \
-o keycap.glb "$(jq -r '.model_urls.glb' <<<"$TASK")"
curl --silent --show-error --fail --max-time 900 \
-o keycap-obj.zip "$(jq -r '.model_urls.obj_zip' <<<"$TASK")"
echo "Done: keycap.glb + keycap-obj.zip"