Creative Lab — Keycap API

Ubah foto sumber menjadi keycap keyboard mekanik kustom berwarna penuh dalam dua tahap: prototipe menghasilkan render desain "keycap selesai" dari foto input Anda. Setelah Anda mengonfirmasi render tersebut, pembangunan mengubahnya menjadi model keycap 3D bertekstur dalam satu kali proses — pembuatan model putih, penempatan dan pemotongan otomatis pada pose default yang terkalibrasi, pewarnaan model penuh, dan perakitan akhir semuanya terjadi dalam satu tugas pembangunan. Kedua tahap tersebut terhubung melalui input_task_id ditambah candidate_id.

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

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

Buat Tugas Prototipe Keycap

Hasilkan render desain keycap yang sudah jadi dari foto sumber. Hasil tugas membawa array image_urls (render tampilan dari keycap yang sudah jadi) dan array candidate_ids paralel; keduanya memegang satu entri. Panggil endpoint ini lagi untuk render lain jika hasilnya tidak sesuai keinginan Anda — setiap panggilan dikenakan biaya terpisah. Berikan candidate_id bersama dengan ID tugas prototipe ke endpoint build. Lihat Objek Tugas Prototipe Keycap untuk bentuk respons.

Parameter

  • Name
    image_url
    Type
    string
    Wajib
    Description

    Foto sumber untuk Meshy untuk diubah menjadi gambar desain keycap. Kami saat ini mendukung format .jpg, .jpeg, .png, dan .webp.

    Format dideteksi dengan mendekode data gambar, bukan dari ekstensi file URL — URL tanpa ekstensi, atau yang mengarahkan ulang, berfungsi selama byte dapat didekode ke format yang didukung. Pengalihan HTTP diikuti. Orientasi EXIF dinormalisasi, sehingga foto ponsel yang diputar digunakan sesuai tampilannya.

    Batasan: setidaknya 32 piksel di setiap sisi, paling banyak 178,956,970 piksel secara total, dan paling banyak 20,000,000 byte setelah diunduh. Untuk Data URI, batasan berlaku untuk byte yang didekode, sehingga file sumber itu sendiri dapat mencapai ukuran tersebut — teks base64 yang sekitar sepertiga lebih besar, yang penting untuk body permintaan Anda, bukan untuk batasan ini. Data URI harus menyatakan tipe konten image/* dan ;base64.

    Ada dua cara untuk menyediakan gambar:

    • URL yang dapat diakses publik: URL yang dapat diakses dari internet publik.
    • Data URI: Data URI yang dikodekan base64 dari gambar. Contoh Data URI: data:image/jpeg;base64,<your base64-encoded image data>.
  • Name
    name
    Type
    string
    Description

    Nama tugas opsional untuk tujuan tampilan. Maksimal 100 karakter.

  • Name
    remove_background
    Type
    boolean
    default false
    Description

    Ketika diatur ke true, render tampilan yang dikembalikan dalam image_urls adalah PNG RGBA transparan dengan latar belakang dihapus, sehingga Anda dapat menggabungkannya ke latar belakang mana pun.

    Ini berlaku hanya untuk render tampilan. Kandidat yang dikonsumsi oleh endpoint build tidak terpengaruh, sehingga hasil 3D identik dalam kedua cara.

Mengembalikan

Properti result dari respons berisi id tugas dari tugas prototipe keycap yang baru dibuat. Pantau endpoint Dapatkan Tugas atau berlangganan stream hingga tugas mencapai SUCCEEDED, lalu ambil entri dari candidate_ids dan berikan, bersama dengan ID tugas, ke endpoint build.

Mode Kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak dapat diterima. Penyebab umum:

    • Parameter hilang: image_url diperlukan.
    • Format gambar tidak valid: image_url yang diberikan bukan format yang didukung (.jpg, .jpeg, .png, .webp).
    • Dimensi gambar di luar jangkauan: 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 rusak.
    • Konten ditandai: Gambar input ditandai oleh moderation NSFW.
  • Name
    401 - Unauthorized
    Description

    Autentikasi gagal. Silakan periksa kunci API Anda.

  • Name
    402 - Payment Required
    Description

    Akun berada pada paket gratis (paket berbayar diperlukan untuk membuat tugas) atau tidak memiliki kredit yang cukup.

  • Name
    403 - Forbidden
    Description

    Gambar input ditandai oleh moderation hak kekayaan intelektual.

  • Name
    429 - Too Many Requests
    Description

    Anda telah melebihi batas laju Anda.

  • Name
    500 - Internal Server Error
    Description

    Terjadi kesalahan server yang tidak terduga — misalnya layanan moderation konten tidak tersedia, staging gambar input gagal, atau tugas tidak dapat dibuat. Tidak ada tugas yang dibuat dalam kasus ini, jadi mencoba lagi aman.

Permintaan

POST
/openapi/creative-lab/keycap/v1/prototype
# Stage 1: generate a finished-keycap design render
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype \
  -X POST \
  -H "Authorization: Bearer ${YOUR_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "image_url": "<your publicly accessible image url or base64-encoded data URI>"
  }'

Respons

{
  "result": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef"
}

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

Membuat Tugas Pembuatan Keycap

Menghasilkan model keycap 3D bertekstur akhir dari tugas prototipe yang berhasil dan salah satu kandidatnya. Satu tugas pembuatan menjalankan seluruh pipeline dari awal hingga akhir — pembuatan model putih dari desain yang dipilih, pemasangan dan pemotongan otomatis pada dasar keycap menggunakan pose default yang dikalibrasi (tidak perlu penyesuaian interaktif), pewarnaan model penuh, dan perakitan serta ekspor akhir. Pembuatan biasanya memakan waktu 3–7 menit, menuju akhir yang lebih tinggi ketika beberapa pembuatan berjalan bersamaan. Lihat Objek Tugas Pembuatan Keycap untuk bentuk respons.

Parameter

  • Name
    input_task_id
    Type
    string
    Wajib
    Description

    ID tugas dari tugas prototipe yang dibuat melalui endpoint OpenAPI ini. Prototipe harus dibuat oleh akun Meshy yang sama, harus mencapai SUCCEEDED, dan harus menghasilkan setidaknya satu kandidat.

    Tugas prototipe yang dibuat melalui webapp tidak diterima — endpoint pembuatan hanya menerima tugas prototipe yang dihasilkan oleh POST /openapi/creative-lab/keycap/v1/prototype dan menolak sumber lain dengan 404.

  • Name
    candidate_id
    Type
    string
    Wajib
    Description

    Kandidat untuk dibangun, diambil dari array candidate_ids dari tugas prototipe yang berhasil. Harus milik tugas tersebut; nilai lain ditolak dengan 400.

  • Name
    name
    Type
    string
    Description

    Nama tugas opsional untuk tujuan tampilan. Maksimum 100 karakter.

options

Penyesuaian geometri opsional. Setiap bidang memiliki default yang dikalibrasi — kirim hanya yang ingin Anda ganti.

  • Name
    base_model
    Type
    string
    default cherry-mx-1x1-r1
    Description

    Dasar keycap untuk dibangun. Saat ini satu-satunya nilai yang tersedia adalah cherry-mx-1x1-r1 — profil Cherry MX standar 1u. 3–5 ukuran standar mainstream tambahan direncanakan; ukuran kustom tidak didukung.

  • Name
    head_size_mm
    Type
    number
    default 23
    Description

    Ukuran target dari kepala yang dipahat, dalam milimeter: dimensi terpanjangnya diskalakan ke nilai ini. Rentang: [10, 40]. Nilai di atas sekitar 32.9 dapat dikurangi sehingga kepala masih sesuai dengan batas jejak pelindung dasar, sehingga dimensi terpanjang yang dikirimkan bisa lebih kecil dari yang diminta. Nilai yang diterapkan tidak dikembalikan pada objek tugas hari ini — jika Anda perlu mengonfirmasi ukuran yang sebenarnya Anda terima, ukur kotak pembatas dari mesh keycap-head dalam model yang diunduh.

  • Name
    vertical_offset_mm
    Type
    number
    default 0
    Description

    Offset vertikal yang diterapkan pada kepala sebelum dipasang pada dasar, dalam milimeter. Rentang: [-5, 5].

Mengembalikan

Properti result dari respons berisi id tugas dari tugas pembuatan keycap yang baru dibuat. Polling endpoint Dapatkan Tugas atau berlangganan stream hingga tugas mencapai SUCCEEDED, kemudian unduh artefak dari model_urls.glb dan model_urls.obj_zip.

Mode Kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak dapat diterima. Penyebab umum:

    • Parameter hilang: input_task_id dan candidate_id diperlukan.
    • UUID tidak valid: input_task_id bukan UUID yang valid.
    • Induk tidak berhasil: Tugas prototipe yang dirujuk belum mencapai SUCCEEDED.
    • Tidak ada kandidat: Tugas prototipe berhasil tetapi tidak menghasilkan kandidat.
    • Kandidat tidak dikenal: candidate_id bukan salah satu kandidat tugas input.
    • Opsi di luar jangkauan: Salah satu bidang options berada di luar rentang yang diizinkan atau set enum.
  • Name
    401 - Unauthorized
    Description

    Autentikasi gagal. Silakan periksa kunci API Anda.

  • Name
    402 - Payment Required
    Description

    Akun berada pada paket gratis (paket berbayar diperlukan untuk membuat tugas) atau tidak memiliki kredit yang cukup.

  • Name
    404 - Not Found
    Description

    Tugas prototipe yang dirujuk tidak ada, milik pengguna lain, atau dibuat melalui webapp (hanya tugas prototipe mode API yang dapat dirantai ke pembuatan).

  • Name
    429 - Too Many Requests
    Description

    Anda telah melebihi batas laju Anda.

  • Name
    500 - Internal Server Error
    Description

    Terjadi kesalahan tak terduga di sisi server — misalnya layanan moderasi konten tidak tersedia, staging gambar input gagal, atau tugas tidak dapat dibuat. Tidak ada tugas yang dibuat dalam kasus ini, jadi mencoba lagi aman.

Permintaan

POST
/openapi/creative-lab/keycap/v1/build
# Stage 2: build the chosen candidate into a 3D keycap
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build \
  -X POST \
  -H "Authorization: Bearer ${YOUR_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "input_task_id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
    "candidate_id": "0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b",
    "options": {
      "base_model": "cherry-mx-1x1-r1",
      "head_size_mm": 23,
      "vertical_offset_mm": 0
    }
  }'

Respons

{
  "result": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af"
}

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

Mengambil Tugas Keycap

Ambil tugas prototipe atau build yang diberikan dengan id tugas yang valid. Jalur URL harus sesuai dengan tahap tugas — tugas build yang diambil melalui /prototype/:id akan mengembalikan 404, dan sebaliknya.

Lihat Objek Tugas Prototipe Keycap dan Objek Tugas Build Keycap untuk bentuk respons.

Parameter

  • Name
    id
    Type
    path
    Description

    Pengenal unik untuk tugas keycap yang akan diambil.

Mengembalikan

Respons berisi objek tugas keycap. Bentuknya tergantung pada tahap mana yang diminta.

Permintaan

GET
/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef
# Prototype
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

# Build
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

Respons Prototipe

{
  "id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
  "type": "creative-lab-keycap-prototype",
  "name": "",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142456000,
  "started_at": 1753142460000,
  "finished_at": 1753142516000,
  "expires_at": 1753401716000,
  "preceding_tasks": 0,
  "task_error": null,
  "consumed_credits": 12,
  "image_urls": [
    "https://assets.meshy.ai/***/design-1.png?Expires=***"
  ],
  "candidate_ids": [
    "0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
  ]
}

