Creative Lab Keycap API
เปลี่ยนภาพถ่ายให้เป็นปุ่มคีย์แคป (keycap) แบบกำหนดเองสีเต็มรูปแบบสำหรับคีย์บอร์ดแบบกลไกได้ในสองขั้นตอน งานสร้างต้นแบบจะสร้างภาพของคีย์แคปที่เสร็จสมบูรณ์จากภาพถ่าย จากนั้นงานสร้างโมเดลจะเปลี่ยนภาพนั้นให้เป็นโมเดลคีย์แคป 3 มิติที่มี texture โดยใช้ ID ของงานสร้างต้นแบบเป็น input_task_id และ ID ของตัวเลือกภาพ (candidate) เป็น candidate_id
POST /openapi/creative-lab/keycap/v1/prototypePOST /openapi/creative-lab/keycap/v1/build
endpoint แบบ POST ทั้งสองแบบต้องใช้แผนแบบชำระเงิน คำขอจากบัญชีแผนฟรีจะได้รับการตอบกลับเป็น 402
สร้างงาน Keycap prototype
สร้างภาพหนึ่งภาพของคีย์แคปที่เสร็จสมบูรณ์จากรูปถ่าย ฟิลด์ image_urls ของงานจะเก็บรูปภาพ และ candidate_ids จะเก็บ ID ของรูปนั้น โดยแต่ละฟิลด์มีหนึ่งรายการ หากคุณไม่ชอบดีไซน์ที่ได้ ให้สร้างงาน prototype ใหม่อีกครั้ง Meshy จะคิดค่าใช้จ่ายแยกต่างหากสำหรับแต่ละงาน prototype
หากต้องการสร้างคีย์แคป 3D ให้ส่ง ID ของงานนี้ไปยัง เอนด์พอยต์ build เป็น input_task_id พร้อมกับรายการ candidate_ids เป็น candidate_id สำหรับฟิลด์ต่าง ๆ ของงาน โปรดดู อ็อบเจ็กต์งาน Keycap prototype
Request
# 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"
}
พารามิเตอร์
- Name
- image_url
- Type
- string
- จำเป็น
- Description
รูปถ่ายที่จะแปลงเป็นดีไซน์คีย์แคป โดยเป็น URL สาธารณะหรือ data URI (
data:image/jpeg;base64,<ข้อมูลรูปภาพที่เข้ารหัส base64 ของคุณ>)รูปภาพต้องเป็นไฟล์ JPG, JPEG, PNG หรือ WebP ที่มีขนาดไม่เกิน 20 MB (20,000,000 ไบต์) แต่ละด้านต้องมีความยาวอย่างน้อย 32 พิกเซล และรูปภาพต้องมีจำนวนพิกเซลรวมไม่เกิน 178,956,970 พิกเซล รูปภาพที่เกินขีดจำกัดเหล่านี้จะคืนค่า
400Meshy ตรวจจับรูปแบบไฟล์จากข้อมูลของรูปภาพ ไม่ใช่จากนามสกุลไฟล์ใน URL ดังนั้น URL ที่ไม่มีนามสกุลก็ใช้งานได้ และ Meshy จะติดตาม HTTP redirects ด้วย Meshy จะใช้ค่าการหมุนภาพตามข้อมูล EXIF ดังนั้นรูปถ่ายจากโทรศัพท์ที่ถูกหมุนจะแสดงผลออกมาตามที่ควรจะเป็น
data URI ต้องเข้ารหัสแบบ base64 พร้อมระบุชนิดของรูปภาพ เช่น
data:image/png;base64,...และรูปภาพที่ถอดรหัสแล้วต้องเป็น JPEG, PNG หรือ WebP ขีดจำกัด 20 MB จะใช้กับรูปภาพที่ถอดรหัสแล้ว ดังนั้นข้อความ base64 อาจมีขนาดใหญ่กว่าประมาณหนึ่งในสาม
- Name
- name
- Type
- string
- Description
ชื่อสำหรับงาน ความยาวไม่เกิน 100 ตัวอักษร ชื่อนี้จะถูกส่งกลับมาในฟิลด์
nameของงาน หากชื่อยาวเกินไปจะคืนค่า400
- Name
- remove_background
- Type
- boolean
- ค่าเริ่มต้น false
- Description
กำหนดว่าจะลบพื้นหลังออกจากรูปภาพ prototype หรือไม่ หากตั้งเป็น
trueจะได้ PNG แบบ RGBA ที่มีพื้นหลังโปร่งใส ทำให้คุณสามารถวางคีย์แคปบนพื้นหลังใดก็ได้ หาก Meshy ไม่สามารถลบพื้นหลังได้ ก็จะคืนค่ารูปภาพพร้อมพื้นหลังเดิม และงานยังคงสำเร็จดีไซน์หัวคีย์แคปที่ขั้นตอน build จะแปลงเป็น 3D จะยังคงพื้นหลังไว้ไม่ว่าจะเลือกตัวเลือกใดก็ตาม ขั้นตอน build จะวาดฐานคีย์แคปจากรูปภาพใน
image_urlsโดยไม่มีพื้นหลังหากคุณส่งค่าtrueขั้นตอน build จะคืนค่ารูปภาพนั้นเป็นprocess_image_urls.composite
ค่าที่ส่งกลับ
ฟิลด์ result จะเก็บ ID ของงาน prototype ใหม่ ดึงข้อมูลงาน หรือ สตรีมงานนั้น จนกว่า status จะเป็น SUCCEEDED จากนั้นส่ง ID ไปยัง เอนด์พอยต์ build เป็น input_task_id พร้อมกับรายการจาก candidate_ids เป็น candidate_id
รูปแบบความล้มเหลว
- Name
400 - Bad Request- Description
คำขอนี้ไม่สามารถดำเนินการได้ ตัวอย่างเช่น:
image_urlขาดหายไป- รูปภาพไม่ใช่ไฟล์ JPG, JPEG, PNG หรือ WebP
- รูปภาพมีขนาดเล็กเกินไป ใหญ่เกิน 20 MB หรือเกินจำนวนพิกเซลสูงสุด
- Meshy ไม่สามารถดาวน์โหลดรูปภาพได้ เช่น เพราะ URL คืนค่า
404หรือหมดเวลา - data URI ไม่ใช่ base64 ที่ถูกต้อง
- รูปภาพถูกตั้งค่าสถานะว่าเป็น NSFW
ข้อความแสดงข้อผิดพลาดจะระบุปัญหาที่พบ แก้ไขคำขอแล้วส่งอีกครั้ง
- Name
401 - Unauthorized- Description
API คีย์ขาดหายไปหรือไม่ถูกต้อง ตรวจสอบเฮดเดอร์
Authorization
- Name
402 - Payment Required- Description
เงื่อนไขข้อใดข้อหนึ่งต่อไปนี้เป็นจริง:
- บัญชีมีเครดิตไม่เพียงพอ
- API คีย์ พื้นที่ทำงาน หรือสมาชิกถึงขีดจำกัดเครดิตแล้ว
- บัญชีอยู่ในแพ็กเกจฟรี
ตรวจสอบเครดิตและแพ็กเกจของคุณ แล้วลองใหม่อีกครั้ง
- Name
403 - Forbidden- Description
ทีมของคุณเปิดใช้งาน IP Filtering และ Meshy ตั้งค่าสถานะรูปภาพนี้ว่าเกี่ยวข้องกับทรัพย์สินทางปัญญาของบุคคลที่สาม โปรดส่งรูปภาพที่คุณมีสิทธิ์ใช้งาน
- Name
429 - Too Many Requests- Description
ถึงขีดจำกัดข้อใดข้อหนึ่งต่อไปนี้:
- คุณส่งคำขอมากกว่าที่การจำกัดอัตราของคุณอนุญาต รอสักสองสามวินาทีแล้วลองใหม่ ดู การจำกัดอัตรา
- มีงานของคุณที่อยู่ในคิวหรือกำลังทำงานมากเกินไป รอจนกว่าบางงานจะเสร็จสิ้น แล้วลองใหม่
- หากอยู่ในแพ็กเกจไม่จำกัดแต่ไม่มีเครดิตเหลือ คุณถึงจำนวนงานสูงสุดที่สามารถรันได้โดยไม่ใช้เครดิตแล้ว รอให้งานเสร็จสิ้น หรือเพิ่มเครดิต
- Name
500 - Internal Server Error- Description
Meshy พบข้อผิดพลาดของเซิร์ฟเวอร์ เช่น เนื่องจากการตรวจสอบเนื้อหา (moderation) หรือการตรวจสอบทรัพย์สินทางปัญญาไม่สามารถทำงานได้ หรือ Meshy ไม่สามารถจัดเก็บรูปภาพได้ Meshy จะไม่สร้างงาน และคืนเครดิตที่เรียกเก็บไปแล้ว ลองส่งคำขออีกครั้ง
สร้างงาน Keycap build
สร้างคีย์แคป 3D ที่มีพื้นผิวแล้วจากงาน prototype ที่สำเร็จ และหนึ่งในตัวเลือก (candidate) ของมัน สำหรับฟิลด์ต่าง ๆ ดูที่ The Keycap build task object
งาน build หนึ่งงานจะรันทุกขั้นตอน โดยจะสร้างโมเดล 3D จากดีไซน์และใส่สีให้ จากนั้นจะวางและตัดโมเดลลงบนฐานคีย์แคปในท่าตั้งค่าเริ่มต้นที่ผ่านการปรับเทียบแล้ว ดังนั้นคุณจึงไม่จำเป็นต้องปรับเองด้วยมือ สุดท้ายจะประกอบคีย์แคปและส่งออกไฟล์ โดยทั่วไปการ build จะใช้เวลา 3 ถึง 7 นาที
Request
# 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"
}
พารามิเตอร์
- Name
- input_task_id
- Type
- string
- จำเป็น
- Description
ID ของงาน prototype ที่จะ build ต้องเป็นงานที่บัญชีของคุณสร้างด้วย
POST /openapi/creative-lab/keycap/v1/prototypeและมีสถานะSUCCEEDEDID ที่ไม่ใช่งาน Keycap prototype ของคุณจาก API จะคืนค่า
404รวมถึง prototype ที่สร้างในเว็บแอปด้วย
- Name
- candidate_id
- Type
- string
- จำเป็น
- Description
ตัวเลือก (candidate) ที่จะ build จากอาร์เรย์
candidate_idsของงาน prototype หากส่งค่าที่ไม่อยู่ในอาร์เรย์นั้นจะคืนค่า400
- Name
- name
- Type
- string
- Description
ชื่อสำหรับงาน ความยาวไม่เกิน 100 ตัวอักษร ชื่อนี้จะกลับมาในฟิลด์
nameของงาน หากชื่อยาวเกินไปจะคืนค่า400
options
การตั้งค่าจีออเมทรีที่เป็นทางเลือก แต่ละฟิลด์มีค่าเริ่มต้นที่ผ่านการปรับเทียบแล้ว ดังนั้นให้ส่งเฉพาะฟิลด์ที่คุณต้องการเปลี่ยนแปลง
- Name
- base_model
- Type
- string
- ค่าเริ่มต้น cherry-mx-1x1-r1
- Description
ฐานคีย์แคปที่จะใช้ build ค่าเดียวที่ใช้ได้คือ
cherry-mx-1x1-r1ซึ่งเป็นคีย์แคปโปรไฟล์ Cherry MX มาตรฐานขนาด 1u ไม่รองรับขนาดที่กำหนดเอง และค่าอื่นใดจะคืนค่า400
- Name
- head_size_mm
- Type
- number
- ค่าเริ่มต้น 23
- Description
ขนาดของส่วนหัวตามมิติที่ยาวที่สุด หน่วยเป็นมิลลิเมตร ตั้งแต่
10ถึง40Meshy จะปรับขนาดส่วนหัวให้มิติที่ยาวที่สุดตรงกับค่านี้ หากค่าอยู่นอกช่วงจะคืนค่า400สำหรับค่าที่สูงกว่าประมาณ
32.9Meshy อาจลดขนาดลงเพื่อให้ส่วนหัวพอดีกับขีดจำกัดพื้นที่ป้องกันของฐาน ส่วนหัวจึงอาจออกมาเล็กกว่าที่คุณขอ ออบเจ็กต์งานไม่ได้คืนค่าขนาดที่ Meshy ใช้จริง หากต้องการตรวจสอบ ให้วัดกล่องขอบเขตของเมชkeycap-headในโมเดล
- Name
- vertical_offset_mm
- Type
- number
- ค่าเริ่มต้น 0
- Description
ค่าชดเชยแนวตั้งที่จะใช้กับส่วนหัวก่อนที่ Meshy จะวางลงบนฐาน หน่วยเป็นมิลลิเมตร ตั้งแต่
-5ถึง5หากค่าอยู่นอกช่วงจะคืนค่า400
ค่าที่ส่งกลับ
ฟิลด์ result เก็บ ID ของงาน build ใหม่ ดึงข้อมูลงาน หรือ สตรีมข้อมูลงาน จนกว่า status จะเป็น SUCCEEDED จากนั้นดาวน์โหลดไฟล์ GLB จาก model_urls.glb และชุดไฟล์ OBJ จาก model_urls.obj_zip
Meshy ส่งออกไฟล์ GLB และชุดไฟล์ OBJ ในขนาดจริงเป็นมิลลิเมตร ทั้งสองใช้ระบบพิกัดแบบ Y-up โดยด้านหน้าของคีย์แคปหันไปทาง +Z
รูปแบบความล้มเหลว
- Name
400 - Bad Request- Description
คำขอนี้ไม่สามารถรันได้ ตัวอย่างเช่น:
input_task_idขาดหายไป หรือไม่ใช่ ID งานที่ถูกต้อง- สถานะของงาน prototype ไม่ใช่
SUCCEEDEDหากยังทำงานอยู่ ให้รอแล้วลองใหม่ หากล้มเหลวหรือถูกยกเลิก ให้สร้างงาน prototype ใหม่ - งาน prototype สำเร็จแล้วแต่ไม่มีตัวเลือก (candidate) ให้สร้างงาน prototype ใหม่
candidate_idขาดหายไป หรือไม่อยู่ในcandidate_idsของงาน prototype ให้ส่งค่าจากอาร์เรย์นั้น- ฟิลด์ใน
optionsอยู่นอกช่วงที่กำหนด หรือbase_modelไม่ใช่ค่าที่ใช้ได้
ข้อความแสดงข้อผิดพลาดจะระบุว่าพบปัญหาใด
- Name
401 - Unauthorized- Description
API คีย์ขาดหายไปหรือไม่ถูกต้อง ตรวจสอบเฮดเดอร์
Authorization
- Name
402 - Payment Required- Description
เกิดกรณีใดกรณีหนึ่งต่อไปนี้:
- บัญชีมีเครดิตไม่เพียงพอ
- API คีย์ พื้นที่ทำงาน หรือสมาชิกถึงขีดจำกัดเครดิตแล้ว
- บัญชีอยู่ในแผนฟรี
ตรวจสอบเครดิตและแผนของคุณ แล้วลองใหม่
- Name
404 - Not Found- Description
input_task_idไม่ตรงกับงาน Keycap prototype ใด ๆ ที่บัญชีของคุณสร้างด้วย API prototype ที่สร้างในเว็บแอปก็จะคืนค่า404เช่นกัน ให้ส่ง ID จากฟิลด์resultของการตอบกลับตอนสร้าง prototype
- Name
429 - Too Many Requests- Description
มีการถึงขีดจำกัดข้อใดข้อหนึ่งต่อไปนี้:
- คุณส่งคำขอมากกว่าที่การจำกัดอัตราของคุณอนุญาต ให้รอสักสองสามวินาทีแล้วลองใหม่ ดู Rate limits
- มีงานของคุณที่อยู่ในคิวหรือกำลังทำงานมากเกินไป ให้รอให้บางงานเสร็จก่อน แล้วลองใหม่
- หากอยู่ในแผนไม่จำกัดและไม่มีเครดิตเหลือ คุณถึงจำนวนงานสูงสุดที่รันได้โดยไม่ใช้เครดิตแล้ว ให้รอให้งานหนึ่งเสร็จ หรือเติมเครดิต
- Name
500 - Internal Server Error- Description
Meshy ไม่สามารถสร้างงานได้เนื่องจากข้อผิดพลาดของเซิร์ฟเวอร์ Meshy จะคืนเครดิตที่เรียกเก็บไปแล้ว ให้ลองส่งคำขอใหม่
ดึงข้อมูลงาน Keycap
คืนค่างาน prototype หรือ build พาธที่ใช้ต้องตรงกับขั้นตอนของงานนั้น งาน build ที่ถูกเรียกผ่าน /prototype/:id จะคืนค่า 404 และงาน prototype ที่ถูกเรียกผ่าน /build/:id ก็เช่นกัน
สำหรับฟิลด์ต่าง ๆ ดูที่ The Keycap prototype task object และ The Keycap build task object
Request
# 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=***"
}
}
พารามิเตอร์
- Name
- id
- Type
- path
- Description
รหัสงานจากการตอบกลับตอนสร้าง
ค่าที่ส่งกลับ
prototype task object หรือ build task object ขึ้นอยู่กับขั้นตอนที่ตรงกับพาธ
รูปแบบความล้มเหลว
- Name
400 - Bad Request- Description
idไม่ใช่รหัสงานที่ถูกต้อง ให้ส่งรหัสresultจากการตอบกลับตอนสร้าง
- Name
403 - Forbidden- Description
ทีมของคุณเปิดใช้งาน IP Filtering และ Meshy ตรวจพบว่ารูปภาพของงาน prototype มีทรัพย์สินทางปัญญาของบุคคลภายนอก งาน build และทีมในแพ็กเกจ Enterprise จะไม่พบข้อผิดพลาดนี้ ให้สร้างงาน prototype จากรูปภาพที่คุณมีสิทธิ์ใช้งาน
- Name
404 - Not Found- Description
ไม่มีงาน Keycap ที่มีรหัสนี้อยู่ในบัญชีของคุณ หรือขั้นตอนของงานไม่ตรงกับพาธ ตรวจสอบรหัส และใช้
/prototypeหรือ/buildให้ตรงกับงาน
- Name
500 - Internal Server Error- Description
Meshy ไม่สามารถตรวจสอบทรัพย์สินทางปัญญาได้ ให้ลองส่งคำขออีกครั้ง
ลบงาน Keycap
ยกเลิกงาน Keycap การยกเลิกงานที่มีสถานะ PENDING จะคืนเครดิตให้ ส่วนงานที่มีสถานะ IN_PROGRESS จะถูกยกเลิกโดยไม่มีการคืนเครดิต เนื่องจาก worker ได้เริ่มดำเนินการไปแล้ว งานที่มีสถานะสุดท้าย (SUCCEEDED, FAILED หรือ CANCELED) ไม่สามารถยกเลิกได้
พาธต้องตรงกับขั้นตอนของงาน ตัวอย่างเช่น การใช้ DELETE บน /prototype/:id ด้วยรหัสของ build task จะส่งคืน 404
Request
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).
พารามิเตอร์พาธ
- Name
- id
- Type
- path
- Description
รหัสของงานที่จะยกเลิก
สิ่งที่ส่งคืน
204 No Content พร้อมเนื้อหาว่างเปล่า
รูปแบบความล้มเหลว
- Name
400 - Bad Request- Description
หนึ่งในกรณีต่อไปนี้ใช้ได้:
idไม่ใช่รหัสงานที่ถูกต้อง ให้ส่งรหัสresultจากการตอบกลับการสร้าง- งานมีสถานะสุดท้ายอยู่แล้ว (
SUCCEEDED,FAILEDหรือCANCELED) จึงไม่สามารถยกเลิกได้
- Name
404 - Not Found- Description
ไม่มีงาน Keycap ที่มีรหัสนี้อยู่ในบัญชีของคุณ หรือขั้นตอนของงานไม่ตรงกับพาธ ตรวจสอบรหัส และใช้
/prototypeหรือ/buildให้ตรงกับงาน
- Name
500 - Internal Server Error- Description
Meshy พบข้อผิดพลาดของเซิร์ฟเวอร์ขณะยกเลิกงาน ดังนั้นงานอาจถูกยกเลิกหรือไม่ก็ได้ ให้ดึงข้อมูลงานเพื่อตรวจสอบ
statusก่อนลองใหม่อีกครั้ง
Stream a Keycap task
สตรีมการอัปเดตของ Keycap task ในรูปแบบ Server-Sent Events (SSE) พาธที่ใช้ต้องตรงกับขั้นตอนของ task นั้น หากไม่ตรงกัน เช่น ใช้ ID ของ build task ที่ /prototype/:id/stream สตรีมจะส่ง error event หนึ่งรายการที่มี status_code: 404 แล้วปิดการเชื่อมต่อ
Request
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=***"
}
}
พารามิเตอร์
- Name
- id
- Type
- path
- Description
ID ของ task จากการตอบกลับตอนสร้าง
ค่าที่ส่งกลับ
สตรีมของอ็อบเจ็กต์ task ประเภท prototype หรือ build แต่ละ event จะมีอ็อบเจ็กต์ task ฉบับเต็ม เช่นเดียวกับที่ Get a Keycap task ส่งกลับ ในขณะที่ task ยังอยู่ในสถานะ PENDING หรือ IN_PROGRESS ฟิลด์ผลลัพธ์ของมันจะยังว่างอยู่ (null, [], หรือ {}) และ finished_at จะเป็น null
หาก IP Filtering บล็อกผลลัพธ์ของ task สตรีมจะส่ง error event หนึ่งรายการแทน โดยมี status_code เดียวกับที่ get request จะส่งกลับ
List Keycap tasks
คืนค่างาน Keycap ของคุณในขั้นตอนเดียว ครั้งละหนึ่งหน้า พาธจะเป็นตัวเลือกขั้นตอน /prototype จะคืนค่าเฉพาะงาน prototype และ /build จะคืนค่าเฉพาะงาน build
Request
# 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"
]
}
]
พารามิเตอร์พาธ (Path parameters)
- Name
- stage
- Type
- path
- จำเป็น
- Description
ขั้นตอนที่จะแสดงรายการ
prototypeหรือbuild
พารามิเตอร์คิวรี (Query parameters)
- Name
- page_num
- Type
- integer
- ค่าเริ่มต้น 1
- Description
หน้าที่จะคืนค่า ตั้งแต่
1ถึง255ค่า0จะคืนค่าหน้าแรก ค่าที่อยู่นอกช่วง0ถึง255จะคืนค่า400
- Name
- page_size
- Type
- integer
- ค่าเริ่มต้น 10
- Description
จำนวนงานต่อหน้า สูงสุด
100ค่าตั้งแต่101ถึง255จะคืนค่า 100 งาน และ0จะใช้ค่าเริ่มต้น ค่าที่อยู่นอกช่วง0ถึง255จะคืนค่า400
- Name
- sort_by
- Type
- string
- ค่าเริ่มต้น -created_at
- Description
ลำดับการเรียง
ค่าที่ใช้ได้:
-created_at: ใหม่ที่สุดก่อน+created_at: เก่าที่สุดก่อน
ค่าที่คืนกลับ
อาร์เรย์ของ ออบเจ็กต์งาน prototype หรือ ออบเจ็กต์งาน build ตามขั้นตอนที่ระบุในพาธ
อ็อบเจ็กต์งาน Keycap Prototype
งาน prototype จะสร้างภาพของคีย์แคปที่เสร็จสมบูรณ์หนึ่งภาพจากรูปถ่าย หากต้องการเปลี่ยนดีไซน์ให้เป็นคีย์แคป 3 มิติ ให้ส่ง ID ของงานไปยัง build endpoint ในฐานะ input_task_id พร้อมกับรายการ candidate_ids ในฐานะ candidate_id
Properties
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 ของงาน อย่าอ้างอิงรูปแบบของ ID นี้
- Name
- type
- Type
- string
- Description
ประเภทของงาน ซึ่งจะเป็น
creative-lab-keycap-prototypeเสมอ
- Name
- name
- Type
- string
- Description
nameที่คุณส่งไปตอนสร้างงาน หรือ""หากคุณไม่ได้ส่งค่านี้ไป
- Name
- status
- Type
- string
- Description
สถานะของงาน
ค่าที่เป็นไปได้:
PENDING: กำลังรอในคิวIN_PROGRESS: กำลังสร้างผลลัพธ์SUCCEEDED: เสร็จสิ้นแล้ว พร้อมผลลัพธ์FAILED: เสร็จสิ้นแล้ว พร้อมเหตุผลในtask_errorCANCELED: เสร็จสิ้นแล้ว โดยไม่มีผลลัพธ์
- Name
- progress
- Type
- integer
- Description
เปอร์เซ็นต์ของงานที่เสร็จแล้ว ตั้งแต่
0ถึง100ค่าจะเป็น0จนกว่างานจะเริ่มต้น และเป็น100เมื่อสำเร็จ
- Name
- created_at
- Type
- timestamp
- Description
เวลาที่สร้างงาน ในหน่วยมิลลิวินาทีแบบ Unix
- Name
- started_at
- Type
- timestamp
- Description
เวลาที่ worker เริ่มดำเนินงาน ในหน่วยมิลลิวินาทีแบบ Unix เป็น
nullจนกว่าจะถึงเวลานั้น
- Name
- finished_at
- Type
- timestamp
- Description
เวลาที่งานถึงสถานะสุดท้าย ในหน่วยมิลลิวินาทีแบบ Unix เป็น
nullจนกว่าจะถึงเวลานั้น
- Name
- expires_at
- Type
- timestamp
- Description
เวลาที่ผลลัพธ์ของงานจะหมดอายุ ในหน่วยมิลลิวินาทีแบบ Unix คือ 3 วันหลังจาก
finished_atหรือ 3 วันหลังจากcreated_atจนกว่างานจะเสร็จสิ้น สำหรับบัญชี Enterprise ซึ่งเก็บผลลัพธ์ API ไว้อย่างไม่มีกำหนด ค่านี้จะอยู่ที่ประมาณ 100 ปีถัดไป ดู Asset retention
- Name
- preceding_tasks
- Type
- integer
- Description
ตำแหน่งของงานในคิวขณะที่ยังเป็น
PENDINGค่า1หมายความว่างานนี้จะเริ่มเป็นลำดับถัดไป และเป็น0หลังจากงานออกจากคิวแล้ว และจะเป็น0เสมอในผลลัพธ์แบบรายการ
- Name
- task_error
- Type
- object
- Description
เหตุผลที่งานล้มเหลว เป็น
nullยกเว้นเมื่อstatusเป็นFAILEDดู ข้อผิดพลาด
- Name
- consumed_credits
- Type
- integer
- Description
จำนวนเครดิตที่ถูกเรียกเก็บสำหรับงานนี้ หลังหักการคืนเงินใด ๆ คำขอที่ส่งคืนข้อผิดพลาดจะไม่ถูกเรียกเก็บเครดิต งานที่ล้มเหลวจะเป็น
0เนื่องจาก Meshy จะคืนเครดิตให้ การยกเลิกจะคืนเครดิตของงานก็ต่อเมื่องานยังอยู่ในสถานะPENDINGหาก Meshy ไม่สามารถอ่านค่าธรรมเนียมได้ การตอบกลับแบบ get หรือ stream จะไม่มีฟิลด์นี้ปรากฏ และคำขอแบบ list จะส่งคืน500ในกรณีนั้น ให้ลองส่งคำขอใหม่อีกครั้ง
- Name
- image_urls
- Type
- array of strings
- Description
URL สำหรับดาวน์โหลดภาพของคีย์แคปที่เสร็จสมบูรณ์ อาร์เรย์นี้จะมี URL หนึ่งรายการหลังจากงานสำเร็จ และจะว่างเปล่าจนกว่าจะถึงเวลานั้น
image_urls[i]แสดงตัวเลือกที่สอดคล้องกับcandidate_ids[i]URL เหล่านี้มีไว้สำหรับการแสดงผล ส่วน build endpoint จะรับรายการจาก
candidate_idsไม่ใช่ URL URL เหล่านี้เป็น signed URL ดังนั้นให้ดึงข้อมูลโดยไม่ต้องใส่ส่วนหัวAuthorizationURL จะใช้งานได้จนถึงexpires_atและการเรียกดูงานอีกครั้งจะส่งคืน URL เดิม
- Name
- candidate_ids
- Type
- array of strings
- Description
ID ของตัวเลือกต่าง ๆ โดยเรียงลำดับเดียวกับ
image_urlsหากต้องการสร้างตัวเลือกใดตัวเลือกหนึ่ง ให้ส่ง ID ของตัวเลือกนั้นเป็นcandidate_idในคำขอ build อย่าอ้างอิงรูปแบบของ ID เหล่านี้
The Keycap build task object
งาน build จะสร้างคีย์แคป 3D ที่มีเท็กซ์เจอร์จากงาน prototype ที่สำเร็จและหนึ่งในตัวเลือกของมัน โดยจะสร้างโมเดล 3D ลงสี วางและตัดลงบนฐานคีย์แคป แล้วจึงประกอบและส่งออกคีย์แคป
คุณสมบัติ
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 ของงาน อย่าอ้างอิงตามรูปแบบของมัน
- Name
- type
- Type
- string
- Description
ประเภทของงาน ซึ่งเป็น
creative-lab-keycap-buildเสมอ
- Name
- name
- Type
- string
- Description
nameที่คุณส่งมาตอนสร้างงาน หรือ""ถ้าคุณไม่ได้ส่งมา
- Name
- status
- Type
- string
- Description
สถานะของงาน
ค่าที่เป็นไปได้:
PENDING: กำลังรอในคิวIN_PROGRESS: กำลังสร้างผลลัพธ์SUCCEEDED: สถานะสุดท้าย พร้อมผลลัพธ์FAILED: สถานะสุดท้าย พร้อมเหตุผลในtask_errorCANCELED: สถานะสุดท้าย โดยไม่มีผลลัพธ์
- Name
- progress
- Type
- integer
- Description
เปอร์เซ็นต์ของงานที่ทำเสร็จแล้ว ตั้งแต่
0ถึง100ค่าเป็น0จนกว่างานจะเริ่ม และเป็น100เมื่องานสำเร็จ
- Name
- created_at
- Type
- timestamp
- Description
เวลาที่สร้างงาน หน่วยเป็นมิลลิวินาทีแบบ Unix
- Name
- started_at
- Type
- timestamp
- Description
เวลาที่ worker เริ่มงาน หน่วยเป็นมิลลิวินาทีแบบ Unix เป็น
nullจนกว่าจะถึงเวลานั้น
- Name
- finished_at
- Type
- timestamp
- Description
เวลาที่งานถึงสถานะสุดท้าย หน่วยเป็นมิลลิวินาทีแบบ Unix เป็น
nullจนกว่าจะถึงเวลานั้น
- Name
- expires_at
- Type
- timestamp
- Description
เวลาที่ผลลัพธ์ของงานจะหมดอายุ หน่วยเป็นมิลลิวินาทีแบบ Unix คือ 3 วันหลังจาก
finished_atหรือ 3 วันหลังจากcreated_atจนกว่างานจะเสร็จสิ้น สำหรับบัญชี Enterprise ซึ่งเก็บผลลัพธ์ของ API ไว้ไม่มีกำหนด ค่านี้จะเป็นประมาณ 100 ปีถัดไป ดู การเก็บรักษาแอสเซ็ต
- Name
- preceding_tasks
- Type
- integer
- Description
ตำแหน่งของงานในคิวขณะที่สถานะเป็น
PENDINGค่า1หมายความว่างานนี้จะเริ่มถัดไป ค่าเป็น0หลังจากงานออกจากคิว และเป็น0เสมอในผลลัพธ์แบบรายการ
- Name
- task_error
- Type
- object
- Description
เหตุผลที่งานล้มเหลว เป็น
nullเว้นแต่statusจะเป็นFAILEDดู ข้อผิดพลาด
- Name
- consumed_credits
- Type
- integer
- Description
จำนวนเครดิตที่เรียกเก็บสำหรับงาน หลังจากการคืนเงินใดๆ คำขอที่ส่งคืนข้อผิดพลาดจะไม่ถูกเรียกเก็บเครดิต งานที่ล้มเหลวจะมีค่าเป็น
0เพราะ Meshy จะคืนเครดิตให้ การยกเลิกจะคืนเครดิตให้เฉพาะเมื่องานยังอยู่ในสถานะPENDINGเท่านั้น ถ้า Meshy ไม่สามารถอ่านค่าการเรียกเก็บเงินได้ การตอบกลับแบบ get หรือ stream จะไม่มีฟิลด์นี้ และคำขอแบบ list จะส่งคืน500ในกรณีนั้น ให้ลองคำขอใหม่อีกครั้ง
- Name
- model_urls
- Type
- object
- Description
URL สำหรับดาวน์โหลดโมเดล 3D Meshy จะส่งออกไฟล์ GLB และชุด OBJ ตามสเกลจริงเป็นมิลลิเมตร แกน Y ชี้ขึ้น โดยด้านหน้าของคีย์แคปหันไปทาง +Z
โมเดลมีเมชชื่อ
keycap-headและkeycap-baseเมื่อ Meshy ใช้การเติมลวดลายสำรองสำหรับฐาน โมเดลจะมีเมชkeycap-base-interiorสำหรับโพรงก้าน(stem cavity) เพิ่มเติมด้วย อย่าสันนิษฐานว่าโมเดลมีเมชเพียงสองชิ้นเสมอไปURL เหล่านี้เป็น URL ที่มีการเซ็นชื่อ ดังนั้นให้เรียกใช้โดยไม่ต้องใส่ header
AuthorizationURL เหล่านี้จะใช้งานได้จนถึงexpires_atและการเรียกดูงานอีกครั้งก่อนถึงเวลานั้นจะส่งคืน URL เดิม URL ที่หมดอายุแล้วไม่สามารถต่ออายุได้ ดังนั้นควรดาวน์โหลดและจัดเก็บไฟล์ไว้ก่อนที่จะหมดอายุ- Name
glb- Type
- string
- Description
URL สำหรับดาวน์โหลดไฟล์ GLB ที่มีเท็กซ์เจอร์
model.glb
- Name
obj_zip- Type
- string
- Description
URL สำหรับดาวน์โหลดชุด OBJ ซึ่งเป็นไฟล์ ZIP ที่มี
model.obj,model.mtlและเท็กซ์เจอร์ PNG ที่model.mtlใช้งาน เมื่อฐานเป็นสีพื้นเดียว เท็กซ์เจอร์เดียวที่มีคือkeycap-head.pngเมื่อฐานมีลวดลาย ไฟล์ ZIP จะมีkeycap-base.pngด้วย
- Name
- process_image_urls
- Type
- object
- Description
URL สำหรับดาวน์โหลดภาพจากขั้นตอนต่างๆ ของการ build โดยจัดเรียงตามประเภท เช่นเดียวกับ
model_urlsภาพเหล่านี้เป็น URL ที่มีการเซ็นชื่อ ดังนั้นให้เรียกใช้โดยไม่ต้องใส่ headerAuthorizationURL เหล่านี้จะใช้งานได้จนถึงexpires_atและการเรียกดูงานอีกครั้งจะส่งคืน URL เดิมอาจมีคีย์เหล่านี้:
head_design: ภาพออกแบบของตัวเลือกที่เลือก ซึ่งการ build นำไปแปลงเป็น 3D มีอยู่เสมอcomposite: ภาพของคีย์แคปที่เสร็จสมบูรณ์สำหรับตัวเลือกที่เลือก ซึ่งใช้ในการวาดฐาน อาจไม่มีอยู่ก็ได้base_canvas: ฐานคีย์แคปที่ถูกวาดแล้ว อาจไม่มีอยู่ก็ได้
Meshy อาจเพิ่มคีย์ใหม่ขึ้นมาได้ ดังนั้นให้ข้ามคีย์ที่คุณไม่รู้จักไป
End-to-end example
ตัวอย่างนี้รันกระบวนการทั้งหมด:
- สร้างงาน prototype จากรูปภาพ
- ดึงข้อมูลงานจนกว่า
statusจะเป็นSUCCEEDED - เลือกตัวเลือกจาก
candidate_ids - สร้างงาน build ด้วยตัวเลือกนั้น
- ดึงข้อมูลงาน build จนกว่า
statusจะเป็นSUCCEEDED - ดาวน์โหลดไฟล์ GLB และชุดไฟล์ OBJ จาก
model_urls
ตัวอย่างนี้เลือกตัวเลือกแรก ในแอปของคุณ ควรแสดงรายการ image_urls ให้ผู้ใช้เห็นและให้เลือกเอง ดัชนีของรูปภาพที่เลือกใน image_urls คือดัชนีของ ID ของรูปภาพนั้นใน candidate_ids
Complete flow
#!/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"