lowpoly dihentikan pada 30 Okt 2026. Ganti model sebelum tanggal-tanggal ini agar permintaan tidak error. Lihat semua penghentian

API Keycap Creative Lab

Ubah sebuah foto menjadi keycap (tombol) kustom full-color untuk keyboard mekanik dalam dua tahap. Tugas prototipe menghasilkan gambar keycap jadi dari foto tersebut. Tugas build mengubah gambar tersebut menjadi model keycap 3D bertekstur. Tugas build ini menggunakan ID tugas prototipe sebagai input_task_id dan ID kandidat gambar sebagai candidate_id.

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

Kedua endpoint POST tersebut memerlukan paket berbayar. Permintaan dari akun paket gratis akan mengembalikan 402.


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

Membuat tugas prototipe Keycap

Menghasilkan satu gambar keycap jadi dari sebuah foto. Field image_urls tugas ini menyimpan gambarnya, dan candidate_ids menyimpan ID-nya, dengan satu entri di masing-masing. Jika Anda tidak menyukai desainnya, buat tugas prototipe lain. Meshy mengenakan biaya untuk setiap tugas prototipe secara terpisah.

Untuk membangun keycap 3D, kirimkan ID tugas ini ke endpoint build sebagai input_task_id, dengan entri candidate_ids sebagai candidate_id. Untuk field tugas ini, lihat Objek tugas prototipe Keycap.

Request

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>"
  }'

Response

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

Parameter

  • Name
    image_url
    Type
    string
    Wajib
    Description

    Foto yang akan diubah menjadi desain keycap, sebagai URL publik atau data URI (data:image/jpeg;base64,<data gambar Anda yang dienkode base64>).

    Gambar harus berupa file JPG, JPEG, PNG, atau WebP berukuran maksimal 20 MB (20.000.000 byte). Setiap sisi harus berukuran minimal 32 piksel, dan gambar dapat memiliki total maksimal 178.956.970 piksel. Gambar di luar batas ini mengembalikan 400.

    Meshy mendeteksi format dari data gambar, bukan dari ekstensi file di URL. URL tanpa ekstensi tetap berfungsi, dan Meshy mengikuti pengalihan HTTP. Meshy menerapkan orientasi EXIF, sehingga foto ponsel yang berputar akan muncul sesuai tampilan aslinya.

    Data URI harus dienkode base64 dengan jenis gambar, seperti data:image/png;base64,..., dan gambar yang didekode harus berupa JPEG, PNG, atau WebP. Batas 20 MB berlaku untuk gambar yang sudah didekode, sehingga teks base64-nya bisa sekitar sepertiga lebih besar.

  • Name
    name
    Type
    string
    Description

    Nama untuk tugas, hingga 100 karakter. Nama ini dikembalikan pada field name tugas. Nama yang lebih panjang mengembalikan 400.

  • Name
    remove_background
    Type
    boolean
    default false
    Description

    Apakah akan menghapus latar belakang dari gambar prototipe. true mengembalikan PNG RGBA transparan, sehingga Anda dapat menempatkan keycap pada latar belakang apa pun. Jika Meshy tidak dapat menghapus latar belakang, Meshy mengembalikan gambar dengan latar belakangnya, dan tugas tetap berhasil.

    Desain kepala yang diubah menjadi 3D oleh proses build tetap mempertahankan latar belakangnya terlepas dari pilihan ini. Build mewarnai dasar keycap dari gambar di image_urls, tanpa latar belakangnya jika Anda mengirim true. Build mengembalikan gambar tersebut sebagai process_image_urls.composite.

Hasil

Field result menyimpan ID tugas prototipe baru. Dapatkan tugasnya atau alirkan (stream) tugasnya hingga status bernilai SUCCEEDED. Kemudian kirimkan ID tersebut ke endpoint build sebagai input_task_id, dengan entri dari candidate_ids sebagai candidate_id.