Respons Build

{
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "type": "creative-lab-keycap-build",
  "name": "",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142600000,
  "started_at": 1753142610000,
  "finished_at": 1753143050000,
  "expires_at": 1753402250000,
  "preceding_tasks": 0,
  "task_error": null,
  "consumed_credits": 50,
  "model_urls": {
    "glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
    "obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
  },
  "process_image_urls": {
    "head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***",
    "composite": "https://assets.meshy.ai/***/composite.png?Expires=***",
    "base_canvas": "https://assets.meshy.ai/***/base-canvas.png?Expires=***"
  }
}

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

Hapus Tugas Keycap

Batalkan tugas keycap. Jika tugas masih PENDING, kredit yang digunakan saat pembuatan akan dikembalikan. Tugas yang sudah IN_PROGRESS dibatalkan tanpa pengembalian dana (pekerja mungkin sudah menggunakan sumber daya). Tugas yang sudah mencapai status akhir (SUCCEEDED, FAILED, CANCELED) tidak dapat dibatalkan.

Jalur URL harus sesuai dengan tahap tugas — DELETE pada /prototype/:buildId mengembalikan 404.

Parameter Jalur

  • Name
    id
    Type
    path
    Description

    Pengenal unik untuk tugas keycap yang akan dibatalkan.

