Creative Lab — Keycap API

Tukar foto sumber kepada keycap papan kekunci mekanikal tersuai berwarna penuh dalam dua peringkat: prototaip menjana render reka bentuk "keycap siap" daripada foto input anda. Setelah anda mengesahkan render tersebut, binaan menukarkannya kepada model keycap 3D bertekstur dalam satu larian — penjanaan model putih, pendudukan dan pemotongan automatik pada pose lalai yang ditentukur, pewarnaan model penuh, dan pemasangan akhir semuanya berlaku dalam satu tugas binaan. Kedua-dua peringkat ini dihubungkan melalui input_task_id beserta candidate_id.

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

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

Cipta Tugasan Prototaip Keycap

Jana render reka bentuk keycap siap daripada foto sumber. Hasil tugasan membawa array image_urls (render paparan bagi keycap yang siap) dan array candidate_ids yang selari; kedua-duanya memegang satu entri sahaja. Panggil endpoint ini sekali lagi untuk render lain jika hasilnya bukan yang anda mahu — setiap panggilan dicaj secara berasingan. Hantar candidate_id bersama-sama dengan ID tugasan prototaip kepada endpoint build. Rujuk Objek Tugasan Prototaip Keycap untuk bentuk respons.

Parameter

  • Name
    image_url
    Type
    string
    Diperlukan
    Description

    Foto sumber untuk Meshy menukarkannya menjadi imej reka bentuk keycap. Kami kini menyokong format .jpg, .jpeg, .png, dan .webp.

    Format dikesan dengan mengekod semula (decode) data imej, bukan daripada sambungan fail URL — URL tanpa sambungan, atau yang mengubah hala (redirect), tetap berfungsi selagi bait-bait tersebut boleh dikod semula kepada format yang disokong. Pengubahan hala HTTP akan diikuti. Orientasi EXIF dinormalisasi, jadi foto telefon yang berputar akan digunakan mengikut cara ia kelihatan.

    Had: sekurang-kurangnya 32 piksel pada setiap sisi, paling banyak 178,956,970 piksel secara keseluruhan, dan paling banyak 20,000,000 bait selepas dimuat turun. Untuk Data URI, had ini terpakai kepada bait yang telah dinyahkod (decoded), jadi fail sumber itu sendiri boleh mencapai saiz tersebut — teks base64 yang kira-kira satu pertiga lebih besar itulah yang penting untuk badan permintaan (request body) 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 daripada internet awam.
    • Data URI: Data URI imej yang dikod dalam base64. Contoh Data URI: data:image/jpeg;base64,<data imej anda yang dikod base64>.
  • Name
    name
    Type
    string
    Description

    Nama tugasan 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 lutsinar dengan latar belakang dibuang, jadi anda boleh menggabungkannya (composite) ke atas mana-mana latar belakang.

    Ini hanya terpakai kepada render paparan sahaja. Calon yang digunakan oleh endpoint build tidak terjejas, jadi hasil 3D adalah sama sahaja.

Pemulangan

Sifat result bagi respons mengandungi id tugasan bagi tugasan prototaip keycap yang baru dicipta. Poll endpoint Get a Task atau langgan stream sehingga tugasan mencapai SUCCEEDED, kemudian ambil entri daripada candidate_ids dan hantarkannya, bersama-sama dengan ID tugasan, kepada endpoint build.