Mode kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak dapat dijalankan. Misalnya:

    • image_url tidak ada.
    • Gambar bukan file JPG, JPEG, PNG, atau WebP.
    • Gambar terlalu kecil, lebih dari 20 MB, atau melebihi jumlah piksel maksimum.
    • Meshy tidak dapat mengunduh gambar, misalnya karena URL mengembalikan 404 atau waktu habis (timeout).
    • Data URI bukan base64 yang valid.
    • Gambar ditandai sebagai NSFW.

    Pesan error menjelaskan masalah apa yang ditemukan. Perbaiki permintaan, lalu kirim lagi.

  • Name
    401 - Unauthorized
    Description

    Kunci API tidak ada atau tidak valid. Periksa header Authorization.

  • Name
    402 - Payment Required
    Description

    Salah satu dari berikut ini berlaku:

    • Akun tidak memiliki kredit yang cukup.
    • Kunci API, ruang kerja, atau anggota mencapai batas kreditnya.
    • Akun menggunakan paket gratis.

    Periksa kredit dan paket Anda, lalu coba lagi.

  • Name
    403 - Forbidden
    Description

    Tim Anda mengaktifkan IP Filtering, dan Meshy menandai gambar tersebut karena kekayaan intelektual pihak ketiga. Kirim gambar yang hak penggunaannya Anda miliki.

  • Name
    429 - Too Many Requests
    Description

    Salah satu batas berikut tercapai:

    • Anda mengirim lebih banyak permintaan daripada yang diizinkan oleh batas laju Anda. Tunggu beberapa detik, lalu coba lagi. Lihat Batas laju.
    • Terlalu banyak tugas Anda yang sedang dalam antrean atau berjalan. Tunggu hingga beberapa selesai, lalu coba lagi.
    • Pada paket tak terbatas tanpa sisa kredit, Anda mencapai jumlah tugas yang dapat berjalan tanpa kredit. Tunggu hingga sebuah tugas selesai, atau tambahkan kredit.
  • Name
    500 - Internal Server Error
    Description

    Meshy mengalami kesalahan server, misalnya karena moderation konten atau pemeriksaan kekayaan intelektual tidak dapat dijalankan, atau Meshy tidak dapat menyimpan gambar. Meshy tidak membuat tugas tersebut, dan mengembalikan kredit apa pun yang telah dikenakan. Coba kirim permintaan lagi.


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

Buat tugas build Keycap

Menghasilkan keycap 3D bertekstur dari tugas prototipe yang berhasil dan salah satu kandidatnya. Untuk kolomnya, lihat Objek tugas build Keycap.

Satu tugas build menjalankan setiap langkah. Tugas ini menghasilkan model 3D dari desain dan mewarnainya. Kemudian tugas ini mendudukkan dan memotong model ke dasar keycap dalam pose default yang terkalibrasi, sehingga Anda tidak perlu menyesuaikannya secara manual. Terakhir, tugas ini merakit keycap dan mengekspor file-filenya. Satu build biasanya memakan waktu 3 hingga 7 menit.

Request

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
    }
  }'

Response

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

Parameter

  • Name
    input_task_id
    Type
    string
    Wajib
    Description

    ID tugas prototipe yang akan dibuild. ID ini harus berupa tugas yang dibuat akun Anda dengan POST /openapi/creative-lab/keycap/v1/prototype, dengan status SUCCEEDED.

    ID yang bukan merupakan salah satu tugas prototipe Keycap Anda dari API akan mengembalikan 404, termasuk prototipe yang dibuat di aplikasi web.

  • Name
    candidate_id
    Type
    string
    Wajib
    Description

    Kandidat yang akan dibuild, dari array candidate_ids milik tugas prototipe. Nilai yang tidak ada dalam array tersebut akan mengembalikan 400.

  • Name
    name
    Type
    string
    Description

    Nama untuk tugas, hingga 100 karakter. Nama ini akan muncul kembali di kolom name milik tugas. Nama yang lebih panjang akan mengembalikan 400.

options