Pengembalian

Mengembalikan 204 No Content jika berhasil dengan tubuh kosong.

Mode Kegagalan

  • Name
    400 - Bad Request
    Description

    Tugas sudah dalam status akhir dan tidak dapat dibatalkan.

  • Name
    404 - Not Found
    Description

    Tugas tidak ada, milik pengguna lain, atau tahapannya tidak sesuai dengan jalur URL.

  • Name
    500 - Internal Server Error
    Description

    Terjadi kesalahan tak terduga di sisi server saat membatalkan. Tugas mungkin sudah atau belum dibatalkan — baca ulang untuk mengonfirmasi sebelum mencoba lagi.

Permintaan

DELETE
/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef
curl --request DELETE \
  --url https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

Respon

// Returns 204 No Content on success (empty body).

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

Streaming Tugas Keycap

Streaming pembaruan real-time untuk tugas keycap melalui Server-Sent Events (SSE). Jalur URL harus sesuai dengan tahap tugas — membuka stream di /prototype/:buildId/stream akan mengeluarkan satu event: error payload dengan status_code: 404 dan menutup stream.

Parameter

  • Name
    id
    Type
    path
    Description

    Pengenal unik untuk tugas keycap yang akan di-stream.

Mengembalikan

Mengembalikan stream dari objek tugas Keycap Prototype atau Keycap Build sebagai Server-Sent Events. Untuk tugas PENDING atau IN_PROGRESS, stream respons hanya akan menyertakan bidang progress dan status yang diperlukan.

