Ubah foto sumber menjadi papan fidget pixel-art multi-warna yang dapat dicetak
dalam 3D melalui dua tahap: prototype mengubah foto Anda menjadi gambar
pixel-art, kemudian build mengambil sampel gambar tersebut ke dalam grid
16×16 atau 32×32 dan mengubah setiap piksel menjadi keping persegi atau
heksagonal yang saling mengunci, dikirimkan sebagai satu 3MF yang objek-objeknya
membawa warnanya masing-masing sehingga slicer multi-filamen mencetak setiap
keping dengan warna yang tepat. Kedua tahap ini dihubungkan melalui
input_task_id.
POST /openapi/creative-lab/fidget-pixel/v1/prototype
POST /openapi/creative-lab/fidget-pixel/v1/build
Kedua endpoint POST memerlukan paket langganan berbayar. Permintaan dari
akun paket gratis akan ditolak dengan 402 Payment Required.
Menghasilkan satu gambar pixel-art dari foto sumber. ID task yang dikembalikan adalah yang Anda kirimkan sebagai input_task_id ke endpoint build. Panggil endpoint ini lagi untuk percobaan lain jika hasilnya tidak sesuai keinginan Anda — setiap panggilan ditagih secara terpisah. Lihat
The Fidget Pixel Prototype Task Object
untuk bentuk responsnya.
Parameter
Name
image_url
Type
string
Wajib
Description
Foto sumber yang akan dipiksel oleh Meshy. Kami saat ini mendukung format .jpg, .jpeg, .png, dan .webp.
Format terdeteksi dengan mendekode data gambar, bukan dari ekstensi file pada URL — URL tanpa ekstensi, atau yang melakukan redirect, tetap berfungsi selama byte-nya terdekode ke format yang didukung. HTTP redirect akan diikuti.
Ada dua cara untuk menyediakan gambar:
URL yang dapat diakses publik: URL yang dapat diakses dari internet publik.
Data URI: Data URI gambar yang di-encode base64. Contoh data URI: data:image/jpeg;base64,<data gambar Anda yang di-encode base64>.
Name
type
Type
string
Wajib
Description
Apa yang ditampilkan foto tersebut. Menentukan gaya pixelization, jadi pilihlah dengan cermat — kedua opsi menghasilkan hasil yang terlihat berbeda secara nyata. Nilai yang tersedia:
person — subjeknya adalah seseorang (potret atau seluruh tubuh). Menghasilkan sprite piksel bergaya chibi dari subjek tersebut.
other — apa pun selain itu: hewan peliharaan, objek, maskot, logo, pemandangan. Menghasilkan ikon piksel bergaya bead-art dari subjek tersebut.
Name
name
Type
string
Description
Nama task opsional untuk tujuan tampilan. Maksimum 100 karakter.
Returns
Properti result dari respons berisi id task dari task prototipe fidget pixel yang baru dibuat. Poll endpoint Get a Task atau berlangganan ke stream hingga task mencapai status SUCCEEDED, lalu kirimkan ID tersebut ke endpoint build sebagai input_task_id.
Failure Modes
Name
400 - Bad Request
Description
Permintaan tidak dapat diterima. Penyebab umum:
Parameter hilang: image_url dan type keduanya wajib diisi.
Type tidak valid: type harus berupa person atau other.
Format gambar tidak valid: image_url yang diberikan bukan format yang didukung (.jpg, .jpeg, .png, .webp).
Dimensi gambar di luar rentang: Gambar terlalu kecil, melebihi ukuran file maksimum, atau melebihi jumlah piksel maksimum.
URL tidak dapat dijangkau: image_url tidak dapat diunduh (404 atau timeout).
Data URI tidak valid: String base64 tidak berformat dengan benar.
Konten ditandai: Gambar input ditandai oleh moderation NSFW.
Name
401 - Unauthorized
Description
Autentikasi gagal. Silakan periksa kunci API Anda.
Name
402 - Payment Required
Description
Kredit tidak mencukupi untuk melakukan task ini, atau kunci API tersebut dimiliki oleh akun paket gratis.
Name
403 - Forbidden
Description
Gambar input ditandai oleh moderation kekayaan intelektual (Content flagged for intellectual property violation). Hanya akun Enterprise dengan penyaringan kekayaan intelektual yang diaktifkan yang diblokir; tidak ada tagihan yang dikenakan.
Name
429 - Too Many Requests
Description
Anda telah melampaui batas laju Anda.
Name
500 - Internal Server Error
Description
Pemeriksaan kekayaan intelektual itu sendiri tidak dapat diselesaikan (Unable to perform intellectual property check, please try again). Akun Enterprise dengan penyaringan kekayaan intelektual yang diaktifkan akan gagal secara tertutup pada pemeriksaan ini; tidak ada tagihan yang dikenakan — coba ulangi permintaan tersebut.
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" }'
Menghasilkan bagian-bagian yang siap dicetak 3D dari prototype task yang berhasil. Proses build ini mengambil sampel gambar pixel-art dari prototype ke grid yang diminta, mengkuantisasinya menjadi maksimal color_count warna, dan menghasilkan satu bagian yang saling mengunci untuk setiap sel grid. Hasil akhirnya adalah satu file 3MF di mana setiap bagian merupakan objek terpisah yang ditandai dengan warnanya, siap untuk slicer multi-filamen. Lihat
The Fidget Pixel Build Task Object
untuk bentuk responsnya.
Parameter
Name
input_task_id
Type
string
Wajib
Description
ID task dari prototype task yang dibuat melalui endpoint OpenAPI yang sama ini. Prototype tersebut harus dibuat oleh akun Meshy yang sama dan harus telah mencapai SUCCEEDED.
Prototype task yang dibuat melalui webapp tidak diterima — endpoint build hanya menerima prototype task yang dihasilkan oleh POST /openapi/creative-lab/fidget-pixel/v1/prototype dan menolak sumber lainnya dengan 404.
Name
name
Type
string
Description
Nama task opsional untuk keperluan tampilan. Maksimal 100 karakter.
options
Geometri bagian opsional. Setiap field memiliki nilai default — kirim hanya yang ingin Anda timpa. Ini adalah kontrol yang sama yang ditampilkan oleh webapp Creative Lab; ketinggian pasak, skala tutup, dan preset manufaktur lainnya diturunkan dari shape dan piece_size_mm dan tidak diekspos.
Name
shape
Type
string
default square
Description
Bentuk jejak setiap bagian. Nilai yang tersedia:
square (default) — bagian persegi pada grid persegi.
hex — bagian heksagonal pada grid heksagonal. Bagian hex tersedia hanya dalam ukuran 6 dan 8 mm.
Name
grid_size
Type
integer
default 32
Description
Jumlah bagian di sepanjang setiap sisi papan. Nilai yang tersedia: 16 atau 32. Grid 32 mempertahankan lebih banyak detail; grid 16 berarti bagian yang lebih sedikit dan lebih besar untuk subjek yang sama.
Name
piece_size_mm
Type
integer
default 8
Description
Panjang sisi setiap bagian, dalam milimeter. Nilai yang tersedia: 6, 8, atau 10. Bersama dengan grid_size, ini menentukan ukuran papan yang dicetak — misalnya 32 × 8 mm ≈ 26 cm per sisi. 10 tidak tersedia untuk shape: "hex" (permukaan hex yang miring menyebabkan overhang pada sebagian besar printer FDM konsumen).
Name
color_count
Type
integer
default 8
Description
Jumlah maksimum warna dalam palet tempat gambar dikuantisasi. Rentang: [1, 8]. Setiap warna menjadi satu filamen di slicer Anda.
Name
piece_height_mm
Type
integer
default 15
Description
Tinggi setiap bagian, dalam milimeter. Rentang: [10, 80].
output
Pemilih format wire opsional. Default ke 3mf, yang saat ini merupakan satu-satunya nilai yang didukung.
Name
format
Type
string
default 3mf
Description
Artefak yang dikembalikan oleh proses build. Nilai yang tersedia:
3mf (default) — mengembalikan satu model.3mf di bawah model_urls.3mf, dengan satu objek per bagian dan warna bagian yang dilekatkan pada setiap objek.
Nilai yang Dikembalikan
Properti result pada respons berisi id task dari fidget pixel build task yang baru dibuat. Poll endpoint Get a Task atau berlangganan ke stream hingga task mencapai SUCCEEDED, lalu unduh artefaknya dari model_urls.3mf.
Mode Kegagalan
Name
400 - Bad Request
Description
Permintaan tidak dapat diterima. Penyebab umum:
Parameter hilang: input_task_id wajib diisi.
UUID tidak valid: input_task_id bukan UUID yang valid.
Parent belum berhasil: Prototype task yang dirujuk belum mencapai SUCCEEDED.
Tidak ada kandidat: Prototype task berhasil tetapi tidak menghasilkan gambar pixel-art; buat prototype baru.
Options di luar rentang: Salah satu field options berada di luar kumpulan atau rentang yang diizinkan — misalnya options.grid_size must be 16 or 32, atau options.piece_size_mm=10 is not supported for shape=hex; hex pieces are available in 6 and 8 mm.
Format tidak didukung: output.format harus 3mf.
Name
401 - Unauthorized
Description
Autentikasi gagal. Silakan periksa kunci API Anda.
Name
402 - Payment Required
Description
Kredit tidak mencukupi untuk melakukan task ini, atau kunci API tersebut milik akun paket gratis.
Name
403 - Forbidden
Description
Gambar prototype yang dirujuk ditandai oleh moderation kekayaan intelektual. Hanya akun Enterprise dengan filtering kekayaan intelektual yang diaktifkan yang diblokir; tidak ada biaya yang dikenakan.
Name
404 - Not Found
Description
Prototype task yang dirujuk tidak ada, milik pengguna lain, atau dibuat melalui webapp (hanya prototype task mode API yang dapat dirangkai ke build).
Name
429 - Too Many Requests
Description
Anda telah melampaui batas laju Anda.
Name
500 - Internal Server Error
Description
Vonis kekayaan intelektual dari prototype yang dirujuk tidak dapat ditetapkan (Unable to perform intellectual property check, please try again). Akun Enterprise dengan filtering kekayaan intelektual yang diaktifkan akan gagal secara tertutup pada pemeriksaan ini; tidak ada biaya yang dikenakan — coba lagi permintaan tersebut.
Mengambil task prototype atau build dengan id task yang valid. Path URL
harus sesuai dengan tahap task tersebut — task build yang diambil melalui
/prototype/:id akan mengembalikan 404, dan begitu pula sebaliknya.
Pengenal unik untuk task fidget pixel yang ingin diambil.
Returns
Respons berisi objek task fidget pixel. Bentuknya bergantung pada
tahap mana yang diminta.
Mode Kegagalan
Name
400 - Bad Request
Description
id bukan UUID yang valid (Invalid ID).
Name
403 - Forbidden
Description
Gambar task ditandai oleh moderasi kekayaan intelektual. Hanya akun Enterprise dengan filter kekayaan intelektual yang diaktifkan yang akan diblokir.
Name
404 - Not Found
Description
Task tersebut tidak ada, milik pengguna lain, atau tahapnya tidak sesuai dengan path URL.
Name
500 - Internal Server Error
Description
Pemeriksaan kekayaan intelektual tidak dapat diselesaikan (Unable to perform intellectual property check, please try again); akun Enterprise dengan filter kekayaan intelektual yang diaktifkan akan gagal secara tertutup (fail closed). Coba lagi permintaan tersebut.
Membatalkan task fidget pixel. Jika task masih berstatus PENDING, kredit
yang digunakan saat pembuatan akan dikembalikan. Task yang sudah
IN_PROGRESS akan dibatalkan tanpa pengembalian kredit (karena worker mungkin
sudah menggunakan sumber daya). Task yang sudah mencapai status akhir
(SUCCEEDED, FAILED, CANCELED) tidak dapat dibatalkan.
Path URL harus sesuai dengan tahap task tersebut — DELETE pada
/prototype/:buildId akan mengembalikan 404.
Parameter Path
Name
id
Type
path
Description
Pengenal unik untuk task fidget pixel yang akan dibatalkan.
Hasil
Mengembalikan 204 No Content jika berhasil dengan body kosong.
Mode Kegagalan
Name
400 - Bad Request
Description
Permintaan tidak dapat diterima. Penyebab umum:
ID tidak valid: id bukan UUID yang valid.
Status akhir: Task sudah berstatus SUCCEEDED, FAILED, atau CANCELED dan tidak dapat dibatalkan.
Name
404 - Not Found
Description
Task tidak ditemukan, milik pengguna lain, atau tahapnya tidak sesuai dengan path URL.
Melakukan streaming pembaruan secara real-time untuk task fidget pixel melalui Server-Sent Events (SSE).
Jalur URL harus sesuai dengan tahap task tersebut — membuka stream di
/prototype/:buildId/stream akan mengeluarkan satu event: error payload dengan
status_code: 404 dan menutup stream tersebut; id yang salah format akan melakukan hal yang sama dengan
status_code: 400 (Invalid ID).
Parameter
Name
id
Type
path
Description
Pengenal unik untuk task fidget pixel yang akan di-stream.
Nilai Kembali
Mengembalikan sebuah stream berisi objek task Fidget Pixel Prototype
atau Fidget Pixel Build sebagai
Server-Sent Events. Setiap frame membawa objek task lengkap untuk tahap tersebut — bentuk yang sama
dengan yang dikembalikan oleh endpoint Get — sehingga selama task masih PENDING atau IN_PROGRESS
kolom output tersebut belum terisi (null, [] atau {}) dan
finished_at bernilai null.
Ambil daftar tugas fidget pixel Anda yang dipaginasi untuk satu tahap.
Path URL memilih tahap tersebut — /prototype mengembalikan tugas prototype;
/build mengembalikan tugas build. Tugas dari tahap lainnya tidak disertakan
dalam kedua respons tersebut.
Path Parameters
Name
stage
Type
path
Wajib
Description
Salah satu dari prototype atau build. Koleksi tersebut hanya mengembalikan tugas
yang tahapnya cocok dengan URL — mengambil /prototype tidak akan pernah mengembalikan
tugas build dan sebaliknya.
Query Parameters
Name
page_num
Type
integer
default 1
Description
Nomor halaman untuk paginasi.
Name
page_size
Type
integer
default 10
Description
Batas ukuran halaman. Maksimum yang diizinkan adalah 100 item.
Name
sort_by
Type
string
default -created_at
Description
Kolom untuk pengurutan. Nilai yang tersedia:
+created_at: Urutkan berdasarkan waktu pembuatan secara ascending.
-created_at: Urutkan berdasarkan waktu pembuatan secara descending.
Objek Task Fidget Pixel Prototype adalah unit kerja yang dilacak oleh Meshy
untuk mengubah foto sumber menjadi gambar pixel-art. Output dari tahap ini
dirangkai ke tahap build
melalui input_task_id.
Properties
Name
id
Type
string
Description
Pengidentifikasi unik untuk task. Meskipun kami menggunakan UUID yang dapat diurutkan-k (k-sortable) untuk id task sebagai detail implementasi, Anda tidak boleh membuat asumsi apa pun tentang format id tersebut.
Name
type
Type
string
Description
Tipe task. Nilainya adalah creative-lab-fidget-pixel-prototype.
Name
name
Type
string
Description
Nama task yang diberikan saat task dibuat. String kosong jika tidak ada nama yang diberikan.
Name
status
Type
string
Description
Status task. Nilai yang mungkin adalah salah satu dari PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Progress dari task. Jika task belum dimulai, properti ini akan bernilai 0. Setelah task berhasil, nilainya akan menjadi 100.
Name
created_at
Type
timestamp
Description
Stempel waktu saat task dibuat, dalam milidetik.
Stempel waktu merepresentasikan jumlah milidetik yang berlalu sejak 1 Januari 1970 UTC, mengikuti
standar RFC 3339.
Misalnya, Jumat, 1 September 2023 12:00:00 PM GMT direpresentasikan sebagai 1693569600000. Ini berlaku
untuk semua stempel waktu di Meshy API.
Name
started_at
Type
timestamp
Description
Stempel waktu saat task dimulai, dalam milidetik. Jika task belum dimulai, properti ini akan bernilai null.
Name
finished_at
Type
timestamp
Description
Stempel waktu saat task selesai, dalam milidetik. Jika task belum selesai, properti ini akan bernilai null.
Name
expires_at
Type
timestamp
Description
Stempel waktu saat hasil task kedaluwarsa, dalam milidetik — 3 hari setelah task selesai. Akun Enterprise menyimpan hasil API tanpa batas waktu (lihat Asset Retention); untuk mereka, stempel waktu ini diatur sekitar 100 tahun ke depan.
Name
preceding_tasks
Type
integer
Description
Jumlah task yang mendahului.
Nilai dari field ini hanya bermakna jika status task adalah PENDING.
Name
task_error
Type
object
Description
Detail kesalahan untuk task yang gagal. Lihat Kesalahan untuk referensi lengkap objek task_error.
Name
consumed_credits
Type
integer
Description
Jumlah kredit yang dikonsumsi oleh task ini. Task yang mencapai SUCCEEDED akan dikenakan biaya penuh untuk tahapnya. Task yang tidak pernah dibuat (4xx pada saat request, termasuk penolakan moderation) tidak dikenakan biaya sama sekali. Task yang mencapai FAILED mengembalikan 0 — biaya akan dikembalikan. Membatalkan melalui DELETE hanya mengembalikan biaya selama task masih PENDING; task yang sudah IN_PROGRESS tetap dikenakan biaya, karena pekerjaan sudah dilakukan.
Name
image_urls
Type
array of strings
Description
URL yang dapat diunduh untuk gambar pixel-art yang dihasilkan oleh task prototype ini. Saat ini API selalu mengembalikan tepat satu gambar; field ini berupa array agar revisi mendatang dapat menampilkan beberapa kandidat tanpa perubahan yang tidak kompatibel. Kosong hingga task mencapai SUCCEEDED.
Ini adalah URL yang ditandatangani (signed): ambil tanpa header Authorization. URL ini tetap valid hingga expires_at, yaitu 3 hari setelah finished_at, dan membaca ulang task dalam rentang waktu tersebut akan mengembalikan URL yang identik, bukan yang baru ditandatangani. Unduh dan simpan file tersebut sendiri sebelum waktu itu — tidak ada cara untuk memperbarui tautan yang sudah kedaluwarsa.
Objek Fidget Pixel Build Task adalah unit kerja yang dilacak oleh Meshy untuk
menghasilkan bagian-bagian yang dapat dicetak dari sebuah prototype task yang berhasil. Build
mengambil sampel gambar pixel-art dari prototype tersebut ke dalam grid yang diminta dan mempublikasikan
satu 3MF dengan penanda warna.
Properti
Name
id
Type
string
Description
Pengenal unik untuk task ini.
Name
type
Type
string
Description
Jenis task. Nilainya adalah creative-lab-fidget-pixel-build.
Name
name
Type
string
Description
Nama task yang diberikan saat task dibuat. String kosong jika tidak ada nama yang diberikan.
Name
status
Type
string
Description
Status task. Nilai yang mungkin adalah salah satu dari PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Progress dari task. Jika task belum dimulai, properti ini akan bernilai 0. Setelah task berhasil, nilainya akan menjadi 100.
Name
created_at
Type
timestamp
Description
Stempel waktu saat task dibuat, dalam milidetik.
Name
started_at
Type
timestamp
Description
Stempel waktu saat task dimulai, dalam milidetik. null sampai task dimulai.
Name
finished_at
Type
timestamp
Description
Stempel waktu saat task selesai, dalam milidetik. null sampai task selesai.
Name
expires_at
Type
timestamp
Description
Stempel waktu saat hasil task kedaluwarsa, dalam milidetik — 3 hari setelah task selesai. Akun Enterprise menyimpan hasil API tanpa batas waktu (lihat Asset Retention); untuk mereka, stempel waktu ini disetel sekitar 100 tahun ke depan.
Name
preceding_tasks
Type
integer
Description
Jumlah task yang mendahului. Hanya bermakna ketika status adalah PENDING.
Name
task_error
Type
object
Description
Detail kesalahan untuk task yang gagal. Lihat Kesalahan untuk referensi lengkap objek task_error.
Name
consumed_credits
Type
integer
Description
Jumlah kredit yang dikonsumsi oleh task ini. Task yang mencapai SUCCEEDED dikenakan biaya penuh untuk tahapannya. Task yang tidak pernah dibuat (sebuah 4xx pada saat permintaan, termasuk penolakan moderation) tidak dikenakan biaya sama sekali. Task yang mencapai FAILED mengembalikan 0 — biaya dikembalikan. Membatalkan melalui DELETE hanya mengembalikan biaya selama task masih PENDING; task yang sudah IN_PROGRESS tetap dikenakan biaya, karena pekerjaannya sudah dilakukan.
Name
model_urls
Type
object
Description
URL yang dapat diunduh untuk artefak yang dihasilkan, dengan kunci berdasarkan format. Berisi tepat satu entri — format yang diminta melalui output.format pada permintaan build. Kosong sampai task mencapai SUCCEEDED.
Ini adalah URL bertanda tangan: ambil tanpa header Authorization. URL ini tetap berlaku hingga expires_at, yaitu 3 hari setelah finished_at, dan membaca ulang task di dalam jangka waktu tersebut akan mengembalikan URL yang identik, bukan yang baru ditandatangani. Unduh dan simpan file tersebut sendiri sebelum itu — tidak ada cara untuk memperbarui tautan yang sudah kedaluwarsa.
Name
3mf
Type
string
Description
URL yang dapat diunduh untuk file 3MF. Satu objek per bagian, masing-masing ditandai dengan warna palet-nya, sehingga slicer multi-filamen dapat menetapkan filamen per warna. Ada saat output.format adalah 3mf (default).
Alur lengkap: buat prototipe dari sebuah foto, poll hingga
SUCCEEDED, buat build dari prototipe tersebut, poll build hingga SUCCEEDED, lalu
unduh 3MF dari model_urls.
Sebuah prototipe biasanya selesai dalam beberapa menit; sebuah build biasanya
selesai dalam waktu kurang dari satu menit. Dalam integrasi nyata, Anda akan menampilkan
entri image_urls dari prototipe kepada pengguna akhir dan membiarkan mereka mengonfirmasi
(atau menjalankan ulang prototipe) sebelum menggunakan kredit untuk build.
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"