Pengaturan geometri opsional. Setiap kolom memiliki default yang terkalibrasi, jadi kirim hanya kolom yang ingin Anda ubah.

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

    Dasar keycap untuk dibuild. Satu-satunya nilai adalah cherry-mx-1x1-r1, sebuah keycap profil Cherry MX 1u standar. Ukuran kustom tidak didukung, dan nilai lain apa pun akan mengembalikan 400.

  • Name
    head_size_mm
    Type
    number
    default 23
    Description

    Ukuran kepala sepanjang dimensi terpanjangnya, dalam milimeter, dari 10 hingga 40. Meshy menskalakan kepala sehingga dimensi terpanjangnya sesuai dengan nilai ini. Nilai di luar rentang akan mengembalikan 400.

    Untuk nilai di atas sekitar 32.9, Meshy mungkin mengurangi ukurannya agar kepala sesuai dengan batas jejak pelindung dasar. Kepala kemudian dapat menjadi lebih kecil dari yang Anda minta. Objek tugas tidak mengembalikan ukuran yang diterapkan Meshy. Untuk memeriksanya, ukur kotak pembatas dari mesh keycap-head di dalam model.

  • Name
    vertical_offset_mm
    Type
    number
    default 0
    Description

    Offset vertikal yang diterapkan pada kepala sebelum Meshy mendudukkannya pada dasar, dalam milimeter, dari -5 hingga 5. Nilai di luar rentang akan mengembalikan 400.

Hasil yang Dikembalikan

Kolom result berisi ID tugas build yang baru. Ambil tugasnya atau streaming tugasnya hingga status bernilai SUCCEEDED. Kemudian unduh file GLB dari model_urls.glb dan bundel OBJ dari model_urls.obj_zip.

Mode kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak dapat dijalankan. Misalnya:

    • input_task_id tidak ada atau bukan ID tugas yang valid.
    • Status tugas prototipe bukan SUCCEEDED. Jika masih berjalan, tunggu dan coba lagi. Jika gagal atau dibatalkan, buat tugas prototipe baru.
    • Tugas prototipe berhasil tetapi tidak memiliki kandidat. Buat tugas prototipe baru.
    • candidate_id tidak ada, atau tidak ada dalam candidate_ids milik tugas prototipe. Kirim nilai dari array tersebut.
    • Sebuah kolom dalam options berada di luar rentang, atau base_model bukan nilai yang tersedia.

    Pesan error menunjukkan masalah mana yang ditemukan.

  • Name
    401 - Unauthorized
    Description

    Kunci API tidak ada atau tidak valid. Periksa header Authorization.

  • Name
    402 - Payment Required
    Description

    Salah satu dari ini berlaku:

    • Akun tidak memiliki cukup kredit.
    • Kunci API, ruang kerja, atau anggota mencapai batas kreditnya.
    • Akun berada pada paket gratis.

    Periksa kredit dan paket Anda, lalu coba lagi.

  • Name
    404 - Not Found
    Description

    input_task_id tidak cocok dengan tugas prototipe Keycap mana pun yang dibuat akun Anda dengan API. Prototipe yang dibuat di aplikasi web juga akan mengembalikan 404. Kirim ID result dari respons pembuatan prototipe.

  • Name
    429 - Too Many Requests
    Description

    Salah satu batas berikut tercapai:

    • Anda mengirim lebih banyak permintaan daripada yang diizinkan oleh batas laju Anda. Tunggu beberapa detik, lalu coba lagi. Lihat Batas laju.
    • Terlalu banyak tugas Anda yang sedang dalam antrean atau berjalan. Tunggu hingga beberapa selesai, lalu coba lagi.
    • Pada paket tak terbatas tanpa sisa kredit, Anda telah mencapai jumlah tugas yang dapat berjalan tanpa kredit. Tunggu hingga sebuah tugas selesai, atau tambahkan kredit.
  • Name
    500 - Internal Server Error
    Description

    Meshy tidak dapat membuat tugas karena kesalahan server. Meshy mengembalikan kredit apa pun yang telah dibebankannya. Coba lagi permintaan tersebut.


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