Permintaan

GET
/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream
curl -N https://api.meshy.ai/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream \
-H "Authorization: Bearer ${YOUR_API_KEY}"

Response Stream

// Error event example (wrong stage or task not found)
event: error
data: {
  "status_code": 404,
  "message": "Task not found"
}

// Message event examples illustrate task progress.
// For PENDING or IN_PROGRESS tasks, the response stream will not include all fields.
event: message
data: {
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "progress": 0,
  "status": "PENDING"
}

event: message
data: {
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "type": "creative-lab-keycap-build",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142600000,
  "started_at": 1753142610000,
  "finished_at": 1753143050000,
  "expires_at": 1753402250000,
  "task_error": null,
  "consumed_credits": 50,
  "model_urls": {
    "glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
    "obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
  },
  "process_image_urls": {
    "head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***"
  }
}

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

Daftar Tugas Keycap

Ambil daftar tugas keycap Anda yang dipaginasi untuk satu tahap. Jalur URL memilih tahap — /prototype mengembalikan tugas prototipe; /build mengembalikan tugas build. Tugas dari tahap lain tidak termasuk dalam kedua respons.

Parameter Jalur

  • Name
    stage
    Type
    path
    Wajib
    Description

    Baik prototype atau build. Koleksi hanya mengembalikan tugas yang tahapnya sesuai dengan URL — mengambil /prototype tidak pernah mengembalikan tugas build dan sebaliknya.

