lowpoly se retira el 30 oct 2026. Cambia de modelo antes de estas fechas para evitar errores en las solicitudes. Ver todas las obsolescencias

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/prototype
  • POST /openapi/creative-lab/keycap/v1/build

Ambos endpoints POST requieren un plan de pago. Una solicitud desde una cuenta con plan gratuito devuelve 402.


POST/openapi/creative-lab/keycap/v1/prototype

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

POST
/openapi/creative-lab/keycap/v1/prototype
# 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 name de la tarea. Un nombre más largo devuelve 400.

  • Name
    remove_background
    Type
    boolean
    predeterminado false
    Description

    Si se debe eliminar el fondo de la imagen del prototipo. true devuelve 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 enviaste true. La construcción devuelve esa imagen como process_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 404 o 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.

  • 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.


POST/openapi/creative-lab/keycap/v1/build

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

POST
/openapi/creative-lab/keycap/v1/build
# 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 estado SUCCEEDED.

    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_ids de la tarea de prototipo. Un valor que no esté en ese array devuelve 400.

  • Name
    name
    Type
    string
    Description

    Un nombre para la tarea, de hasta 100 caracteres. Se devuelve en el campo name de la tarea. Un nombre más largo devuelve 400.

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 devuelve 400.

  • 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 10 a 40. Meshy escala la cabeza para que su dimensión más larga coincida con este valor. Un valor fuera del rango devuelve 400.

    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 malla keycap-head en 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 -5 a 5. Un valor fuera del rango devuelve 400.

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.

Modos de fallo

  • Name
    400 - Bad Request
    Description

    La solicitud no puede ejecutarse. Por ejemplo:

    • input_task_id falta 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_id falta, o no está en el candidate_ids de la tarea de prototipo. Envía un valor de ese array.
    • Un campo en options está fuera de rango, o base_model no 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_id no 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 devuelve 404. Envía el ID de result de 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.


GET/openapi/creative-lab/keycap/v1/(prototype|build)/:id

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

GET
/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef
# 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

    id no es un ID de tarea válido. Envía el ID result de 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 /prototype o /build segú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.


DELETE/openapi/creative-lab/keycap/v1/(prototype|build)/:id

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

DELETE
/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef
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:

    • id no es un ID de tarea válido. Envía el ID result de la respuesta de creación.
    • La tarea ya tiene un estado final (SUCCEEDED, FAILED o CANCELED), 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 /prototype o /build para 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 status antes de reintentar.


GET/openapi/creative-lab/keycap/v1/(prototype|build)/:id/stream

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

GET
/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream
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.


GET/openapi/creative-lab/keycap/v1/(prototype|build)

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

GET
/openapi/creative-lab/keycap/v1/prototype
# 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, prototype o build.

Parámetros de consulta

  • Name
    page_num
    Type
    integer
    predeterminado 1
    Description

    La página a devolver, de 1 a 255. 0 devuelve la primera página. Un valor fuera del rango 0 a 255 devuelve 400.

  • Name
    page_size
    Type
    integer
    predeterminado 10
    Description

    Número de tareas por página, hasta 100. Un valor de 101 a 255 devuelve 100 tareas, y 0 usa el valor predeterminado. Un valor fuera del rango 0 a 255 devuelve 400.

  • 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 name que 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 cola
    • IN_PROGRESS: generando el resultado
    • SUCCEEDED: final, con el resultado
    • FAILED: final, con el motivo en task_error
    • CANCELED: final, sin resultado
  • Name
    progress
    Type
    integer
    Description

    Porcentaje del trabajo realizado, de 0 a 100. Es 0 hasta que la tarea comienza y 100 cuando 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. null hasta entonces.

  • Name
    finished_at
    Type
    timestamp
    Description

    Momento en que la tarea alcanzó un estado final, en milisegundos Unix. null hasta 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 de created_at hasta 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. 1 significa que empieza a continuación. 0 después de que la tarea sale de la cola, y siempre 0 en los resultados de listas.

  • Name
    task_error
    Type
    object
    Description

    Por qué falló la tarea. null a menos que status sea FAILED. 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 devuelve 500. 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 en candidate_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 encabezado Authorization. Permanecen válidas hasta expires_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 como candidate_id en 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 name que 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 cola
    • IN_PROGRESS: generando el resultado
    • SUCCEEDED: final, con el resultado
    • FAILED: final, con el motivo en task_error
    • CANCELED: final, sin resultado
  • Name
    progress
    Type
    integer
    Description

    Porcentaje del trabajo completado, de 0 a 100. Es 0 hasta que la tarea comienza y 100 cuando 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. null hasta entonces.

  • Name
    finished_at
    Type
    timestamp
    Description

    Momento en que la tarea alcanzó un estado final, en milisegundos Unix. null hasta 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 de created_at hasta 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. 1 significa que comienza a continuación. 0 después de que la tarea sale de la cola, y siempre 0 en los resultados de listas.

  • Name
    task_error
    Type
    object
    Description

    Por qué falló la tarea. null a menos que status sea FAILED. 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á en PENDING. Si Meshy no puede leer el cargo, una respuesta de obtención o transmisión omite el campo, y una solicitud de lista devuelve 500. 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-head y keycap-base. Cuando Meshy recurre a un relleno de patrón para la base, el modelo también tiene una malla keycap-base-interior para 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 hasta expires_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 usa model.mtl. Con una base de color sólido, la única textura es keycap-head.png. Con una base con patrón, el archivo ZIP también tiene keycap-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 encabezado Authorization. Permanecen válidas hasta expires_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:

  1. Crear una tarea de prototipo a partir de una foto.
  2. Consultar la tarea hasta que su status sea SUCCEEDED.
  3. Elegir un candidato de candidate_ids.
  4. Crear una tarea de construcción con ese candidato.
  5. Consultar la tarea de construcción hasta que su status sea SUCCEEDED.
  6. 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

POST
/openapi/creative-lab/keycap/v1
#!/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"