Mendapatkan task Keycap

Mengembalikan task prototype atau build. Path harus sesuai dengan stage task tersebut. Task build yang diminta melalui /prototype/:id mengembalikan 404, begitu juga task prototype yang diminta melalui /build/:id.

Untuk field-field-nya, lihat The Keycap prototype task object dan The Keycap build task object.

Request

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}"

Prototype Response

{
  "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"
  ]
}

Build Response

{
  "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=***"
  }
}

Parameter

  • Name
    id
    Type
    path
    Description

    ID task dari respons create.

Returns

Objek task prototype atau objek task build, sesuai dengan stage pada path.

Mode kegagalan

  • Name
    400 - Bad Request
    Description

    id bukan ID task yang valid. Kirim ID result dari respons create.

  • Name
    403 - Forbidden
    Description

    Tim Anda mengaktifkan IP Filtering, dan Meshy menandai gambar task prototype tersebut karena kekayaan intelektual pihak ketiga. Task build dan tim pada paket Enterprise tidak mendapatkan error ini. Buat task prototype dari gambar yang hak penggunaannya Anda miliki.

  • Name
    404 - Not Found
    Description

    Tidak ada task Keycap dengan ID ini yang dimiliki akun Anda, atau stage task tidak sesuai dengan path. Periksa ID-nya, dan gunakan /prototype atau /build yang sesuai dengan task tersebut.

  • Name
    500 - Internal Server Error
    Description

    Meshy tidak dapat menjalankan pemeriksaan kekayaan intelektual. Coba lagi permintaan tersebut.


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

Hapus task Keycap

Membatalkan task Keycap. Membatalkan task PENDING akan mengembalikan kreditnya. Task IN_PROGRESS dibatalkan tanpa pengembalian dana, karena worker sudah mulai mengerjakannya. Task dengan status akhir (SUCCEEDED, FAILED, atau CANCELED) tidak dapat dibatalkan.

Path harus sesuai dengan tahap task tersebut. Misalnya, DELETE pada /prototype/:id dengan ID task build akan mengembalikan 404.

Request

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}"

Response

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

Parameter path

  • Name
    id
    Type
    path
    Description

    ID task yang akan dibatalkan.

Hasil yang dikembalikan

204 No Content dengan body kosong.

Mode kegagalan

  • Name
    400 - Bad Request
    Description

    Salah satu dari hal berikut berlaku:

    • id bukan ID task yang valid. Kirim ID result dari respons pembuatan.
    • Task sudah memiliki status akhir (SUCCEEDED, FAILED, atau CANCELED), sehingga tidak dapat dibatalkan.
  • Name
    404 - Not Found
    Description

    Tidak ada task Keycap dengan ID ini yang dimiliki oleh akun Anda, atau tahap task tidak cocok dengan path. Periksa ID-nya, dan gunakan /prototype atau /build yang sesuai dengan task tersebut.

  • Name
    500 - Internal Server Error
    Description

    Meshy mengalami kesalahan server saat membatalkan task, sehingga task mungkin sudah atau belum dibatalkan. Ambil task tersebut untuk memeriksa status-nya sebelum Anda mencoba lagi.


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

Stream a Keycap task

Mengalirkan pembaruan task Keycap sebagai Server-Sent Events (SSE). Path harus sesuai dengan tahap task tersebut. Jika tidak, misalnya ID task build pada /prototype/:id/stream, stream akan mengirim satu event error dengan status_code: 404 lalu ditutup.

Request

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.
// Every frame is the full task object; fields not yet populated are null / empty.
// The following PENDING frame is shortened to the fields that change.
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=***"
  }
}

Parameter

  • Name
    id
    Type
    path
    Description

    ID task dari respons pembuatan.

Returns