Parameter Kuery

  • 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

    Bidang untuk diurutkan. Nilai yang tersedia:

    • +created_at: Urutkan berdasarkan waktu pembuatan dalam urutan naik.
    • -created_at: Urutkan berdasarkan waktu pembuatan dalam urutan turun.

Mengembalikan

Mengembalikan daftar tugas per tahap yang dipaginasi — baik objek tugas prototipe keycap saat mendaftar /prototype atau objek tugas build keycap saat mendaftar /build.

Permintaan

GET
/openapi/creative-lab/keycap/v1/prototype
# List prototype tasks
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype?page_size=10 \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

# List build tasks
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/build?page_size=10 \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

Respons (Daftar Tugas Prototipe)

[
  {
    "id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
    "type": "creative-lab-keycap-prototype",
    "name": "",
    "status": "SUCCEEDED",
    "progress": 100,
    "created_at": 1753142456000,
    "started_at": 1753142460000,
    "finished_at": 1753142516000,
    "expires_at": 1753401716000,
    "preceding_tasks": 0,
    "task_error": null,
    "consumed_credits": 12,
    "image_urls": [
      "https://assets.meshy.ai/***/design-1.png?Expires=***"
    ],
    "candidate_ids": [
      "0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
    ]
  }
]

Objek Tugas Prototipe Keycap

Objek Tugas Prototipe Keycap adalah unit kerja yang dilacak oleh Meshy untuk menghasilkan satu gambar desain keycap selesai dari foto sumber. Hasil dari tahap ini dihubungkan ke tahap pembuatan melalui input_task_id plus candidate_id.

Properti

  • Name
    id
    Type
    string
    Description

    Pengenal unik untuk tugas. Meskipun kami menggunakan UUID yang dapat diurutkan secara k untuk id tugas sebagai detail implementasi, Anda tidak boleh membuat asumsi apa pun 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 saat tugas dibuat. String kosong jika tidak ada nama yang diberikan.

  • Name
    status
    Type
    string
    Description

    Status tugas. Nilai yang mungkin adalah salah satu dari PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Kemajuan tugas. Jika tugas belum dimulai, properti ini akan menjadi 0. Setelah tugas berhasil, ini akan menjadi 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas dibuat, dalam milidetik.

  • Name
    started_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas dimulai, dalam milidetik. Jika tugas belum dimulai, properti ini akan menjadi 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas selesai, dalam milidetik. Jika tugas belum selesai, properti ini akan menjadi 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Stempel waktu saat hasil tugas kedaluwarsa, dalam milidetik.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Jumlah tugas sebelumnya.

  • Name
    task_error
    Type
    object
    Description

    Detail kesalahan untuk tugas yang gagal. Lihat Kesalahan untuk referensi lengkap objek task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    Jumlah kredit yang dikonsumsi oleh tugas ini. Tugas yang mencapai SUCCEEDED dikenakan biaya penuh untuk tahapannya. Tugas yang tidak pernah dibuat (kesalahan 4xx saat permintaan, termasuk penolakan moderasi) tidak dikenakan biaya sama sekali. Tugas yang mencapai FAILED mengembalikan 0 — biaya dikembalikan, termasuk blok moderasi asinkron. Pembatalan melalui DELETE hanya mengembalikan biaya saat tugas masih PENDING; tugas yang sudah IN_PROGRESS tetap dikenakan biaya, karena pekerjaan telah dilakukan.

  • Name
    image_urls
    Type
    array of strings
    Description

    URL yang dapat diunduh dari render desain keycap selesai — seperti apa kandidat terlihat sebagai keycap selesai. Memiliki satu entri; image_urls[i] sesuai dengan candidate_ids[i]. Kosong sampai tugas mencapai SUCCEEDED. URL ini hanya untuk tampilan; endpoint pembuatan mengonsumsi candidate_ids, bukan URL ini. Siklus hidup URL sama dengan model_urls: ditandatangani, tanpa header Authorization, berlaku hingga expires_at, dan stabil saat tugas dibaca ulang.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Pengenal kandidat yang tidak transparan, paralel dengan image_urls. Kirim entri yang sesuai dengan desain pilihan Anda sebagai candidate_id permintaan pembuatan. Jangan membuat asumsi apa pun tentang format id ini.