Mod Kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak boleh diterima. Punca biasa:

    • Parameter hilang: image_url diperlukan.
    • Format imej tidak sah: image_url yang diberikan bukan format yang disokong (.jpg, .jpeg, .png, .webp).
    • Dimensi imej di luar julat: Imej terlalu kecil, melebihi saiz fail maksimum, atau melebihi bilangan piksel maksimum.
    • URL tidak boleh dicapai: image_url tidak dapat dimuat turun (404 atau timeout).
    • Data URI tidak sah: Rentetan base64 tidak sah bentuknya.
    • Kandungan ditandai: Imej input ditandai 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 tugasan) atau mempunyai kredit yang tidak mencukupi.

  • Name
    403 - Forbidden
    Description

    Imej input ditandai oleh moderation harta intelek.

  • Name
    429 - Too Many Requests
    Description

    Anda telah melebihi had kadar anda.

  • Name
    500 - Internal Server Error
    Description

    Ralat sisi pelayan yang tidak dijangka berlaku — sebagai contoh perkhidmatan moderation kandungan tidak tersedia, penyediaan imej input gagal, atau tugasan tidak dapat dicipta. Tiada tugasan dicipta dalam kes ini, jadi mencuba semula adalah selamat.

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

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

Cipta Tugas Pembinaan Keycap

Menjana model keycap 3D bertekstur akhir daripada tugas prototaip yang berjaya dan salah satu calonnya. Satu tugas pembinaan menjalankan keseluruhan saluran paip dari hujung ke hujung — penjanaan model putih daripada reka bentuk yang dipilih, kedudukan dan pemotongan automatik ke atas asas keycap menggunakan kedudukan lalai yang dikalibrasi (tiada pelarasan interaktif diperlukan), pewarnaan model penuh, serta pemasangan dan eksport akhir. Pembinaan biasanya mengambil masa 3–7 minit, ke arah penghujung atas apabila beberapa pembinaan dijalankan serentak. Rujuk The Keycap Build Task Object untuk bentuk respons.

Parameter

  • Name
    input_task_id
    Type
    string
    Diperlukan
    Description

    ID tugas bagi tugas prototaip yang dicipta melalui endpoint OpenAPI yang sama. Prototaip mestilah dicipta oleh akaun Meshy yang sama, mesti telah mencapai SUCCEEDED, dan mesti telah menghasilkan sekurang-kurangnya satu calon.

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

  • Name
    candidate_id
    Type
    string
    Diperlukan
    Description

    Calon yang hendak dibina, diambil daripada tatasusunan candidate_ids bagi tugas prototaip yang berjaya. Mesti tergolong dalam tugas tersebut; sebarang nilai lain akan ditolak dengan 400.

  • Name
    name
    Type
    string
    Description

    Nama tugas pilihan untuk tujuan paparan. Maksimum 100 aksara.

options

Penalaan geometri pilihan. Setiap medan mempunyai nilai lalai yang dikalibrasi — hantar hanya yang anda ingin gantikan.

  • 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 — keycap profil Cherry MX 1u standard. 3–5 saiz standard arus perdana tambahan dirancang; saiz tersuai tidak disokong.

  • Name
    head_size_mm
    Type
    number
    lalai 23
    Description

    Saiz sasaran bagi kepala terukir, dalam milimeter: dimensi terpanjangnya diskalakan kepada nilai ini. Julat: [10, 40]. Nilai melebihi kira-kira 32.9 mungkin dikurangkan supaya kepala masih sesuai dengan had jejak lindungan asas, sehingga dimensi terpanjang yang dihasilkan boleh lebih kecil daripada yang diminta. Nilai yang digunakan tidak digambarkan semula pada objek tugas pada masa ini — jika anda perlu mengesahkan saiz yang anda terima sebenarnya, ukur kotak pembatas jejaring keycap-head dalam model yang dimuat turun.

  • Name
    vertical_offset_mm
    Type
    number
    lalai 0
    Description

    Ofset menegak yang dikenakan pada kepala sebelum ia diletakkan pada asas, dalam milimeter. Julat: [-5, 5].

Pulangan

Sifat result bagi respons mengandungi id tugas bagi tugas pembinaan keycap yang baru dicipta. Poll endpoint Get a Task atau langgan stream sehingga tugas mencapai SUCCEEDED, kemudian muat turun artifak daripada model_urls.glb dan model_urls.obj_zip.