Sebuah stream objek task prototype atau build. Setiap event berisi objek task lengkap, sebagaimana dikembalikan oleh Get a Keycap task. Selama task masih PENDING atau IN_PROGRESS, kolom outputnya masih kosong (null, [], atau {}), dan finished_at bernilai null.

Jika IP Filtering memblokir hasil task, stream akan mengirim satu event error sebagai gantinya, dengan status_code yang sama seperti yang akan dikembalikan oleh permintaan get.


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

List Keycap tasks

Mengembalikan tugas Keycap Anda dari satu tahap, satu halaman pada satu waktu. Path menentukan tahapnya. /prototype hanya mengembalikan tugas prototype, dan /build hanya mengembalikan tugas build.

Request

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}"

Response (List Prototype Tasks)

[
  {
    "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"
    ]
  }
]

Parameter path

  • Name
    stage
    Type
    path
    Wajib
    Description

    Tahap yang akan ditampilkan, prototype atau build.

Parameter kueri

  • Name
    page_num
    Type
    integer
    default 1
    Description

    Halaman yang akan dikembalikan, dari 1 hingga 255. 0 mengembalikan halaman pertama. Nilai di luar 0 hingga 255 akan mengembalikan 400.

  • Name
    page_size
    Type
    integer
    default 10
    Description

    Jumlah tugas per halaman, hingga 100. Nilai dari 101 hingga 255 akan mengembalikan 100 tugas, dan 0 menggunakan nilai default. Nilai di luar 0 hingga 255 akan mengembalikan 400.

  • Name
    sort_by
    Type
    string
    default -created_at
    Description

    Urutan pengurutan.

    Nilai yang tersedia:

    • -created_at: terbaru lebih dulu
    • +created_at: terlama lebih dulu

Returns

Sebuah array berisi objek tugas prototype atau objek tugas build, sesuai dengan tahap pada path.


Objek tugas prototipe Keycap

Tugas prototipe menghasilkan satu gambar keycap jadi dari sebuah foto. Untuk mengubah desain menjadi keycap 3D, kirimkan ID tugas tersebut ke build endpoint sebagai input_task_id, dengan entri candidate_ids-nya sebagai candidate_id.

Properti

Example Keycap Prototype Task Object

{
  "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"
  ]
}
  • Name
    id
    Type
    string
    Description

    ID tugas. Jangan bergantung pada formatnya.

  • Name
    type
    Type
    string
    Description

    Tipe tugas, selalu creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    name yang Anda kirim saat membuat tugas, atau "" jika Anda tidak mengirimkannya.

  • Name
    status
    Type
    string
    Description

    Status tugas.

    Nilai yang tersedia:

    • PENDING: menunggu dalam antrean
    • IN_PROGRESS: menghasilkan hasil
    • SUCCEEDED: final, dengan hasil
    • FAILED: final, dengan alasan di task_error
    • CANCELED: final, tanpa hasil
  • Name
    progress
    Type
    integer
    Description

    Persentase pekerjaan yang telah selesai, dari 0 hingga 100. Nilainya 0 hingga tugas dimulai dan 100 saat berhasil.

  • Name
    created_at
    Type
    timestamp
    Description

    Waktu tugas dibuat, dalam milidetik Unix.

  • Name
    started_at
    Type
    timestamp
    Description

    Waktu seorang worker memulai tugas, dalam milidetik Unix. null hingga saat itu.

  • Name
    finished_at
    Type
    timestamp
    Description

    Waktu tugas mencapai status final, dalam milidetik Unix. null hingga saat itu.

  • Name
    expires_at
    Type
    timestamp
    Description

    Waktu hasil tugas kedaluwarsa, dalam milidetik Unix. Nilainya 3 hari setelah finished_at, atau 3 hari setelah created_at hingga tugas selesai. Untuk akun Enterprise, yang menyimpan hasil API tanpa batas waktu, nilainya sekitar 100 tahun kemudian. Lihat Retensi aset.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Posisi tugas dalam antrean selagi berstatus PENDING. 1 berarti tugas ini berikutnya yang akan dimulai. 0 setelah tugas keluar dari antrean, dan selalu 0 dalam hasil daftar.

  • Name
    task_error
    Type
    object
    Description

    Alasan tugas gagal. null kecuali status adalah FAILED. Lihat Kesalahan.

  • Name
    consumed_credits
    Type
    integer
    Description

    Jumlah kredit yang dikenakan untuk tugas, setelah pengembalian dana (jika ada). Permintaan yang mengembalikan kesalahan tidak dikenakan biaya. Tugas yang gagal bernilai 0, karena Meshy mengembalikan dananya. Membatalkan tugas hanya mengembalikan dana selagi tugas berstatus PENDING. Jika Meshy tidak dapat membaca biaya yang dikenakan, respons get atau stream akan menghilangkan field ini, dan permintaan daftar akan mengembalikan 500. Dalam kasus tersebut, coba lagi permintaannya.

  • Name
    image_urls
    Type
    array of strings
    Description

    URL unduhan untuk gambar keycap jadi. Array ini berisi satu URL setelah tugas berhasil, dan kosong hingga saat itu. image_urls[i] menampilkan kandidat di candidate_ids[i].

    URL ini digunakan untuk ditampilkan. Build endpoint mengambil entri dari candidate_ids, bukan URL. URL ini adalah signed URL, jadi ambil tanpa header Authorization. URL tetap berlaku hingga expires_at, dan mengambil tugas kembali akan mengembalikan URL yang sama.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    ID kandidat, dalam urutan yang sama dengan image_urls. Untuk membangun sebuah kandidat, kirim ID-nya sebagai candidate_id dalam permintaan build. Jangan bergantung pada format ID ini.


