Tukar foto sumber kepada keycap papan kekunci mekanikal berwarna penuh dalam
dua peringkat: prototaip menjana render reka bentuk "keycap siap"
daripada foto input anda. Setelah anda mengesahkan render tersebut, pembinaan menukarkannya menjadi
model keycap 3D bertekstur dalam satu proses — penjanaan model putih, pemasangan dan pemotongan automatik pada pose lalai yang dikalibrasi, pewarnaan model penuh, dan
pemasangan akhir semuanya berlaku dalam satu tugas pembinaan. Kedua-dua peringkat dihubungkan
melalui input_task_id dan candidate_id.
POST /openapi/creative-lab/keycap/v1/prototype
POST /openapi/creative-lab/keycap/v1/build
Kedua-dua POST endpoint memerlukan pelan langganan berbayar. Permintaan daripada
akaun pelan percuma ditolak dengan 402 Payment Required.
Hasilkan render reka bentuk keycap siap daripada foto sumber. Hasil tugas
membawa array image_urls (render paparan keycap siap) dan array candidate_ids yang selari; kedua-duanya memegang satu entri. Panggil endpoint ini sekali lagi untuk render lain jika hasilnya bukan apa yang anda inginkan — setiap panggilan dikenakan bayaran secara berasingan. Serahkan candidate_id bersama dengan ID tugas prototaip kepada endpoint bina.
Rujuk kepada
Objek Tugas Prototaip Keycap
untuk bentuk respons.
Parameter
Name
image_url
Type
string
Diperlukan
Description
Foto sumber untuk Meshy menukar kepada imej reka bentuk keycap. Kami kini menyokong format .jpg, .jpeg, .png, dan .webp.
Format dikesan dengan menyahkod data imej, bukan dari sambungan fail URL — URL tanpa sambungan, atau yang mengalihkan, berfungsi selagi bait menyahkod kepada format yang disokong. Pengalihan HTTP diikuti. Orientasi EXIF dinormalisasi, jadi foto telefon yang diputar digunakan seperti yang kelihatan.
Had: sekurang-kurangnya 32 piksel pada setiap sisi, paling banyak 178,956,970 piksel secara keseluruhan, dan paling banyak 20,000,000 bait setelah dimuat turun. Untuk Data URI had ini terpakai kepada bait yang dinyahkod, jadi fail sumber itu sendiri boleh mencapai saiz tersebut — ia adalah teks base64 yang kira-kira satu pertiga lebih besar, yang penting untuk badan permintaan anda, bukan untuk had ini. Data URI mesti mengisytiharkan jenis kandungan image/* dan ;base64.
Terdapat dua cara untuk menyediakan imej:
URL yang boleh diakses secara awam: URL yang boleh diakses dari internet awam.
Data URI: Data URI yang dikodkan base64 bagi imej. Contoh Data URI: data:image/jpeg;base64,<your base64-encoded image data>.
Name
name
Type
string
Description
Nama tugas pilihan untuk tujuan paparan. Maksimum 100 aksara.
Name
remove_background
Type
boolean
lalai false
Description
Apabila ditetapkan kepada true, render paparan yang dikembalikan dalam image_urls adalah PNG RGBA telus dengan latar belakang dibuang, jadi anda boleh menggabungkannya pada mana-mana latar belakang.
Ini terpakai kepada render paparan sahaja. Calon yang digunakan oleh endpoint bina tidak terjejas, jadi hasil 3D adalah sama sama ada cara.
Mengembalikan
Harta result dalam respons mengandungi ID tugas id bagi tugas prototaip keycap yang baru dicipta. Kaji endpoint Dapatkan Tugas atau langgan kepada aliran sehingga tugas mencapai SUCCEEDED, kemudian ambil entri dari candidate_ids dan serahkannya, bersama dengan ID tugas, kepada endpoint bina.
Mod Kegagalan
Name
400 - Bad Request
Description
Permintaan tidak dapat diterima. Punca biasa:
Parameter hilang: image_url diperlukan.
Format imej tidak sah: image_url yang disediakan bukan format yang disokong (.jpg, .jpeg, .png, .webp).
Dimensi imej di luar julat: Imej terlalu kecil, melebihi saiz fail maksimum, atau melebihi jumlah piksel maksimum.
URL tidak dapat dicapai: image_url tidak dapat dimuat turun (404 atau timeout).
Data URI tidak sah: Rentetan base64 rosak.
Kandungan ditandakan: Imej input ditandakan oleh moderation NSFW.
Name
401 - Unauthorized
Description
Pengesahan gagal. Sila semak kunci API anda.
Name
402 - Payment Required
Description
Akaun berada pada pelan percuma (pelan berbayar diperlukan untuk mencipta tugas) atau tidak mempunyai kredit yang mencukupi.
Name
403 - Forbidden
Description
Imej input ditandakan oleh moderation harta intelek.
Name
429 - Too Many Requests
Description
Anda telah melebihi had kadar anda.
Name
500 - Internal Server Error
Description
Ralat pelayan yang tidak dijangka berlaku — contohnya perkhidmatan moderation kandungan tidak tersedia, pementasan imej input gagal, atau tugas tidak dapat dicipta. Tiada tugas yang dicipta dalam kes ini, jadi mencuba semula adalah selamat.
Permintaan
POST
/openapi/creative-lab/keycap/v1/prototype
# Stage 1: generate a finished-keycap design rendercurlhttps://api.meshy.ai/openapi/creative-lab/keycap/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>" }'
Hasilkan model keycap 3D bertekstur akhir dari tugas prototaip yang berjaya dan salah satu calonnya. Satu tugas pembinaan menjalankan keseluruhan saluran dari awal hingga akhir — penjanaan model putih dari reka bentuk yang dipilih, pemasangan dan pemotongan automatik pada asas keycap menggunakan pose lalai yang telah dikalibrasi (tiada pelarasan interaktif diperlukan), pewarnaan model penuh, dan pemasangan akhir serta eksport. Pembinaan biasanya mengambil masa 3–7 minit, ke arah hujung atas apabila beberapa pembinaan dijalankan serentak. Rujuk kepada Objek Tugas Pembinaan Keycap untuk bentuk respons.
Parameter
Name
input_task_id
Type
string
Diperlukan
Description
ID tugas bagi tugas prototaip yang dicipta melalui endpoint OpenAPI yang sama ini. Prototaip mesti telah dicipta oleh akaun Meshy yang sama, mesti telah mencapai SUCCEEDED, dan mesti telah menghasilkan sekurang-kurangnya satu calon.
Tugas prototaip yang dicipta melalui aplikasi web tidak diterima — endpoint pembinaan hanya menerima tugas prototaip yang dihasilkan oleh POST /openapi/creative-lab/keycap/v1/prototype dan menolak mana-mana sumber lain dengan 404.
Name
candidate_id
Type
string
Diperlukan
Description
Calon untuk dibina, diambil dari array candidate_ids dari tugas prototaip yang berjaya. Mesti milik tugas itu; sebarang nilai lain ditolak dengan 400.
Name
name
Type
string
Description
Nama tugas pilihan untuk tujuan paparan. Maksimum 100 aksara.
options
Penalaan geometri pilihan. Setiap medan mempunyai lalai yang telah dikalibrasi — hantar hanya yang anda ingin ganti.
Name
base_model
Type
string
lalai cherry-mx-1x1-r1
Description
Asas keycap untuk dibina. Pada masa ini, satu-satunya nilai yang tersedia adalah cherry-mx-1x1-r1 — profil standard Cherry MX 1u keycap. 3–5 saiz standard arus perdana tambahan dirancang; saiz tersuai tidak disokong.
Name
head_size_mm
Type
number
lalai 23
Description
Saiz sasaran kepala yang diukir, dalam milimeter: dimensi terpanjangnya diskalakan kepada nilai ini. Julat: [10, 40]. Nilai di atas kira-kira 32.9 mungkin dikurangkan supaya kepala masih muat dalam had jejak pelindung asas, jadi dimensi terpanjang yang dihantar boleh lebih kecil daripada yang diminta. Nilai yang diterapkan tidak dipaparkan semula pada objek tugas hari ini — jika anda perlu mengesahkan saiz yang sebenarnya diterima, ukur kotak pembatas jejaring keycap-head dalam model yang dimuat turun.
Name
vertical_offset_mm
Type
number
lalai 0
Description
Ofset menegak yang diterapkan kepada kepala sebelum ia dipasang pada asas, dalam milimeter. Julat: [-5, 5].
Pulangan
Harta result dari respons mengandungi id tugas dari tugas pembinaan keycap yang baru dicipta. Poll endpoint Dapatkan Tugas atau langgan aliran sehingga tugas mencapai SUCCEEDED, kemudian muat turun artifak dari model_urls.glb dan model_urls.obj_zip.
Kedua-dua GLB dan bundle OBJ dieksport pada skala milimeter dunia nyata, dengan sistem koordinat Y-up dan bahagian depan keycap menghadap +Z.
Mod Kegagalan
Name
400 - Bad Request
Description
Permintaan tidak dapat diterima. Punca biasa:
Parameter hilang: input_task_id dan candidate_id diperlukan.
UUID tidak sah: input_task_id bukan UUID yang sah.
Induk tidak berjaya: Tugas prototaip yang dirujuk belum mencapai SUCCEEDED.
Tiada calon: Tugas prototaip berjaya tetapi tidak menghasilkan calon.
Calon tidak diketahui: candidate_id bukan salah satu calon tugas input.
Pilihan di luar julat: Salah satu medan options jatuh di luar julat atau set enum yang dibenarkan.
Name
401 - Unauthorized
Description
Pengesahan gagal. Sila semak kunci API anda.
Name
402 - Payment Required
Description
Akaun berada pada pelan percuma (pelan berbayar diperlukan untuk mencipta tugas) atau tidak mempunyai kredit yang mencukupi.
Name
404 - Not Found
Description
Tugas prototaip yang dirujuk tidak wujud, milik pengguna lain, atau dicipta melalui aplikasi web (hanya tugas prototaip mod API yang berantai ke dalam pembinaan).
Name
429 - Too Many Requests
Description
Anda telah melebihi had kadar anda.
Name
500 - Internal Server Error
Description
Ralat pelayan yang tidak dijangka berlaku — contohnya perkhidmatan moderation kandungan tidak tersedia, pementasan imej input gagal, atau tugas tidak dapat dicipta. Tiada tugas yang dicipta dalam kes ini, jadi mencuba semula adalah selamat.
Permintaan
POST
/openapi/creative-lab/keycap/v1/build
# Stage 2: build the chosen candidate into a 3D keycapcurlhttps://api.meshy.ai/openapi/creative-lab/keycap/v1/build \-XPOST \-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 } }'
Dapatkan tugas prototaip atau binaan dengan memberikan id tugas yang sah. Laluan URL mesti sepadan dengan peringkat tugas — tugas binaan yang diambil melalui /prototype/:id akan mengembalikan 404, dan sebaliknya.
Batalkan tugas keycap. Jika tugas masih PENDING, kredit
yang digunakan semasa penciptaan akan dikembalikan. Tugas yang sudah
IN_PROGRESS dibatalkan tanpa pengembalian (pekerja mungkin sudah
menggunakan sumber). Tugas yang telah mencapai keadaan terminal
(SUCCEEDED, FAILED, CANCELED) tidak boleh dibatalkan.
Laluan URL mesti sepadan dengan tahap tugas — DELETE pada
/prototype/:buildId mengembalikan 404.
Parameter Laluan
Name
id
Type
path
Description
Pengenal pasti unik untuk tugas keycap yang hendak dibatalkan.
Pulangan
Mengembalikan 204 No Content apabila berjaya dengan badan kosong.
Mod Kegagalan
Name
400 - Bad Request
Description
Tugas sudah berada dalam keadaan terminal dan tidak boleh dibatalkan.
Name
404 - Not Found
Description
Tugas tidak wujud, milik pengguna lain, atau tahapnya tidak sepadan dengan laluan URL.
Name
500 - Internal Server Error
Description
Ralat tidak dijangka di sisi pelayan berlaku semasa pembatalan. Tugas mungkin atau mungkin tidak telah dibatalkan — baca semula untuk mengesahkan sebelum mencuba semula.
Strim kemas kini masa nyata untuk tugas keycap melalui Server-Sent Events (SSE).
Laluan URL mesti sepadan dengan peringkat tugas — membuka strim di
/prototype/:buildId/stream akan mengeluarkan satu event: error payload dengan
status_code: 404 dan menutup strim.
Parameter
Name
id
Type
path
Description
Pengenal pasti unik untuk tugas keycap yang ingin distrim.
Mengembalikan
Mengembalikan strim objek tugas Keycap Prototype
atau Keycap Build sebagai
Server-Sent Events. Untuk tugas PENDING atau IN_PROGRESS, strim respons
hanya akan menyertakan medan progress dan status yang diperlukan.
Dapatkan senarai berpenomboran halaman bagi tugas keycap anda untuk satu peringkat. Laluan URL memilih peringkat — /prototype mengembalikan tugas prototaip; /build mengembalikan tugas binaan. Tugas dari peringkat lain tidak termasuk dalam mana-mana respons.
Parameter Laluan
Name
stage
Type
path
Diperlukan
Description
Sama ada prototype atau build. Koleksi hanya mengembalikan tugas
yang peringkatnya sepadan dengan URL — mendapatkan /prototype tidak akan mengembalikan
tugas binaan dan sebaliknya.
Parameter Pertanyaan
Name
page_num
Type
integer
lalai 1
Description
Nombor halaman untuk penomboran halaman.
Name
page_size
Type
integer
lalai 10
Description
Had saiz halaman. Maksimum yang dibenarkan ialah 100 item.
Name
sort_by
Type
string
lalai -created_at
Description
Medan untuk disusun. Nilai yang tersedia:
+created_at: Susun mengikut masa penciptaan dalam susunan menaik.
-created_at: Susun mengikut masa penciptaan dalam susunan menurun.
Objek Tugas Prototip Kekunci adalah unit kerja yang Meshy pantau untuk menghasilkan satu imej reka bentuk kekunci siap daripada foto sumber. Hasil daripada peringkat ini dihubungkan ke peringkat binaan melalui input_task_id dan candidate_id.
Sifat-sifat
Name
id
Type
string
Description
Pengenal pasti unik untuk tugas. Walaupun kami menggunakan UUID yang boleh diurutkan k untuk id tugas sebagai perincian pelaksanaan, anda tidak seharusnya membuat sebarang andaian tentang format id.
Name
type
Type
string
Description
Jenis tugas. Nilainya adalah creative-lab-keycap-prototype.
Name
name
Type
string
Description
Nama tugas yang diberikan semasa tugas dicipta. Rentetan kosong jika tiada nama diberikan.
Name
status
Type
string
Description
Status tugas. Nilai yang mungkin adalah salah satu daripada PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Kemajuan tugas. Jika tugas belum dimulakan, sifat ini akan menjadi 0. Setelah tugas berjaya, ini akan menjadi 100.
Name
created_at
Type
timestamp
Description
Cap masa apabila tugas dicipta, dalam milisaat.
Cap masa mewakili bilangan milisaat yang berlalu sejak 1 Januari 1970 UTC, mengikut
piawaian RFC 3339.
Sebagai contoh, Jumaat, 1 September 2023 12:00:00 PM GMT diwakili sebagai 1693569600000. Ini terpakai
kepada semua cap masa dalam Meshy API.
Name
started_at
Type
timestamp
Description
Cap masa apabila tugas dimulakan, dalam milisaat. Jika tugas belum dimulakan, sifat ini akan menjadi 0.
Name
finished_at
Type
timestamp
Description
Cap masa apabila tugas selesai, dalam milisaat. Jika tugas belum selesai, sifat ini akan menjadi 0.
Name
expires_at
Type
timestamp
Description
Cap masa apabila hasil tugas tamat tempoh, dalam milisaat.
Name
preceding_tasks
Type
integer
Description
Bilangan tugas terdahulu.
Nilai medan ini hanya bermakna jika status tugas adalah PENDING.
Name
task_error
Type
object
Description
Butiran ralat untuk tugas yang gagal. Lihat Ralat untuk rujukan penuh objek task_error.
Name
consumed_credits
Type
integer
Description
Bilangan kredit yang digunakan oleh tugas ini. Tugas yang mencapai SUCCEEDED dikenakan caj penuh untuk peringkatnya. Tugas yang tidak pernah dicipta (kesalahan 4xx semasa masa permintaan, termasuk penolakan moderation) tidak dikenakan caj sama sekali. Tugas yang mencapai FAILED mengembalikan 0 — caj dikembalikan, termasuk blok moderation tidak segerak. Pembatalan melalui DELETE hanya mengembalikan wang semasa tugas masih PENDING; tugas yang sudah IN_PROGRESS tetap dikenakan caj, kerana kerja telah dilakukan.
Name
image_urls
Type
array of strings
Description
URL yang boleh dimuat turun bagi render reka bentuk kekunci siap — bagaimana calon kelihatan sebagai kekunci siap. Mengandungi satu entri; image_urls[i] sepadan dengan candidate_ids[i]. Kosong sehingga tugas mencapai SUCCEEDED. URL adalah untuk paparan sahaja; endpoint binaan menggunakan candidate_ids, bukan URL ini. Kitaran hayat URL sama seperti model_urls: ditandatangani, tiada header Authorization, sah sehingga expires_at, dan stabil apabila tugas dibaca semula.
Name
candidate_ids
Type
array of strings
Description
Pengenal pasti calon yang tidak telus, selari dengan image_urls. Serahkan entri yang sepadan dengan reka bentuk pilihan anda sebagai candidate_id permintaan binaan. Jangan buat sebarang andaian tentang format id ini.
Objek Tugas Pembinaan Keycap adalah unit kerja yang Meshy jejak untuk menghasilkan keycap 3D bertekstur akhir dari tugas prototaip yang berjaya dan calon yang dipilih. Satu pembinaan menjalankan keseluruhan saluran — penjanaan model putih, pemasangan dan pemotongan automatik, pewarnaan, pemasangan, dan eksport.
Sifat
Name
id
Type
string
Description
Pengenal pasti unik untuk tugas ini.
Name
type
Type
string
Description
Jenis tugas. Nilainya adalah creative-lab-keycap-build.
Name
name
Type
string
Description
Nama tugas yang diberikan semasa tugas dicipta. Rentetan kosong jika tiada nama diberikan.
Name
status
Type
string
Description
Status tugas. Nilai yang mungkin adalah salah satu daripada PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Kemajuan tugas. Jika tugas belum dimulakan, sifat ini akan menjadi 0. Setelah tugas berjaya, ini akan menjadi 100.
Name
created_at
Type
timestamp
Description
Cap masa apabila tugas dicipta, dalam milisaat.
Name
started_at
Type
timestamp
Description
Cap masa apabila tugas dimulakan, dalam milisaat.
Name
finished_at
Type
timestamp
Description
Cap masa apabila tugas selesai, dalam milisaat.
Name
expires_at
Type
timestamp
Description
Cap masa apabila hasil tugas tamat tempoh, dalam milisaat.
Name
preceding_tasks
Type
integer
Description
Bilangan tugas terdahulu. Bermakna hanya apabila status adalah PENDING.
Name
task_error
Type
object
Description
Butiran ralat untuk tugas yang gagal. Lihat Ralat untuk rujukan objek task_error penuh.
Name
consumed_credits
Type
integer
Description
Bilangan kredit yang digunakan oleh tugas ini. Tugas yang mencapai SUCCEEDED dikenakan caj penuh untuk tahapnya. Tugas yang tidak pernah dicipta (kesalahan 4xx pada masa permintaan, termasuk penolakan moderation) tidak dikenakan caj sama sekali. Tugas yang mencapai FAILED mengembalikan 0 — caj dikembalikan, termasuk blok moderation asinkron. Pembatalan melalui DELETE hanya mengembalikan wang semasa tugas masih PENDING; tugas yang sudah IN_PROGRESS tetap dikenakan caj, kerana kerja telah dilakukan.
Name
model_urls
Type
object
Description
URL yang boleh dimuat turun untuk artifak model yang dihasilkan. Kedua-dua GLB dan bundel OBJ dieksport pada skala milimeter dunia sebenar, Y-up, dengan bahagian depan keycap menghadap +Z. Jejaring dinamakan keycap-head dan keycap-base; apabila asas kembali kepada pengisian corak, jejaring ketiga keycap-base-interior juga hadir untuk rongga batang. Jangan anggap tepat dua jejaring.
Ini adalah URL yang ditandatangani: ambil mereka tanpa tajuk Authorization. Mereka kekal sah sehingga expires_at, iaitu 3 hari selepas finished_at, dan membaca semula tugas dalam tempoh itu mengembalikan URL yang sama dan bukannya yang baru ditandatangani. Muat turun dan simpan fail sendiri sebelum itu — tiada cara untuk menyegarkan pautan yang telah tamat tempoh.
Name
glb
Type
string
Description
URL yang boleh dimuat turun untuk model.glb bertekstur akhir.
Name
obj_zip
Type
string
Description
URL yang boleh dimuat turun untuk bundel zip yang mengandungi model.obj, model.mtl, dan PNG tekstur yang dirujuk oleh MTLnya. Asas warna pepejal hanya menghantar keycap-head.png; asas bercorak juga menghantar keycap-base.png.
Name
process_image_urls
Type
object
Description
URL yang boleh dimuat turun untuk imej proses perantaraan, dikunci mengikut jenis. Kitaran hayat URL yang sama seperti model_urls: ditandatangani, tiada tajuk Authorization, sah sehingga expires_at, dan stabil apabila tugas dibaca semula. Jenis yang dikeluarkan pada masa ini:
head_design — imej reka bentuk calon yang dipilih yang digunakan dalam pembinaan (sentiasa hadir).
composite — render paparan keycap siap calon yang dipilih (hadir apabila tersedia).
base_canvas — kanvas asas keycap yang dicat (hadir apabila tersedia).
Anggap set kunci sebagai terbuka; jenis baru boleh ditambah tanpa perubahan yang memecahkan.
Aliran lengkap: cipta prototaip daripada foto, pantau sehingga SUCCEEDED, pilih calon daripada candidate_ids, cipta binaan dengan calon tersebut, pantau binaan sehingga SUCCEEDED, kemudian muat turun GLB dan pakej OBJ daripada model_urls.
Contoh ini memilih calon pertama secara programatik. Dalam integrasi sebenar, anda akan memaparkan entri image_urls kepada pengguna akhir dan membiarkan mereka memilih; indeks yang dipilih memetakan 1:1 kepada candidate_ids.
Aliran lengkap
POST
/openapi/creative-lab/keycap/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://...:"${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">&2exit1fiBASE="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 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'{"image_url":"data:%s;base64,'"$MIME"base64<"$IMAGE_PATH"|tr-d'\n'printf'"}' } >"$BODY"elseprintf'{"image_url":"%s"}'"$IMAGE_URL">"$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 design renderpollprototype"$PROTO_ID"# 3. Pick a candidate (first one here; show image_urls to a user in production)CANDIDATE_ID=$(apiGET"$BASE/prototype/$PROTO_ID"|jq-r'.candidate_ids[0]')# 4. Create the build taskjq-n--argp"$PROTO_ID"--argc"$CANDIDATE_ID" \'{input_task_id: $p, candidate_id: $c}'>"$BODY"BUILD_ID=$(apiPOST"$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)pollbuild"$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=$(apiGET"$BASE/build/$BUILD_ID")curl--silent--show-error--fail--max-time900 \-okeycap.glb"$(jq-r '.model_urls.glb' <<<"$TASK")"curl--silent--show-error--fail--max-time900 \-okeycap-obj.zip"$(jq-r '.model_urls.obj_zip' <<<"$TASK")"echo"Done: keycap.glb + keycap-obj.zip"