Mod Kegagalan

  • Name
    400 - Bad Request
    Description

    Permintaan tidak dapat diterima. Sebab-sebab biasa:

    • Parameter hilang: input_task_id dan candidate_id diperlukan.
    • UUID tidak sah: input_task_id bukan UUID yang sah.
    • Induk belum berjaya: Tugas prototaip yang dirujuk belum mencapai SUCCEEDED.
    • Tiada calon: Tugas prototaip berjaya tetapi tidak menghasilkan sebarang calon.
    • Calon tidak dikenali: candidate_id bukan salah satu calon bagi tugas input.
    • Options di luar julat: Salah satu medan options berada 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 mempunyai kredit yang tidak mencukupi.

  • Name
    404 - Not Found
    Description

    Tugas prototaip yang dirujuk tidak wujud, tergolong kepada pengguna lain, atau dicipta melalui webapp (hanya tugas prototaip mod API boleh berlanjut kepada pembinaan).

  • Name
    429 - Too Many Requests
    Description

    Anda telah melebihi had kadar anda.

  • Name
    500 - Internal Server Error
    Description

    Ralat tidak dijangka pada bahagian pelayan telah berlaku — contohnya perkhidmatan moderation kandungan tidak tersedia, penyediaan (staging) imej input gagal, atau tugas tidak dapat dicipta. Tiada tugas dicipta dalam kes ini, jadi mencuba semula adalah selamat.

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

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

Dapatkan Semula Tugas Keycap

Dapatkan semula tugas prototaip atau build dengan id tugas yang sah. Laluan URL mestilah sepadan dengan peringkat tugas — tugas build yang diambil melalui /prototype/:id akan mengembalikan 404, dan sebaliknya.

Rujuk The Keycap Prototype Task Object dan The Keycap Build Task Object untuk bentuk respons.

Parameter

  • Name
    id
    Type
    path
    Description

    Pengecam unik untuk tugas keycap yang hendak diambil.

Nilai Pulangan

Respons mengandungi objek tugas keycap. Bentuknya bergantung pada peringkat yang diminta.

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

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

Padam Tugas Keycap

Batalkan tugas keycap. Jika tugas masih PENDING, kredit yang digunakan pada masa penciptaan akan dikembalikan. Tugas yang sudah IN_PROGRESS akan dibatalkan tanpa bayaran balik (pekerja mungkin sudah menggunakan sumber). Tugas yang telah mencapai keadaan terminal (SUCCEEDED, FAILED, CANCELED) tidak boleh dibatalkan.

Laluan URL mesti sepadan dengan peringkat tugas — DELETE pada /prototype/:buildId mengembalikan 404.

Parameter Laluan

  • Name
    id
    Type
    path
    Description

    Pengenal unik untuk tugas keycap yang akan 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, dimiliki oleh pengguna lain, atau peringkatnya tidak sepadan dengan laluan URL.

  • Name
    500 - Internal Server Error
    Description

    Ralat pelayan yang tidak dijangka berlaku semasa pembatalan. Tugas mungkin telah atau belum dibatalkan — baca semula untuk mengesahkannya sebelum mencuba semula.

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).

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

Streaming Tugas Keycap

Streaming 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 menghasilkan satu payload event: error tunggal dengan status_code: 404 dan menutup strim tersebut.

Parameter

  • Name
    id
    Type
    path
    Description

    Pengenal unik untuk tugas keycap yang akan di-stream.

Pulangan

Mengembalikan strim objek tugas Keycap Prototype atau Keycap Build sebagai Server-Sent Events. Setiap bingkai membawa objek tugas penuh untuk peringkat tersebut — bentuk yang sama seperti yang dikembalikan oleh endpoint Get — jadi semasa tugas berstatus PENDING atau IN_PROGRESS, medan output hanya belum diisi lagi (null, [] atau {}) dan finished_at adalah null.

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 PENDING frame below is abbreviated 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=***"
  }
}

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

List Keycap Tasks

