Convierte una foto de origen en un tablero fidget de pixel art multicolor
imprimible en 3D en dos etapas: prototipo pixela tu foto en una imagen de
pixel art, luego construcción muestrea esa imagen en una cuadrícula de
16×16 o 32×32 y convierte cada píxel en una pieza cuadrada o hexagonal
entrelazada, entregada como un único 3MF cuyos objetos llevan sus colores para
que un laminador multifilamento imprima cada pieza en el color correcto. Las
dos etapas están vinculadas mediante input_task_id.
POST /openapi/creative-lab/fidget-pixel/v1/prototype
POST /openapi/creative-lab/fidget-pixel/v1/build
Ambos endpoints POST requieren un plan de suscripción de pago. Las
solicitudes de cuentas del plan gratuito se rechazan con 402 Payment Required.
Genera una única imagen de pixel-art a partir de la foto de origen. El ID de tarea devuelto es lo que se pasa como input_task_id al endpoint de build. Vuelve a llamar a este endpoint para obtener otro intento si el resultado no es el que deseas — cada llamada se factura por separado. Consulta
El objeto de tarea de prototipo de Fidget Pixel
para conocer la forma de la respuesta.
Parámetros
Name
image_url
Type
string
Requerido
Description
Foto de origen para que Meshy la pixelice. Actualmente admitimos los formatos .jpg, .jpeg, .png y .webp.
El formato se detecta decodificando los datos de la imagen, no a partir de la extensión de archivo de la URL — una URL sin extensión, o una que redirige, funciona siempre que los bytes se decodifiquen a un formato compatible. Se siguen las redirecciones HTTP.
Hay dos formas de proporcionar la imagen:
URL de acceso público: Una URL accesible desde internet de forma pública.
Data URI: Un Data URI en base64 de la imagen. Ejemplo de un Data URI: data:image/jpeg;base64,<tus datos de imagen codificados en base64>.
Name
type
Type
string
Requerido
Description
Lo que muestra la foto. Selecciona el estilo de pixelización, así que elige con cuidado — las dos opciones producen resultados visiblemente diferentes. Valores disponibles:
person — el sujeto es una persona (retrato o cuerpo completo). Produce un sprite de pixel-art estilo chibi del sujeto.
other — cualquier otra cosa: mascotas, objetos, mascotas de marca, logotipos, paisajes. Produce un icono de pixel-art estilo bead-art del sujeto.
Name
name
Type
string
Description
Nombre de tarea opcional para fines de visualización. Máximo 100 caracteres.
Devuelve
La propiedad result de la respuesta contiene el id de tarea de la tarea de prototipo de fidget pixel recién creada. Consulta periódicamente el endpoint Obtener una tarea o suscríbete al stream hasta que la tarea alcance el estado SUCCEEDED, y luego pasa ese ID al endpoint de build como input_task_id.
Modos de fallo
Name
400 - Bad Request
Description
La solicitud no era aceptable. Causas comunes:
Parámetro faltante: image_url y type son ambos obligatorios.
Tipo no válido: type debe ser person o other.
Formato de imagen no válido: El image_url proporcionado no tiene un formato compatible (.jpg, .jpeg, .png, .webp).
Dimensiones de imagen fuera de rango: La imagen es demasiado pequeña, supera el tamaño máximo de archivo o supera el número máximo de píxeles.
URL inalcanzable: No se pudo descargar el image_url (404 o timeout).
Data URI no válido: La cadena en base64 está malformada.
Contenido marcado: La imagen de entrada fue marcada por la moderation de contenido NSFW.
Name
401 - Unauthorized
Description
Error de autenticación. Comprueba tu clave de API.
Name
402 - Payment Required
Description
Créditos insuficientes para realizar esta tarea, o la clave de API pertenece a una cuenta de plan gratuito.
Name
403 - Forbidden
Description
La imagen de entrada fue marcada por la moderation de propiedad intelectual (Content flagged for intellectual property violation). Solo se bloquean las cuentas Enterprise con el filtrado de propiedad intelectual activado; no se cobra nada.
Name
429 - Too Many Requests
Description
Has superado tu límite de tasa.
Name
500 - Internal Server Error
Description
No se pudo completar la propia verificación de propiedad intelectual (Unable to perform intellectual property check, please try again). Las cuentas Enterprise con el filtrado de propiedad intelectual activado fallan de forma segura (fail closed) en esta verificación; no se cobra nada — vuelve a intentar la solicitud.
Request
POST
/openapi/creative-lab/fidget-pixel/v1/prototype
# Stage 1: pixelize the source photocurlhttps://api.meshy.ai/openapi/creative-lab/fidget-pixel/v1/prototype \-XPOST \-H"Authorization: Bearer ${YOUR_API_KEY}" \-H'Content-Type: application/json' \-d'{ "image_url": "<your publicly accessible image url or base64-encoded data URI>", "type": "person" }'
Genera las piezas imprimibles en 3D a partir de una tarea de prototipo exitosa. La
construcción muestrea la imagen de pixel art del prototipo sobre la cuadrícula
solicitada, la cuantiza a un máximo de color_count colores y genera una
pieza entrelazable por celda de la cuadrícula. El entregable es un único 3MF en
el que cada pieza es un objeto separado etiquetado con su color, listo para un
laminador multi-filamento. Consulta
El objeto de tarea de construcción de Fidget Pixel
para conocer la forma de la respuesta.
Parámetros
Name
input_task_id
Type
string
Requerido
Description
El ID de tarea de una tarea de prototipo creada a través de este mismo endpoint de OpenAPI. El prototipo debe haber sido creado por la misma cuenta de Meshy y debe haber alcanzado SUCCEEDED.
Las tareas de prototipo creadas a través de la aplicación web no se aceptan — el endpoint de construcción solo acepta tareas de prototipo producidas por POST /openapi/creative-lab/fidget-pixel/v1/prototype y rechaza cualquier otra fuente con 404.
Name
name
Type
string
Description
Nombre de tarea opcional para fines de visualización. Máximo 100 caracteres.
options
Geometría de pieza opcional. Cada campo tiene un valor predeterminado — envía solo los que quieras sobrescribir. Estos son los mismos controles que expone la aplicación web de Creative Lab; la altura del tapón, la escala de la tapa y los demás preajustes de fabricación se derivan de shape y piece_size_mm y no están expuestos.
Name
shape
Type
string
predeterminado square
Description
Forma de la base de cada pieza. Valores disponibles:
square (predeterminado) — piezas cuadradas en una cuadrícula cuadrada.
hex — piezas hexagonales en una cuadrícula hexagonal. Las piezas hexagonales están disponibles solo en 6 y 8 mm.
Name
grid_size
Type
integer
predeterminado 32
Description
Número de piezas a lo largo de cada lado del tablero. Valores disponibles: 16 o 32. Una cuadrícula de 32 conserva más detalle; una cuadrícula de 16 significa piezas menos numerosas y más grandes para el mismo sujeto.
Name
piece_size_mm
Type
integer
predeterminado 8
Description
Longitud de arista de cada pieza, en milímetros. Valores disponibles: 6, 8 o 10. Junto con grid_size, esto establece el tamaño del tablero impreso — por ejemplo 32 × 8 mm ≈ 26 cm por lado. 10 no está disponible para shape: "hex" (la cara hexagonal inclinada genera voladizos en la mayoría de las impresoras FDM de consumo).
Name
color_count
Type
integer
predeterminado 8
Description
Número máximo de colores en la paleta a la que se cuantiza la imagen. Rango: [1, 8]. Cada color se convierte en un filamento en tu laminador.
Name
piece_height_mm
Type
integer
predeterminado 15
Description
Altura de cada pieza, en milímetros. Rango: [10, 80].
output
Selector de formato de salida opcional. Por defecto es 3mf, que actualmente es el único valor admitido.
Name
format
Type
string
predeterminado 3mf
Description
Artefacto devuelto por la construcción. Valores disponibles:
3mf (predeterminado) — devuelve un único model.3mf bajo model_urls.3mf, con un objeto por pieza y el color de la pieza adjunto a cada objeto.
Devuelve
La propiedad result de la respuesta contiene el id de tarea de la tarea de construcción de fidget pixel recién creada. Consulta periódicamente el endpoint Obtener una tarea o suscríbete al stream hasta que la tarea alcance SUCCEEDED, y luego descarga el artefacto desde model_urls.3mf.
Modos de fallo
Name
400 - Bad Request
Description
La solicitud fue inaceptable. Causas comunes:
Parámetro faltante: input_task_id es obligatorio.
UUID inválido: input_task_id no es un UUID válido.
El padre no tuvo éxito: La tarea de prototipo referenciada aún no ha alcanzado SUCCEEDED.
Sin candidato: La tarea de prototipo tuvo éxito pero no produjo ninguna imagen de pixel art; crea un nuevo prototipo.
Opciones fuera de rango: Uno de los campos de options está fuera de su conjunto o rango permitido — por ejemplo options.grid_size must be 16 or 32, o options.piece_size_mm=10 is not supported for shape=hex; hex pieces are available in 6 and 8 mm.
Formato no compatible: output.format debe ser 3mf.
Name
401 - Unauthorized
Description
Error de autenticación. Verifica tu clave de API.
Name
402 - Payment Required
Description
Créditos insuficientes para realizar esta tarea, o la clave de API pertenece a una cuenta de plan gratuito.
Name
403 - Forbidden
Description
La imagen del prototipo referenciado fue marcada por la moderation de propiedad intelectual. Solo se bloquean las cuentas Enterprise con el filtrado de propiedad intelectual habilitado; no se cobra nada.
Name
404 - Not Found
Description
La tarea de prototipo referenciada no existe, pertenece a otro usuario, o fue creada a través de la aplicación web (solo las tareas de prototipo en mode API se encadenan a la construcción).
Name
429 - Too Many Requests
Description
Has excedido tu límite de tasa.
Name
500 - Internal Server Error
Description
No se pudo establecer el veredicto de propiedad intelectual del prototipo referenciado (Unable to perform intellectual property check, please try again). Las cuentas Enterprise con el filtrado de propiedad intelectual habilitado fallan de forma cerrada en esta verificación; no se cobra nada — vuelve a intentar la solicitud.
Recupera una tarea de prototipo o de compilación dado un id de tarea válido. La ruta de la URL
debe coincidir con la etapa de la tarea: una tarea de compilación obtenida a través de
/prototype/:id devuelve 404, y viceversa.
Identificador único de la tarea de fidget pixel que se desea recuperar.
Devuelve
La respuesta contiene el objeto de tarea de fidget pixel. El formato depende de
qué etapa se haya solicitado.
Modos de fallo
Name
400 - Bad Request
Description
id no es un UUID válido (Invalid ID).
Name
403 - Forbidden
Description
La imagen de la tarea fue marcada por la moderación de propiedad intelectual. Solo las cuentas Enterprise con el filtrado de propiedad intelectual habilitado son bloqueadas.
Name
404 - Not Found
Description
La tarea no existe, pertenece a otro usuario, o su etapa no coincide con la ruta de la URL.
Name
500 - Internal Server Error
Description
No se pudo completar la verificación de propiedad intelectual (Unable to perform intellectual property check, please try again); las cuentas Enterprise con el filtrado de propiedad intelectual habilitado fallan de forma cerrada. Vuelve a intentar la solicitud.
Cancela una tarea de fidget pixel. Si la tarea todavía está en estado PENDING, los
créditos consumidos en el momento de la creación se reembolsan. Las tareas que ya están
en IN_PROGRESS se cancelan sin reembolso (es posible que el worker ya esté
consumiendo recursos). Las tareas que ya han alcanzado un estado terminal
(SUCCEEDED, FAILED, CANCELED) no se pueden cancelar.
La ruta de la URL debe coincidir con la etapa de la tarea — un DELETE en
/prototype/:buildId devuelve 404.
Parámetros de ruta
Name
id
Type
path
Description
Identificador único de la tarea de fidget pixel que se desea cancelar.
Devuelve
Devuelve 204 No Content en caso de éxito, con un cuerpo vacío.
Modos de fallo
Name
400 - Bad Request
Description
La solicitud fue inaceptable. Causas comunes:
ID inválido: id no es un UUID válido.
Estado terminal: La tarea ya está en SUCCEEDED, FAILED o CANCELED y no se puede cancelar.
Name
404 - Not Found
Description
La tarea no existe, pertenece a un usuario diferente, o su etapa no coincide con la ruta de la URL.
Transmite actualizaciones en tiempo real para una tarea de fidget pixel mediante Server-Sent Events (SSE).
La ruta de la URL debe coincidir con la etapa de la tarea: abrir un stream en
/prototype/:buildId/stream emite un único payload event: error con
status_code: 404 y cierra el stream; un id con formato incorrecto hace lo mismo con
status_code: 400 (Invalid ID).
Parámetros
Name
id
Type
path
Description
Identificador único de la tarea de fidget pixel que se va a transmitir.
Devuelve
Devuelve un stream de objetos de tarea Fidget Pixel Prototype
o Fidget Pixel Build como
Server-Sent Events. Cada frame contiene el objeto de tarea completo para la etapa correspondiente —la misma forma que
devuelve el endpoint Get—, por lo que mientras la tarea está en PENDING o IN_PROGRESS, los
campos de salida simplemente aún no están poblados (null, [] o {}) y
finished_at es null.
Recupera una lista paginada de tus tareas de fidget pixel para una única etapa.
La ruta de la URL selecciona la etapa: /prototype devuelve las tareas de prototipo;
/build devuelve las tareas de compilación. Las tareas de la otra etapa no se incluyen
en ninguna de las dos respuestas.
Parámetros de ruta
Name
stage
Type
path
Requerido
Description
Puede ser prototype o build. La colección devuelve solo las tareas
cuya etapa coincida con la URL; obtener /prototype nunca devuelve
tareas de compilación, y viceversa.
Parámetros de consulta
Name
page_num
Type
integer
predeterminado 1
Description
Número de página para la paginación.
Name
page_size
Type
integer
predeterminado 10
Description
Límite del tamaño de página. El máximo permitido es 100 elementos.
Name
sort_by
Type
string
predeterminado -created_at
Description
Campo por el que ordenar. Valores disponibles:
+created_at: Ordenar por hora de creación en orden ascendente.
-created_at: Ordenar por hora de creación en orden descendente.
El objeto de tarea de prototipo de Fidget Pixel es una unidad de trabajo que Meshy
mantiene registrada para pixelar una foto de origen en una imagen de pixel art. La salida de
esta etapa se encadena a la etapa de compilación
mediante input_task_id.
Propiedades
Name
id
Type
string
Description
Identificador único de la tarea. Aunque usamos un UUID ordenable por k como detalle de implementación para los ids de tarea, no debes hacer ninguna suposición sobre el formato del id.
Name
type
Type
string
Description
Tipo de la tarea. El valor es creative-lab-fidget-pixel-prototype.
Name
name
Type
string
Description
El nombre de la tarea proporcionado al crearla. Cadena vacía si no se proporcionó ningún nombre.
Name
status
Type
string
Description
Estado de la tarea. Los valores posibles son uno de PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Progreso de la tarea. Si la tarea aún no ha comenzado, esta propiedad será 0. Una vez que la tarea se haya completado con éxito, esta será 100.
Name
created_at
Type
timestamp
Description
Marca de tiempo de cuándo se creó la tarea, en milisegundos.
Una marca de tiempo representa el número de milisegundos transcurridos desde el 1 de enero de 1970 UTC, siguiendo
el estándar RFC 3339.
Por ejemplo, el viernes 1 de septiembre de 2023 a las 12:00:00 PM GMT se representa como 1693569600000. Esto aplica
a todas las marcas de tiempo en Meshy API.
Name
started_at
Type
timestamp
Description
Marca de tiempo de cuándo se inició la tarea, en milisegundos. Si la tarea aún no ha comenzado, esta propiedad será null.
Name
finished_at
Type
timestamp
Description
Marca de tiempo de cuándo finalizó la tarea, en milisegundos. Si la tarea aún no ha finalizado, esta propiedad será null.
Name
expires_at
Type
timestamp
Description
Marca de tiempo de cuándo expira el resultado de la tarea, en milisegundos — 3 días después de que la tarea finalizó. Las cuentas empresariales conservan los resultados de la API indefinidamente (consulta Retención de recursos); para ellas, esta marca de tiempo se establece en aproximadamente 100 años en el futuro.
Name
preceding_tasks
Type
integer
Description
El recuento de tareas precedentes.
El valor de este campo solo tiene sentido si el estado de la tarea es PENDING.
Name
task_error
Type
object
Description
Detalles del error para tareas fallidas. Consulta Errores para la referencia completa del objeto task_error.
Name
consumed_credits
Type
integer
Description
El número de créditos consumidos por esta tarea. A una tarea que llega a SUCCEEDED se le cobra el importe completo correspondiente a su etapa. A una tarea que nunca llega a crearse (un 4xx en el momento de la solicitud, incluido un rechazo por moderation) no se le cobra nada en absoluto. Una tarea que llega a FAILED devuelve 0 — se reembolsa el cargo. Cancelar mediante DELETE solo reembolsa mientras la tarea aún esté en PENDING; una tarea que ya esté IN_PROGRESS mantiene el cargo, porque el trabajo ya se ha invertido.
Name
image_urls
Type
array of strings
Description
URLs descargables para la imagen de pixel art generada por esta tarea de prototipo. Actualmente la API siempre devuelve exactamente una imagen; el campo es un array para que futuras revisiones puedan mostrar múltiples candidatas sin un cambio disruptivo. Vacío hasta que la tarea llega a SUCCEEDED.
Estas son URLs firmadas: obtenlas sin un encabezado Authorization. Permanecen válidas hasta expires_at, que es 3 días después de finished_at, y volver a leer la tarea dentro de esa ventana devuelve la misma URL en lugar de una recién firmada. Descarga y almacena los archivos tú mismo antes de ese momento — no hay forma de renovar un enlace expirado.
El objeto Fidget Pixel Build Task es una unidad de trabajo que Meshy supervisa para
generar las piezas imprimibles a partir de una tarea de prototipo con estado SUCCEEDED. La compilación
muestrea la imagen de arte de píxeles del prototipo sobre la cuadrícula solicitada y publica
un único 3MF etiquetado por color.
Propiedades
Name
id
Type
string
Description
Identificador único de la tarea.
Name
type
Type
string
Description
Tipo de la tarea. El valor es creative-lab-fidget-pixel-build.
Name
name
Type
string
Description
El nombre de la tarea proporcionado al crearla. Cadena vacía si no se proporcionó ningún nombre.
Name
status
Type
string
Description
Estado de la tarea. Los valores posibles son uno de PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Progreso de la tarea. Si la tarea aún no se ha iniciado, esta propiedad será 0. Una vez que la tarea haya finalizado con éxito, esta propiedad será 100.
Name
created_at
Type
timestamp
Description
Marca de tiempo de cuándo se creó la tarea, en milisegundos.
Name
started_at
Type
timestamp
Description
Marca de tiempo de cuándo se inició la tarea, en milisegundos. null hasta que la tarea se inicia.
Name
finished_at
Type
timestamp
Description
Marca de tiempo de cuándo finalizó la tarea, en milisegundos. null hasta que la tarea finaliza.
Name
expires_at
Type
timestamp
Description
Marca de tiempo de cuándo expira el resultado de la tarea, en milisegundos: 3 días después de que la tarea finalizara. Las cuentas Enterprise conservan los resultados de la API de forma indefinida (consulta Retención de recursos); para ellas, esta marca de tiempo se establece con un adelanto de unos 100 años.
Name
preceding_tasks
Type
integer
Description
El recuento de tareas precedentes. Solo tiene sentido cuando el estado es PENDING.
Name
task_error
Type
object
Description
Detalles del error para tareas fallidas. Consulta Errores para ver la referencia completa del objeto task_error.
Name
consumed_credits
Type
integer
Description
El número de créditos consumidos por esta tarea. A una tarea que alcanza el estado SUCCEEDED se le cobra el importe completo correspondiente a su etapa. A una tarea que nunca llega a crearse (un 4xx en el momento de la solicitud, incluido un rechazo por moderation) no se le cobra nada en absoluto. Una tarea que alcanza el estado FAILED devuelve 0: el cargo se reembolsa. Cancelar mediante DELETE solo reembolsa mientras la tarea sigue en estado PENDING; una tarea que ya está en IN_PROGRESS sigue teniendo el cargo, porque el trabajo ya se ha invertido.
Name
model_urls
Type
object
Description
URLs descargables para el recurso generado, indexadas por formato. Contiene exactamente una entrada: el formato solicitado mediante el output.format de la solicitud de compilación. Está vacío hasta que la tarea alcanza el estado SUCCEEDED.
Estas son URLs firmadas: obténlas sin una cabecera Authorization. Permanecen válidas hasta expires_at, que es 3 días después de finished_at, y volver a leer la tarea dentro de esa ventana devuelve la misma URL en lugar de una firmada de nuevo. Descarga y almacena los archivos por tu cuenta antes de ese momento; no hay forma de renovar un enlace expirado.
Name
3mf
Type
string
Description
URL descargable del archivo 3MF. Un objeto por pieza, cada uno etiquetado con su color de paleta, de modo que un laminador multifilamento asigna filamentos por color. Presente cuando output.format era 3mf (el valor predeterminado).
El flujo completo: crear un prototipo a partir de una foto, sondearlo hasta
SUCCEEDED, crear una construcción a partir de él, sondear la construcción hasta
SUCCEEDED, y luego descargar el 3MF desde model_urls.
Un prototipo normalmente termina en unos pocos minutos; una construcción
típicamente se completa en bastante menos de un minuto. En una integración real,
mostrarías la entrada image_urls del prototipo al usuario final y le dejarías
confirmar (o volver a ejecutar el prototipo) antes de gastar créditos en la
construcción.
Complete flow
POST
/openapi/creative-lab/fidget-pixel/v1
#!/usr/bin/env bashset-euopipefail# 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://...# export PIXEL_TYPE=person # or: other:"${MESHY_API_KEY:?export MESHY_API_KEY first}"if [[ -z"${IMAGE_PATH:-}"&&-z"${IMAGE_URL:-}" ]]; thenecho"export IMAGE_PATH (local file) or IMAGE_URL (public url) first">&2exit1fiPIXEL_TYPE=${PIXEL_TYPE:-person}BASE="https://api.meshy.ai/openapi/creative-lab/fidget-pixel/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 bodyshift2 out=$(curl--silent--show-error--max-time60--write-out$'\n%{http_code}' \-X"$method""$url"-H"$AUTH""$@") ||return1 http_code=${out##*$'\n'} body=${out%$'\n'*}if ((http_code >=400)); thenecho"HTTP $http_code for $url: $body">&2return1fiprintf'%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:; doif (($(date +%s) >= deadline)); thenecho"gave up waiting for $kind $id">&2return1fi task_status=$(apiGET"$BASE/$kind/$id"|jq-r'.status')echo"$kind: $task_status"case"$task_status"inSUCCEEDED)return0 ;;FAILED|CANCELED)return1 ;;esacsleep"$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"'EXITif [[ -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')"inpng) MIME=image/png ;;webp) MIME=image/webp ;;*) MIME=image/jpeg ;;esac {printf'{"type":"%s","image_url":"data:%s;base64,'"$PIXEL_TYPE""$MIME"base64<"$IMAGE_PATH"|tr-d'\n'printf'"}' } >"$BODY"elsejq-n--argt"$PIXEL_TYPE"--argu"$IMAGE_URL" \'{type: $t, image_url: $u}'>"$BODY"fi# 1. Create the prototype taskPROTO_ID=$(apiPOST"$BASE/prototype" \-H'Content-Type: application/json'--data-binary@"$BODY"|jq-r'.result')# 2. Wait for the pixel-art image (show image_urls[0] to a user in production)pollprototype"$PROTO_ID"# 3. Create the build task (defaults: square pieces, 32x32 grid, 8 mm, 8 colors, 15 mm tall)jq-n--argp"$PROTO_ID" \'{input_task_id: $p, options: {shape: "square", grid_size: 32, piece_size_mm: 8, color_count: 8, piece_height_mm: 15}, output: {format: "3mf"}}'>"$BODY"BUILD_ID=$(apiPOST"$BASE/build" \-H'Content-Type: application/json'--data-binary@"$BODY"|jq-r'.result')# 4. Wait for the piecespollbuild"$BUILD_ID"# 5. Download the 3MF. This is a signed URL: no Authorization header,# and it stays valid for 3 days after the task finishes.TASK=$(apiGET"$BASE/build/$BUILD_ID")curl--silent--show-error--fail--max-time900 \-ofidget-pixel.3mf"$(jq-r '.model_urls["3mf"]' <<<"$TASK")"echo"Done: fidget-pixel.3mf"