Objek tugas build Keycap

Sebuah tugas build menghasilkan keycap 3D bertekstur dari tugas prototype yang berhasil (succeeded) dan salah satu kandidatnya. Tugas ini menghasilkan model 3D, mewarnainya, mendudukkan dan memotongnya pada base keycap, lalu merakit dan mengekspor keycap tersebut.

Properties

Example Keycap Build Task Object

{
  "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=***"
  }
}
  • Name
    id
    Type
    string
    Description

    ID tugas. Jangan bergantung pada formatnya.

  • Name
    type
    Type
    string
    Description

    Jenis tugas, selalu creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    name yang Anda kirim saat membuat tugas, atau "" jika Anda tidak mengirimkannya.

  • Name
    status
    Type
    string
    Description

    Status tugas.

    Nilai yang tersedia:

    • PENDING: menunggu dalam antrean
    • IN_PROGRESS: sedang menghasilkan hasil
    • SUCCEEDED: final, dengan hasil
    • FAILED: final, dengan alasan di task_error
    • CANCELED: final, tanpa hasil
  • Name
    progress
    Type
    integer
    Description

    Persentase pekerjaan yang telah selesai, dari 0 hingga 100. Nilainya 0 hingga tugas dimulai dan 100 ketika berhasil.

  • Name
    created_at
    Type
    timestamp
    Description

    Waktu tugas dibuat, dalam milidetik Unix.

  • Name
    started_at
    Type
    timestamp
    Description

    Waktu sebuah worker memulai tugas, dalam milidetik Unix. null sampai saat itu.

  • Name
    finished_at
    Type
    timestamp
    Description

    Waktu tugas mencapai status final, dalam milidetik Unix. null sampai saat itu.

  • Name
    expires_at
    Type
    timestamp
    Description

    Waktu hasil tugas kedaluwarsa, dalam milidetik Unix. Nilainya 3 hari setelah finished_at, atau 3 hari setelah created_at sampai tugas selesai. Untuk akun Enterprise, yang menyimpan hasil API tanpa batas waktu, nilainya sekitar 100 tahun kemudian. Lihat Retensi aset.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Posisi tugas dalam antrean selama statusnya PENDING. 1 berarti tugas ini akan dimulai berikutnya. 0 setelah tugas keluar dari antrean, dan selalu 0 dalam hasil daftar (list).

  • Name
    task_error
    Type
    object
    Description

    Alasan tugas gagal. null kecuali status adalah FAILED. Lihat Kesalahan.

  • Name
    consumed_credits
    Type
    integer
    Description

    Jumlah kredit yang dikenakan untuk tugas ini, setelah dikurangi pengembalian dana (refund) jika ada. Permintaan yang mengembalikan kesalahan tidak akan dikenakan biaya. Tugas yang gagal bernilai 0, karena Meshy mengembalikan dananya. Membatalkan tugas hanya mengembalikan dana selama tugas masih PENDING. Jika Meshy tidak dapat membaca biaya yang dikenakan, respons get atau stream akan menghilangkan field ini, dan permintaan list akan mengembalikan 500. Dalam kasus ini, coba lagi permintaan tersebut.

  • Name
    model_urls
    Type
    object
    Description

    URL unduhan untuk model 3D. Meshy mengekspor file GLB dan bundel OBJ dalam skala dunia nyata dalam milimeter, Y-up, dengan bagian depan keycap menghadap +Z.

    Model ini memiliki mesh bernama keycap-head dan keycap-base. Ketika Meshy beralih ke pengisian pola (pattern fill) untuk base, model juga memiliki mesh keycap-base-interior untuk rongga stem. Jangan asumsikan model selalu memiliki tepat dua mesh.

    Ini adalah URL yang ditandatangani (signed URLs), jadi ambil tanpa header Authorization. URL ini tetap berlaku hingga expires_at, dan mengambil tugas yang sama lagi sebelum itu akan mengembalikan URL yang sama. URL yang telah kedaluwarsa tidak dapat diperbarui, jadi unduh dan simpan file-file tersebut sebelum itu terjadi.

    • Name
      glb
      Type
      string
      Description

      URL unduhan untuk file GLB bertekstur, model.glb.

    • Name
      obj_zip
      Type
      string
      Description

      URL unduhan untuk bundel OBJ, sebuah file ZIP berisi model.obj, model.mtl, dan tekstur PNG yang digunakan oleh model.mtl. Dengan base berwarna solid, satu-satunya tekstur adalah keycap-head.png. Dengan base berpola, file ZIP juga berisi keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    URL unduhan untuk gambar dari langkah-langkah build, dikelompokkan berdasarkan jenisnya. Seperti model_urls, ini adalah URL yang ditandatangani (signed URLs), jadi ambil tanpa header Authorization. URL ini tetap berlaku hingga expires_at, dan mengambil tugas lagi akan mengembalikan URL yang sama.

    Objek ini dapat memiliki kunci-kunci berikut:

    • head_design: gambar desain dari kandidat yang dipilih, yang diubah oleh build menjadi 3D. Selalu ada.
    • composite: gambar keycap jadi untuk kandidat yang dipilih, yang menjadi dasar pewarnaan base oleh build. Bisa saja tidak ada.
    • base_canvas: base keycap yang telah diwarnai. Bisa saja tidak ada.

    Meshy dapat menambahkan kunci baru, jadi abaikan kunci yang tidak Anda kenali.


Contoh end-to-end

Contoh ini menjalankan keseluruhan alur:

  1. Membuat tugas prototype dari sebuah foto.
  2. Mengambil tugas tersebut hingga status-nya SUCCEEDED.
  3. Memilih satu kandidat dari candidate_ids.
  4. Membuat tugas build dengan kandidat tersebut.
  5. Mengambil tugas build tersebut hingga status-nya SUCCEEDED.
  6. Mengunduh file GLB dan paket OBJ dari model_urls.

Contoh ini memilih kandidat pertama. Pada aplikasi Anda, tampilkan entri image_urls kepada pengguna dan biarkan mereka memilih. Indeks sebuah gambar yang dipilih dalam image_urls adalah indeks ID-nya dalam candidate_ids.

Complete flow

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"