Dapatkan senarai bertoombor halaman bagi tugasan keycap anda untuk satu peringkat sahaja. Laluan URL

memilih peringkat tersebut — /prototype mengembalikan tugasan prototaip; /build mengembalikan tugasan pembinaan. Tugasan daripada peringkat lain tidak disertakan dalam mana-mana respons.

Parameter Laluan

  • Name
    stage
    Type
    path
    Diperlukan
    Description

    Sama ada prototype atau build. Koleksi ini hanya mengembalikan tugasan yang peringkatnya sepadan dengan URL — mengambil /prototype tidak akan pernah mengembalikan tugasan pembinaan 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 adalah 100 item.

  • Name
    sort_by
    Type
    string
    lalai -created_at
    Description

    Medan untuk isih mengikut. Nilai yang tersedia:

    • +created_at: Isih mengikut masa penciptaan secara menaik.
    • -created_at: Isih mengikut masa penciptaan secara menurun.

Pulangan

Mengembalikan senarai bertoombor halaman bagi objek tugasan setiap peringkat — sama ada objek tugasan prototaip keycap apabila menyenaraikan /prototype atau objek tugasan pembinaan keycap apabila menyenaraikan /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"
    ]
  }
]

The Keycap Prototype Task Object

Objek Keycap Prototype Task ialah unit kerja yang dijejaki oleh Meshy untuk menghasilkan satu imej reka bentuk keycap siap daripada foto sumber. Output peringkat ini dirantaikan ke peringkat pembinaan melalui input_task_id bersama candidate_id.

Ciri-ciri

  • Name
    id
    Type
    string
    Description

    Pengecam unik untuk tugas. Walaupun kami menggunakan UUID yang boleh disusun-k untuk id tugas sebagai butiran pelaksanaan, anda tidak sepatutnya membuat sebarang andaian tentang format id tersebut.

  • Name
    type
    Type
    string
    Description

    Jenis tugas. Nilainya ialah 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 ialah salah satu daripada PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Progress tugas. Jika tugas belum bermula lagi, ciri ini akan menjadi 0. Sebaik sahaja tugas berjaya, nilai ini akan menjadi 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Cap masa bila tugas dicipta, dalam milisaat.

  • Name
    started_at
    Type
    timestamp
    Description

    Cap masa bila tugas dimulakan, dalam milisaat. Jika tugas belum dimulakan lagi, ciri ini akan menjadi 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Cap masa bila tugas selesai, dalam milisaat. Jika tugas belum selesai lagi, ciri ini akan menjadi 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Cap masa bila hasil tugas tamat tempoh, dalam milisaat.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Bilangan tugas terdahulu.

  • 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 akan dikenakan caj penuh untuk peringkatnya. Tugas yang tidak pernah dicipta (4xx pada masa permintaan, termasuk penolakan moderation) tidak dikenakan sebarang caj. Tugas yang mencapai FAILED memulangkan 0 — caj tersebut dikembalikan, termasuk sekatan moderation secara tidak segerak. Membatalkan melalui DELETE hanya mengembalikan caj semasa tugas masih PENDING; tugas yang sudah IN_PROGRESS kekal dikenakan caj, kerana kerja tersebut telah dibelanjakan.

  • Name
    image_urls
    Type
    array of strings
    Description

    URL yang boleh dimuat turun bagi paparan reka bentuk keycap siap — rupa calon tersebut sebagai keycap yang sudah siap. Menyimpan satu entri sahaja; image_urls[i] sepadan dengan candidate_ids[i]. Kosong sehingga tugas mencapai SUCCEEDED. URL ini hanya untuk paparan sahaja; endpoint pembinaan menggunakan candidate_ids, bukan URL ini. Kitaran hayat URL yang sama seperti model_urls: ditandatangan, tiada header Authorization, sah sehingga expires_at, dan stabil apabila tugas dibaca semula.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Pengecam calon buram, selari dengan image_urls. Berikan entri yang sepadan dengan reka bentuk pilihan anda sebagai candidate_id bagi permintaan pembinaan. Jangan membuat sebarang andaian tentang format id ini.

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

