Bir kaynak fotoğrafı, iki aşamada çok renkli, 3D baskıya uygun piksel sanatı bir fidget tahtasına dönüştürün:
prototip aşaması fotoğrafınızı bir piksel sanatı görüntüsüne dönüştürür, ardından
yapı aşaması bu görüntüyü 16×16 veya 32×32'lik bir ızgaraya örnekler ve her pikseli
birbirine kilitlenen kare veya altıgen bir parçaya dönüştürür; nesneleri kendi renklerini
taşıyan tek bir 3MF dosyası olarak sunulur, böylece çok filamentli bir dilimleyici her
parçayı doğru renkte basar. İki aşama input_task_id aracılığıyla birbirine bağlanır.
POST /openapi/creative-lab/fidget-pixel/v1/prototype
POST /openapi/creative-lab/fidget-pixel/v1/build
Her iki POST endpoint'i de ücretli bir abonelik planı gerektirir. Ücretsiz
plandaki hesaplardan gelen istekler 402 Payment Required ile reddedilir.
Kaynak fotoğraftan tek bir piksel-art görüntü oluşturur. Döndürülen görev
ID'si, build uç noktasına input_task_id olarak geçirdiğiniz değerdir. Sonuç
istediğiniz gibi değilse başka bir deneme için bu uç noktayı tekrar
çağırabilirsiniz — her çağrı ayrı ayrı faturalandırılır. Yanıt şekli için
Fidget Pixel Prototip Görevi Nesnesi
bölümüne bakın.
Parametreler
Name
image_url
Type
string
Zorunlu
Description
Meshy'nin pikselleştireceği kaynak fotoğraf. Şu anda .jpg, .jpeg, .png ve .webp formatlarını destekliyoruz.
Format, görüntü verisi çözümlenerek tespit edilir, URL'nin dosya uzantısından değil — uzantısı olmayan veya yönlendirme yapan bir URL, baytlar desteklenen bir formata çözümlendiği sürece çalışır. HTTP yönlendirmeleri takip edilir.
Görüntüyü sağlamanın iki yolu vardır:
Herkese açık erişilebilir URL: Genel internetten erişilebilen bir URL.
Data URI: Görüntünün base64 ile kodlanmış bir data URI'si. Data URI örneği: data:image/jpeg;base64,<base64 ile kodlanmış görüntü verileriniz>.
Name
type
Type
string
Zorunlu
Description
Fotoğrafın neyi gösterdiği. Pikselleştirme stilini belirler, bu yüzden bilinçli seçin — ikisi belirgin şekilde farklı sonuçlar üretir. Mevcut değerler:
person — konu bir kişidir (portre veya tam vücut). Konunun chibi tarzı piksel sprite'ını üretir.
other — diğer her şey: evcil hayvanlar, nesneler, maskotlar, logolar, manzaralar. Konunun boncuk sanatı tarzı piksel simgesini üretir.
Name
name
Type
string
Description
Görüntüleme amaçlı isteğe bağlı görev adı. Maksimum 100 karakter.
Dönüş Değerleri
Yanıtın result özelliği, yeni oluşturulan fidget pixel prototip görevinin id bilgisini içerir. Görev SUCCEEDED durumuna ulaşana kadar Bir Görev Al uç noktasını yoklayın veya stream'e abone olun, ardından bu ID'yi build uç noktasınainput_task_id olarak geçirin.
Hata Modları
Name
400 - Bad Request
Description
İstek kabul edilemedi. Yaygın nedenler:
Eksik parametre: image_url ve type alanlarının her ikisi de zorunludur.
Geçersiz type: type değeri person veya other olmalıdır.
Geçersiz görüntü formatı: Sağlanan image_url desteklenen bir formatta değil (.jpg, .jpeg, .png, .webp).
Görüntü boyutları aralık dışında: Görüntü çok küçük, maksimum dosya boyutunu aşıyor veya maksimum piksel sayısını aşıyor.
Erişilemeyen URL: image_url indirilemedi (404 veya timeout).
Geçersiz Data URI: base64 dizesi hatalı biçimlendirilmiş.
İçerik işaretlendi: Girdi görüntüsü NSFW moderation tarafından işaretlendi.
Name
401 - Unauthorized
Description
Kimlik doğrulama başarısız oldu. Lütfen API anahtarınızı kontrol edin.
Name
402 - Payment Required
Description
Bu görevi gerçekleştirmek için yetersiz kredi veya API anahtarı ücretsiz plana ait bir hesaba ait.
Name
403 - Forbidden
Description
Girdi görüntüsü fikri mülkiyet moderation tarafından işaretlendi (Content flagged for intellectual property violation). Yalnızca fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları engellenir; herhangi bir ücret alınmaz.
Name
429 - Too Many Requests
Description
Hız sınırınızı aştınız.
Name
500 - Internal Server Error
Description
Fikri mülkiyet kontrolünün kendisi tamamlanamadı (Unable to perform intellectual property check, please try again). Fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları bu kontrolde güvenli tarafta kalarak başarısız olur; herhangi bir ücret alınmaz — isteği tekrar deneyin.
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" }'
Başarılı bir prototip görevinden 3D baskıya uygun parçaları oluşturun. Build,
prototipin piksel-art görüntüsünü istenen ızgaraya örnekler, bunu en
fazla color_count renge kuantalar ve her ızgara hücresi için birbirine
geçen bir parça oluşturur. Çıktı, her parçanın renkleriyle etiketlenmiş
ayrı bir nesne olarak yer aldığı, çoklu filaman dilimleyici için hazır
tek bir 3MF dosyasıdır. Yanıt şekli için
The Fidget Pixel Build Task Object
bölümüne bakın.
Parametreler
Name
input_task_id
Type
string
Zorunlu
Description
Aynı bu OpenAPI uç noktası aracılığıyla oluşturulmuş bir prototip görevinin görev kimliği. Prototip, aynı Meshy hesabı tarafından oluşturulmuş olmalı ve SUCCEEDED durumuna ulaşmış olmalıdır.
Webapp aracılığıyla oluşturulan prototip görevleri kabul edilmez — build uç noktası yalnızca POST /openapi/creative-lab/fidget-pixel/v1/prototype tarafından üretilen prototip görevlerini kabul eder ve başka herhangi bir kaynağı 404 ile reddeder.
Name
name
Type
string
Description
Görüntüleme amaçlı isteğe bağlı görev adı. Maksimum 100 karakter.
options
İsteğe bağlı parça geometrisi. Her alanın bir varsayılan değeri vardır — yalnızca geçersiz kılmak istediklerinizi gönderin. Bunlar Creative Lab webapp'inin sunduğu aynı kontrollerdir; fiş yüksekliği, kapak ölçeği ve diğer üretim ön ayarları shape ve piece_size_mm değerlerinden türetilir ve dışarıya açılmaz.
Name
shape
Type
string
varsayılan square
Description
Her parçanın tabanı. Kullanılabilir değerler:
square (varsayılan) — kare ızgara üzerinde kare parçalar.
hex — altıgen ızgara üzerinde altıgen parçalar. Altıgen parçalar yalnızca 6 ve 8 mm olarak mevcuttur.
Name
grid_size
Type
integer
varsayılan 32
Description
Tahtanın her bir kenarı boyunca parça sayısı. Kullanılabilir değerler: 16 veya 32. Bir 32 ızgara daha fazla detay korur; bir 16 ızgara aynı konu için daha az ve daha büyük parça anlamına gelir.
Name
piece_size_mm
Type
integer
varsayılan 8
Description
Her parçanın kenar uzunluğu, milimetre cinsinden. Kullanılabilir değerler: 6, 8 veya 10. grid_size ile birlikte bu, basılan tahta boyutunu belirler — örneğin 32 × 8 mm ≈ kenar başına 26 cm. 10, shape: "hex" için kullanılamaz (eğik altıgen yüzü çoğu tüketici FDM yazıcısında taşma yapar).
Name
color_count
Type
integer
varsayılan 8
Description
Görüntünün kuantalanacağı paletteki maksimum renk sayısı. Aralık: [1, 8]. Her renk, dilimleyicinizde bir filamana karşılık gelir.
Name
piece_height_mm
Type
integer
varsayılan 15
Description
Her parçanın yüksekliği, milimetre cinsinden. Aralık: [10, 80].
output
İsteğe bağlı iletim biçimi seçici. Varsayılan olarak 3mf kullanılır ve şu anda desteklenen tek değer budur.
Name
format
Type
string
varsayılan 3mf
Description
Build tarafından döndürülen çıktı. Kullanılabilir değerler:
3mf (varsayılan) — model_urls.3mf altında, her parça için bir nesne ve her nesneye eklenmiş parça rengiyle birlikte tek bir model.3mf döndürür.
Dönüş Değerleri
Yanıtın result özelliği, yeni oluşturulan fidget pixel build görevinin id değerini içerir. Görev SUCCEEDED durumuna ulaşana kadar Get a Task uç noktasını yoklayın veya stream'e abone olun, ardından çıktıyı model_urls.3mf üzerinden indirin.
Hata Durumları
Name
400 - Bad Request
Description
İstek kabul edilemedi. Yaygın nedenler:
Eksik parametre: input_task_id zorunludur.
Geçersiz UUID: input_task_id geçerli bir UUID değil.
Üst görev başarılı değil: Referans verilen prototip görevi henüz SUCCEEDED durumuna ulaşmadı.
Aday yok: Prototip görevi başarılı oldu ancak piksel-art görüntüsü üretmedi; yeni bir prototip oluşturun.
Seçenekler aralık dışında: options alanlarından biri izin verilen küme veya aralığın dışında — örneğin options.grid_size must be 16 or 32, veya options.piece_size_mm=10 is not supported for shape=hex; hex pieces are available in 6 and 8 mm.
Desteklenmeyen format: output.format3mf olmalıdır.
Name
401 - Unauthorized
Description
Kimlik doğrulama başarısız oldu. Lütfen API anahtarınızı kontrol edin.
Name
402 - Payment Required
Description
Bu görevi gerçekleştirmek için yetersiz kredi veya API anahtarı ücretsiz plan hesabına ait.
Name
403 - Forbidden
Description
Referans verilen prototipin görüntüsü fikri mülkiyet moderation tarafından işaretlendi. Yalnızca fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları engellenir; herhangi bir ücret alınmaz.
Name
404 - Not Found
Description
Referans verilen prototip görevi mevcut değil, başka bir kullanıcıya ait veya webapp aracılığıyla oluşturulmuş (yalnızca API-mode prototip görevleri build'e zincirlenebilir).
Name
429 - Too Many Requests
Description
Hız sınırınızı aştınız.
Name
500 - Internal Server Error
Description
Referans verilen prototipin fikri mülkiyet kararı belirlenemedi (Unable to perform intellectual property check, please try again). Fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları bu kontrolde başarısız olur; herhangi bir ücret alınmaz — isteği yeniden deneyin.
Geçerli bir görev id değeri verildiğinde bir prototip veya build görevini getirir. URL yolu,
görevin aşamasıyla eşleşmelidir — /prototype/:id üzerinden getirilen bir build görevi
404 döndürür, ve tam tersi de geçerlidir.
Getirilecek fidget pixel görevi için benzersiz tanımlayıcı.
Dönüş Değerleri
Yanıt, fidget pixel görev nesnesini içerir. Şekli, hangi aşamanın
istendiğine bağlıdır.
Hata Modları
Name
400 - Bad Request
Description
id geçerli bir UUID değil (Invalid ID).
Name
403 - Forbidden
Description
Görevin görseli, fikri mülkiyet moderasyonu tarafından işaretlendi. Yalnızca fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları engellenir.
Name
404 - Not Found
Description
Görev mevcut değil, farklı bir kullanıcıya ait ya da aşaması URL yoluyla eşleşmiyor.
Name
500 - Internal Server Error
Description
Fikri mülkiyet kontrolü tamamlanamadı (Unable to perform intellectual property check, please try again); fikri mülkiyet filtrelemesi etkinleştirilmiş Enterprise hesapları için işlem başarısız kabul edilir. İsteği yeniden deneyin.
Bir fidget pixel görevini iptal eder. Görev hâlâ PENDING durumundaysa,
oluşturma sırasında harcanan kredi iade edilir. Zaten IN_PROGRESS
durumunda olan görevler iade yapılmadan iptal edilir (işçi zaten
kaynakları tüketiyor olabilir). Zaten sonlanmış bir duruma ulaşmış
görevler (SUCCEEDED, FAILED, CANCELED) iptal edilemez.
Bir fidget pixel görevi için Server-Sent Events (SSE) aracılığıyla gerçek zamanlı güncellemeleri akışa alın.
URL yolu, görevin aşamasıyla eşleşmelidir — /prototype/:buildId/stream adresinde
bir akış açmak, status_code: 404 değerine sahip tek bir event: error
yükü yayınlar ve akışı kapatır; hatalı biçimlendirilmiş bir id de aynısını
status_code: 400 (Invalid ID) ile yapar.
Parametreler
Name
id
Type
path
Description
Akışa alınacak fidget pixel görevi için benzersiz tanımlayıcı.
Dönüş Değerleri
Server-Sent Events olarak bir Fidget Pixel Prototype
veya Fidget Pixel Build görev nesneleri akışı döndürür.
Her kare, ilgili aşamaya ait tam görev nesnesini taşır — bu, Get
uç noktasının döndürdüğü aynı biçimdir — bu nedenle görev PENDING veya IN_PROGRESS
durumundayken çıktı alanları henüz doldurulmamıştır (null, [] veya {}) ve
finished_at değeri null'dır.
Tek bir aşama için fidget pixel görevlerinizin sayfalanmış listesini alır.
URL yolu aşamayı seçer — /prototype prototip görevlerini döndürür;
/build ise derleme (build) görevlerini döndürür. Diğer aşamaya ait görevler
her iki yanıta da dahil edilmez.
Yol Parametreleri
Name
stage
Type
path
Zorunlu
Description
prototype veya build değerlerinden biri. Koleksiyon yalnızca
aşaması URL ile eşleşen görevleri döndürür — /prototype almak
asla build görevlerini döndürmez ve bunun tersi de geçerlidir.
Sorgu Parametreleri
Name
page_num
Type
integer
varsayılan 1
Description
Sayfalama için sayfa numarası.
Name
page_size
Type
integer
varsayılan 10
Description
Sayfa boyutu sınırı. İzin verilen maksimum değer 100 öğedir.
Name
sort_by
Type
string
varsayılan -created_at
Description
Sıralama yapılacak alan. Kullanılabilir değerler:
+created_at: Oluşturulma zamanına göre artan sırada sıralar.
-created_at: Oluşturulma zamanına göre azalan sırada sıralar.
Fidget Pixel Prototip Görev nesnesi, Meshy'nin bir kaynak fotoğrafı piksel-sanatı görüntüsüne dönüştürmek için takip ettiği bir iş birimidir. Bu aşamanın çıktısı, input_task_id aracılığıyla derleme aşamasına zincirlenir.
Özellikler
Name
id
Type
string
Description
Görev için benzersiz tanımlayıcı. Uygulama detayı olarak görev kimlikleri için k-sıralanabilir bir UUID kullansak da, kimliğin biçimi hakkında herhangi bir varsayımda bulunmamalısınız.
Name
type
Type
string
Description
Görevin türü. Değer creative-lab-fidget-pixel-prototype şeklindedir.
Name
name
Type
string
Description
Görev oluşturulduğunda sağlanan görev adı. Ad sağlanmadıysa boş dizedir.
Görevin ilerlemesi. Görev henüz başlamadıysa, bu özellik 0 olacaktır. Görev başarıyla tamamlandığında, bu değer 100 olacaktır.
Name
created_at
Type
timestamp
Description
Görevin oluşturulduğu zamanın milisaniye cinsinden zaman damgası.
Bir zaman damgası, RFC 3339 standardını takip ederek,
1 Ocak 1970 UTC'den bu yana geçen milisaniye sayısını temsil eder.
Örneğin, 1 Eylül 2023 Cuma günü GMT saatiyle 12:00:00, 1693569600000 olarak temsil edilir. Bu, Meshy API'deki
tüm zaman damgaları için geçerlidir.
Name
started_at
Type
timestamp
Description
Görevin başladığı zamanın milisaniye cinsinden zaman damgası. Görev henüz başlamadıysa, bu özellik null olacaktır.
Name
finished_at
Type
timestamp
Description
Görevin tamamlandığı zamanın milisaniye cinsinden zaman damgası. Görev henüz tamamlanmadıysa, bu özellik null olacaktır.
Name
expires_at
Type
timestamp
Description
Görev sonucunun süresinin dolacağı zamanın milisaniye cinsinden zaman damgası — görev tamamlandıktan 3 gün sonra. Kurumsal hesaplar API sonuçlarını süresiz olarak saklar (bkz. Varlık Saklama); bu hesaplar için bu zaman damgası yaklaşık 100 yıl sonrasına ayarlanır.
Name
preceding_tasks
Type
integer
Description
Önceki görevlerin sayısı.
Bu alanın değeri yalnızca görev durumu PENDING olduğunda anlamlıdır.
Name
task_error
Type
object
Description
Başarısız görevler için hata ayrıntıları. Tam task_error nesne referansı için Hatalar bölümüne bakın.
Name
consumed_credits
Type
integer
Description
Bu görev tarafından tüketilen kredi sayısı. SUCCEEDED durumuna ulaşan bir görevden, ait olduğu aşamanın tam tutarı tahsil edilir. Hiçbir zaman oluşturulmayan bir görevden (istek anında bir 4xx, moderation reddi dahil) hiçbir ücret alınmaz. FAILED durumuna ulaşan bir görev 0 döndürür — ücret iade edilir. DELETE ile iptal etmek yalnızca görev hâlâ PENDING durumundayken iade sağlar; zaten IN_PROGRESS olan bir görev, iş harcandığı için ücretlendirilmeye devam eder.
Name
image_urls
Type
array of strings
Description
Bu prototip görevi tarafından oluşturulan piksel-sanatı görüntüsü için indirilebilir URL'ler. Şu anda API her zaman tam olarak bir görüntü döndürür; alan bir dizi olarak tanımlanmıştır, böylece gelecekteki revizyonlar geriye dönük uyumluluğu bozmadan birden fazla aday sunabilir. Görev SUCCEEDED durumuna ulaşana kadar boştur.
Bunlar imzalı URL'lerdir: bunları bir Authorization başlığı olmadan getirin. finished_at'ten 3 gün sonrası olan expires_at'e kadar geçerli kalırlar ve bu pencere içinde görevi yeniden okumak, yeni imzalanmış bir URL yerine aynı URL'yi döndürür. O zamandan önce dosyaları kendiniz indirip saklayın — süresi dolmuş bir bağlantıyı yenilemenin bir yolu yoktur.
Fidget Pixel Build Task nesnesi, başarılı bir prototip görevinden basılabilir parçaları üretmek için Meshy'nin takip ettiği bir iş birimidir. Build, prototipin pixel-art görüntüsünü istenen ızgaraya örnekler ve tek bir renk etiketli 3MF yayımlar.
Özellikler
Name
id
Type
string
Description
Görev için benzersiz tanımlayıcı.
Name
type
Type
string
Description
Görevin türü. Değer creative-lab-fidget-pixel-build'dir.
Name
name
Type
string
Description
Görev oluşturulduğunda sağlanan görev adı. Ad sağlanmadıysa boş dizedir.
Görevin progress değeri. Görev henüz başlamadıysa bu özellik 0 olur. Görev başarılı olduğunda bu değer 100 olur.
Name
created_at
Type
timestamp
Description
Görevin oluşturulduğu andaki zaman damgası, milisaniye cinsinden.
Name
started_at
Type
timestamp
Description
Görevin başladığı andaki zaman damgası, milisaniye cinsinden. Görev başlayana kadar null değerindedir.
Name
finished_at
Type
timestamp
Description
Görevin tamamlandığı andaki zaman damgası, milisaniye cinsinden. Görev tamamlanana kadar null değerindedir.
Name
expires_at
Type
timestamp
Description
Görev sonucunun süresinin dolacağı andaki zaman damgası, milisaniye cinsinden — görevin tamamlanmasından 3 gün sonra. Kurumsal (Enterprise) hesaplar API sonuçlarını süresiz olarak saklar (bkz. Varlık Saklama); bu hesaplar için bu zaman damgası yaklaşık 100 yıl sonrasına ayarlanır.
Name
preceding_tasks
Type
integer
Description
Önceki görevlerin sayısı. Yalnızca durum PENDING olduğunda anlamlıdır.
Name
task_error
Type
object
Description
Başarısız görevler için hata ayrıntıları. Tam task_error nesne referansı için Hatalar bölümüne bakın.
Name
consumed_credits
Type
integer
Description
Bu görev tarafından tüketilen kredi sayısı. SUCCEEDED durumuna ulaşan bir görevden, aşamasının tam tutarı tahsil edilir. Hiç oluşturulmamış bir görevden (istek sırasında bir 4xx hatası, moderation reddi dahil) hiçbir ücret alınmaz. FAILED durumuna ulaşan bir görev 0 döndürür — ücret iade edilir. DELETE ile iptal etme yalnızca görev hâlâ PENDING durumundayken ücreti iade eder; zaten IN_PROGRESS durumundaki bir görevin ücreti, iş harcandığı için tahsil edilmiş olarak kalır.
Name
model_urls
Type
object
Description
Üretilen çıktı için biçime göre anahtarlanmış indirilebilir URL'ler. Tam olarak bir giriş içerir — build isteğinin output.format alanı aracılığıyla istenen biçim. Görev SUCCEEDED durumuna ulaşana kadar boştur.
Bunlar imzalı URL'lerdir: bunları Authorization başlığı olmadan alın. Bunlar, finished_at'ten 3 gün sonrası olan expires_at'e kadar geçerli kalır ve bu süre içinde görevi yeniden okumak, yeni imzalanmış bir URL yerine aynı URL'yi döndürür. Dosyaları bu süre dolmadan önce kendiniz indirip saklayın — süresi dolmuş bir bağlantıyı yenilemenin bir yolu yoktur.
Name
3mf
Type
string
Description
3MF dosyasına indirilebilir URL. Parça başına bir nesne, her biri paletindeki renkle etiketlenmiştir; böylece çok filamentli bir dilimleyici filamentleri renge göre atayabilir. output.format değeri 3mf (varsayılan) olduğunda mevcuttur.
Eksiksiz akış: bir fotoğraftan prototip oluşturun, SUCCEEDED durumuna kadar sorgulayın, bundan bir yapı (build) oluşturun, yapıyı SUCCEEDED durumuna kadar sorgulayın, ardından 3MF'yi model_urls üzerinden indirin.
Bir prototip genellikle birkaç dakika içinde tamamlanır; bir yapı ise tipik olarak bir dakikadan çok daha kısa sürede tamamlanır. Gerçek bir entegrasyonda, yapı için kredi harcamadan önce prototipin image_urls girdisini son kullanıcıya gösterip onaylamasını (veya prototipi yeniden çalıştırmasını) sağlarsınız.
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"