Contoh Objek Tugas Prototipe Keycap

{
  "id": "019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef",
  "type": "creative-lab-keycap-prototype",
  "name": "",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142456000,
  "started_at": 1753142460000,
  "finished_at": 1753142516000,
  "expires_at": 1753401716000,
  "preceding_tasks": 0,
  "task_error": null,
  "consumed_credits": 12,
  "image_urls": [
    "https://assets.meshy.ai/***/design-1.png?Expires=***"
  ],
  "candidate_ids": [
    "0198c1b2-33f5-7d21-a4b7-8e9d0c1f2a3b"
  ]
}

Objek Tugas Pembuatan Keycap

Objek Tugas Pembuatan Keycap adalah unit kerja yang dilacak oleh Meshy untuk menghasilkan keycap 3D bertekstur akhir dari tugas prototipe yang berhasil dan kandidat yang dipilih. Satu pembuatan menjalankan seluruh pipeline — pembuatan model putih, pemasangan dan pemotongan otomatis, pewarnaan, perakitan, dan ekspor.

Properti

  • Name
    id
    Type
    string
    Description

    Pengenal unik untuk tugas tersebut.

  • Name
    type
    Type
    string
    Description

    Jenis tugas. Nilainya adalah creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    Nama tugas yang diberikan saat tugas dibuat. String kosong jika tidak ada nama yang diberikan.

  • Name
    status
    Type
    string
    Description

    Status dari tugas. Nilai yang mungkin adalah salah satu dari PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Kemajuan dari tugas. Jika tugas belum dimulai, properti ini akan bernilai 0. Setelah tugas berhasil, ini akan menjadi 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas dibuat, dalam milidetik.

  • Name
    started_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas dimulai, dalam milidetik.

  • Name
    finished_at
    Type
    timestamp
    Description

    Stempel waktu saat tugas selesai, dalam milidetik.

  • Name
    expires_at
    Type
    timestamp
    Description

    Stempel waktu saat hasil tugas kedaluwarsa, dalam milidetik.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Jumlah tugas sebelumnya. Bermakna hanya ketika status adalah PENDING.

  • Name
    task_error
    Type
    object
    Description

    Detail kesalahan untuk tugas yang gagal. Lihat Kesalahan untuk referensi objek task_error lengkap.

  • Name
    consumed_credits
    Type
    integer
    Description

    Jumlah kredit yang dikonsumsi oleh tugas ini. Tugas yang mencapai SUCCEEDED dikenakan biaya penuh untuk tahapannya. Tugas yang tidak pernah dibuat (kesalahan 4xx saat permintaan, termasuk penolakan moderasi) tidak dikenakan biaya sama sekali. Tugas yang mencapai FAILED mengembalikan 0 — biaya dikembalikan, termasuk blok moderasi asinkron. Pembatalan melalui DELETE hanya mengembalikan biaya saat tugas masih PENDING; tugas yang sudah IN_PROGRESS tetap dikenakan biaya, karena pekerjaan telah dilakukan.

  • Name
    model_urls
    Type
    object
    Description

    URL yang dapat diunduh untuk artefak model yang dihasilkan. Baik bundel GLB maupun OBJ diekspor pada skala milimeter dunia nyata, Y-up, dengan bagian depan keycap menghadap +Z. Mesh dinamai keycap-head dan keycap-base; ketika dasar kembali ke pola isian, mesh ketiga keycap-base-interior juga hadir untuk rongga batang. Jangan berasumsi hanya ada dua mesh.

    Ini adalah URL yang ditandatangani: ambil tanpa header Authorization. Mereka tetap valid hingga expires_at, yaitu 3 hari setelah finished_at, dan membaca ulang tugas dalam jangka waktu tersebut mengembalikan URL yang identik daripada yang baru ditandatangani. Unduh dan simpan file sendiri sebelum itu — tidak ada cara untuk memperbarui tautan yang kedaluwarsa.

    • Name
      glb
      Type
      string
      Description

      URL yang dapat diunduh ke model.glb bertekstur akhir.

    • Name
      obj_zip
      Type
      string
      Description

      URL yang dapat diunduh ke bundel zip yang berisi model.obj, model.mtl, dan PNG tekstur yang sebenarnya dirujuk oleh MTL-nya. Basis warna solid hanya mengirimkan keycap-head.png; basis berpola juga mengirimkan keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    URL yang dapat diunduh untuk gambar proses antara, diindeks berdasarkan jenis. Siklus hidup URL sama seperti model_urls: ditandatangani, tanpa header Authorization, valid hingga expires_at, dan stabil saat tugas dibaca ulang. Jenis yang saat ini dihasilkan:

    • head_design — gambar desain kandidat yang dipilih yang dikonsumsi oleh pembuatan (selalu ada).
    • composite — render tampilan keycap selesai dari kandidat yang dipilih (ada jika tersedia).
    • base_canvas — kanvas dasar keycap yang dicat (ada jika tersedia).

    Perlakukan set kunci sebagai terbuka; jenis baru dapat ditambahkan tanpa perubahan yang merusak.