Objek Tugas Binaan Keycap

Objek Tugas Binaan Keycap ialah unit kerja yang dijejaki oleh Meshy untuk menjana keycap 3D bertekstur akhir daripada tugas prototaip yang berjaya dan kandidat yang dipilih. Satu binaan menjalankan keseluruhan saluran paip — penjanaan model putih, pendudukan dan pemotongan automatik, pewarnaan, pemasangan, dan eksport.

Ciri-ciri

  • Name
    id
    Type
    string
    Description

    Pengecam unik untuk tugas.

  • Name
    type
    Type
    string
    Description

    Jenis tugas. Nilainya ialah 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 ialah salah satu daripada PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Progress tugas. Jika tugas belum bermula, ciri 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 luput, dalam milisaat.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Bilangan tugas terdahulu. Hanya bermakna apabila status ialah 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 akan dikenakan jumlah penuh bagi peringkatnya. Tugas yang tidak pernah dicipta (4xx pada masa permintaan, termasuk penolakan moderation) tidak dikenakan sebarang caj. Tugas yang mencapai FAILED mengembalikan 0 — caj tersebut dikembalikan (refund), termasuk sekatan moderation yang tak segerak. Membatalkan melalui DELETE hanya mengembalikan caj semasa tugas masih PENDING; tugas yang sudah IN_PROGRESS kekal dikenakan caj, kerana kerja tersebut telah dibelanjakan.

  • Name
    model_urls
    Type
    object
    Description

    URL yang boleh dimuat turun untuk artifak model yang dijana. Kedua-dua GLB dan bundel OBJ dieksport pada skala milimeter dunia sebenar, Y-up, dengan bahagian hadapan keycap menghadap +Z. Jejaring dinamakan keycap-head dan keycap-base; apabila dasar kembali kepada isian corak, jejaring ketiga keycap-base-interior turut hadir untuk rongga stem. Jangan andaikan tepat dua jejaring.

    Ini adalah URL bertandatangan (signed URLs): dapatkannya tanpa header Authorization. Ia kekal sah sehingga expires_at, iaitu 3 hari selepas finished_at, dan membaca semula tugas dalam tempoh tersebut akan mengembalikan URL yang sama, bukannya yang baru ditandatangan. Muat turun dan simpan fail tersebut sendiri sebelum itu — tiada cara untuk menyegarkan semula pautan yang telah luput.

    • 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 sebenarnya dirujuk oleh MTL-nya. Dasar warna solid hanya menghantar keycap-head.png; dasar berkorak juga menghantar keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    URL yang boleh dimuat turun untuk imej proses perantaraan, diindeks mengikut jenis. Kitaran hayat URL sama seperti model_urls: bertandatangan, tanpa header Authorization, sah sehingga expires_at, dan stabil apabila tugas dibaca semula. Jenis yang dihasilkan pada masa ini:

    • head_design — imej reka bentuk kandidat yang dipilih yang digunakan oleh binaan (sentiasa hadir).
    • composite — render paparan keycap siap bagi kandidat yang dipilih (hadir apabila tersedia).
    • base_canvas — kanvas dasar keycap yang telah dicat (hadir apabila tersedia).

    Anggap set kunci ini sebagai terbuka; jenis baharu mungkin ditambah tanpa menyebabkan perubahan yang memecahkan (breaking change).

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

Contoh Hujung-ke-Hujung

Aliran lengkap: cipta prototaip daripada foto, tinjau statusnya sehingga SUCCEEDED, pilih calon daripada candidate_ids, cipta bangunan dengan calon tersebut, tinjau bangunan itu sehingga SUCCEEDED, kemudian muat turun GLB dan kumpulan 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.

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"