Contoh Objek Tugas Pembuatan Keycap

{
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "type": "creative-lab-keycap-build",
  "name": "",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142600000,
  "started_at": 1753142610000,
  "finished_at": 1753143050000,
  "expires_at": 1753402250000,
  "preceding_tasks": 0,
  "task_error": null,
  "consumed_credits": 50,
  "model_urls": {
    "glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
    "obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
  },
  "process_image_urls": {
    "head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***",
    "composite": "https://assets.meshy.ai/***/composite.png?Expires=***",
    "base_canvas": "https://assets.meshy.ai/***/base-canvas.png?Expires=***"
  }
}

Contoh End-to-End

Alur lengkap: buat prototipe dari foto, polling hingga SUCCEEDED, pilih kandidat dari candidate_ids, buat build dengan kandidat tersebut, polling build hingga SUCCEEDED, lalu unduh GLB dan bundel OBJ dari model_urls.

Contoh ini memilih kandidat pertama secara programatis. Dalam integrasi nyata, Anda akan menampilkan entri image_urls kepada pengguna akhir dan membiarkan mereka memilih; indeks yang dipilih memetakan 1:1 ke candidate_ids.

Alur lengkap

POST
/openapi/creative-lab/keycap/v1
#!/usr/bin/env bash
set -euo pipefail

# Requires curl and jq. Point IMAGE_PATH at a local photo, or IMAGE_URL at a public one:
#   export MESHY_API_KEY=msy_...
#   export IMAGE_PATH=./portrait.jpg          # or: export IMAGE_URL=https://...
: "${MESHY_API_KEY:?export MESHY_API_KEY first}"
if [[ -z "${IMAGE_PATH:-}" && -z "${IMAGE_URL:-}" ]]; then
  echo "export IMAGE_PATH (local file) or IMAGE_URL (public url) first" >&2
  exit 1
fi

BASE="https://api.meshy.ai/openapi/creative-lab/keycap/v1"
AUTH="Authorization: Bearer $MESHY_API_KEY"

# api METHOD URL [curl args...] -> prints the response body, non-zero on failure.
# Note we do not use -f/--fail: it discards the body, and the body is the only
# place the reason appears.
api() {
  local method=$1 url=$2 out http_code body
  shift 2
  out=$(curl --silent --show-error --max-time 60 --write-out $'\n%{http_code}' \
    -X "$method" "$url" -H "$AUTH" "$@") || return 1
  http_code=${out##*$'\n'}
  body=${out%$'\n'*}
  if ((http_code >= 400)); then
    echo "HTTP $http_code for $url: $body" >&2
    return 1
  fi
  printf '%s' "$body"
}

# Each task gets its own 40-minute budget.
poll() {
  local kind=$1 id=$2 delay=5 task_status deadline
  deadline=$(($(date +%s) + 2400))
  while :; do
    if (($(date +%s) >= deadline)); then
      echo "gave up waiting for $kind $id" >&2
      return 1
    fi
    task_status=$(api GET "$BASE/$kind/$id" | jq -r '.status')
    echo "$kind: $task_status"
    case "$task_status" in
    SUCCEEDED) return 0 ;;
    FAILED | CANCELED) return 1 ;;
    esac
    sleep "$delay"
    delay=$((delay * 2 > 30 ? 30 : delay * 2))
  done
}

# Build the request body in a file. A base64 data URI must never go on the
# command line or into an exported variable - a photo of any real size will
# exceed the OS argument limit.
BODY=$(mktemp)
trap 'rm -f "$BODY"' EXIT
if [[ -n "${IMAGE_PATH:-}" ]]; then
  # Declare the real type: the API accepts JPEG, PNG and WebP.
  case "$(printf '%s' "${IMAGE_PATH##*.}" | tr 'A-Z' 'a-z')" in
    png) MIME=image/png ;;
    webp) MIME=image/webp ;;
    *) MIME=image/jpeg ;;
  esac
  {
    printf '{"image_url":"data:%s;base64,' "$MIME"
    base64 <"$IMAGE_PATH" | tr -d '\n'
    printf '"}'
  } >"$BODY"
else
  printf '{"image_url":"%s"}' "$IMAGE_URL" >"$BODY"
fi

# 1. Create the prototype task
PROTO_ID=$(api POST "$BASE/prototype" \
  -H 'Content-Type: application/json' --data-binary @"$BODY" | jq -r '.result')

# 2. Wait for the design render
poll prototype "$PROTO_ID"

# 3. Pick a candidate (first one here; show image_urls to a user in production)
CANDIDATE_ID=$(api GET "$BASE/prototype/$PROTO_ID" | jq -r '.candidate_ids[0]')

# 4. Create the build task
jq -n --arg p "$PROTO_ID" --arg c "$CANDIDATE_ID" \
  '{input_task_id: $p, candidate_id: $c}' >"$BODY"
BUILD_ID=$(api POST "$BASE/build" \
  -H 'Content-Type: application/json' --data-binary @"$BODY" | jq -r '.result')

# 5. Wait for the model (a build usually takes 3-7 minutes)
poll build "$BUILD_ID"

# 6. Download the artifacts. These are signed URLs: no Authorization header,
#    and they stay valid for 3 days after the task finishes.
TASK=$(api GET "$BASE/build/$BUILD_ID")
curl --silent --show-error --fail --max-time 900 \
  -o keycap.glb "$(jq -r '.model_urls.glb' <<<"$TASK")"
curl --silent --show-error --fail --max-time 900 \
  -o keycap-obj.zip "$(jq -r '.model_urls.obj_zip' <<<"$TASK")"
echo "Done: keycap.glb + keycap-obj.zip"