Biến một bức ảnh nguồn thành một keycap bàn phím cơ tùy chỉnh đầy đủ màu sắc
qua hai giai đoạn: prototype tạo ra bản render thiết kế "keycap hoàn
thiện" từ ảnh đầu vào của bạn. Sau khi đã xác nhận bản render đó, build sẽ
biến nó thành mô hình keycap 3D có texture chỉ trong một lần chạy — tạo mô
hình trắng, tự động căn chỉnh vị trí và cắt gọt theo tư thế mặc định đã hiệu
chuẩn, tô màu toàn bộ mô hình, và lắp ráp cuối cùng đều diễn ra trong một tác
vụ build duy nhất. Hai giai đoạn được liên kết với nhau thông qua
input_task_id cùng với candidate_id.
POST /openapi/creative-lab/keycap/v1/prototype
POST /openapi/creative-lab/keycap/v1/build
Cả hai endpoint POST đều yêu cầu gói đăng ký trả phí. Các yêu cầu từ tài
khoản gói miễn phí sẽ bị từ chối với lỗi 402 Payment Required.
Tạo một bản render thiết kế keycap hoàn chỉnh từ ảnh nguồn. Kết quả của tác vụ mang theo một mảng image_urls (bản render hiển thị của keycap hoàn chỉnh) và một mảng candidate_ids song song; cả hai đều chỉ chứa một mục duy nhất.
Gọi lại endpoint này để tạo một bản render khác nếu kết quả không như mong muốn — mỗi lần gọi được tính phí riêng. Truyền candidate_id cùng với ID của tác vụ prototype tới endpoint build.
Tham khảo
The Keycap Prototype Task Object
để biết cấu trúc phản hồi.
Tham số
Name
image_url
Type
string
Bắt buộc
Description
Ảnh nguồn để Meshy chuyển đổi thành các ảnh thiết kế keycap. Hiện chúng tôi hỗ trợ các định dạng .jpg, .jpeg, .png, và .webp.
Định dạng được phát hiện bằng cách giải mã dữ liệu ảnh, không dựa vào phần mở rộng tệp trong URL — một URL không có phần mở rộng, hoặc một URL chuyển hướng, vẫn hoạt động miễn là các byte giải mã được thành một định dạng được hỗ trợ. Các chuyển hướng HTTP sẽ được theo dõi. Hướng EXIF được chuẩn hóa, vì vậy một ảnh chụp từ điện thoại bị xoay sẽ được sử dụng đúng theo hướng hiển thị của nó.
Giới hạn: ít nhất 32 pixel mỗi cạnh, tối đa 178,956,970 pixel tổng cộng, và tối đa 20,000,000 byte sau khi tải xuống. Đối với Data URI, giới hạn áp dụng cho các byte đã giải mã, vì vậy bản thân tệp nguồn có thể lên tới kích thước đó — chính văn bản base64 mới lớn hơn khoảng một phần ba, điều này ảnh hưởng đến nội dung yêu cầu (request body) của bạn, chứ không ảnh hưởng đến giới hạn này. Data URI phải khai báo kiểu nội dung image/* và ;base64.
Có hai cách để cung cấp ảnh:
URL truy cập công khai: Một URL có thể truy cập được từ internet công cộng.
Data URI: Một Data URI của ảnh được mã hóa base64. Ví dụ về Data URI: data:image/jpeg;base64,<dữ liệu ảnh mã hóa base64 của bạn>.
Name
name
Type
string
Description
Tên tác vụ tùy chọn dùng cho mục đích hiển thị. Tối đa 100 ký tự.
Name
remove_background
Type
boolean
mặc định false
Description
Khi đặt thành true, bản render hiển thị được trả về trong image_urls là một ảnh PNG RGBA trong suốt với nền đã được loại bỏ, để bạn có thể ghép nó lên bất kỳ nền nào.
Điều này chỉ áp dụng cho bản render hiển thị. Candidate mà endpoint build sử dụng không bị ảnh hưởng, vì vậy kết quả 3D vẫn giống nhau trong cả hai trường hợp.
Giá trị trả về
Thuộc tính result của phản hồi chứa id của tác vụ của tác vụ keycap prototype vừa được tạo. Hãy poll endpoint Get a Task hoặc đăng ký stream cho đến khi tác vụ đạt trạng thái SUCCEEDED, sau đó lấy mục từ candidate_ids và truyền nó, cùng với ID của tác vụ, tới endpoint build.
Các chế độ lỗi
Name
400 - Bad Request
Description
Yêu cầu không hợp lệ. Các nguyên nhân phổ biến:
Thiếu tham số: image_url là bắt buộc.
Định dạng ảnh không hợp lệ: image_url được cung cấp không phải là định dạng được hỗ trợ (.jpg, .jpeg, .png, .webp).
Kích thước ảnh nằm ngoài phạm vi cho phép: Ảnh quá nhỏ, vượt quá kích thước tệp tối đa, hoặc vượt quá số lượng pixel tối đa.
URL không thể truy cập: Không thể tải xuống image_url (404 hoặc timeout).
Data URI không hợp lệ: Chuỗi base64 bị lỗi định dạng.
Nội dung bị gắn cờ: Ảnh đầu vào bị gắn cờ bởi moderation nội dung nhạy cảm (NSFW).
Name
401 - Unauthorized
Description
Xác thực thất bại. Vui lòng kiểm tra khóa API của bạn.
Name
402 - Payment Required
Description
Tài khoản đang sử dụng gói miễn phí (cần có gói trả phí để tạo tác vụ) hoặc không đủ tín dụng.
Name
403 - Forbidden
Description
Ảnh đầu vào bị gắn cờ bởi moderation sở hữu trí tuệ.
Name
429 - Too Many Requests
Description
Bạn đã vượt quá giới hạn tốc độ.
Name
500 - Internal Server Error
Description
Đã xảy ra lỗi phía máy chủ ngoài dự kiến — ví dụ: dịch vụ kiểm duyệt nội dung không khả dụng, việc tải tạm (staging) ảnh đầu vào thất bại, hoặc không thể tạo tác vụ. Trong trường hợp này, không có tác vụ nào được tạo, vì vậy việc thử lại là an toàn.
Request
POST
/openapi/creative-lab/keycap/v1/prototype
# Stage 1: generate a finished-keycap design rendercurlhttps://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype \-XPOST \-H"Authorization: Bearer ${YOUR_API_KEY}" \-H'Content-Type: application/json' \-d'{ "image_url": "<your publicly accessible image url or base64-encoded data URI>" }'
Tạo mô hình keycap 3D cuối cùng đã được phủ texture từ một tác vụ prototype đã thành công và một trong các candidate của nó. Một tác vụ build duy nhất chạy toàn bộ pipeline từ đầu đến cuối — tạo white-model từ thiết kế đã chọn, tự động đặt và cắt lên nền keycap bằng một tư thế mặc định đã được hiệu chỉnh (không cần điều chỉnh tương tác), tô màu toàn bộ mô hình, và lắp ráp cùng xuất file cuối cùng. Một lần build thường mất 3–7 phút, thiên về mức cao hơn khi có nhiều lượt build chạy đồng thời.
Tham khảo The Keycap Build Task Object
để biết cấu trúc phản hồi.
Tham số
Name
input_task_id
Type
string
Bắt buộc
Description
ID tác vụ của một tác vụ prototype được tạo qua cùng endpoint OpenAPI này. Prototype phải được tạo bởi cùng tài khoản Meshy, phải đã đạt trạng thái SUCCEEDED, và phải đã tạo ra ít nhất một candidate.
Các tác vụ prototype được tạo qua webapp không được chấp nhận — endpoint build chỉ chấp nhận các tác vụ prototype được tạo bởi POST /openapi/creative-lab/keycap/v1/prototype và từ chối mọi nguồn khác với mã 404.
Name
candidate_id
Type
string
Bắt buộc
Description
Candidate cần build, lấy từ mảng candidate_ids của tác vụ prototype đã thành công. Phải thuộc về tác vụ đó; bất kỳ giá trị nào khác sẽ bị từ chối với mã 400.
Name
name
Type
string
Description
Tên tác vụ tùy chọn để hiển thị. Tối đa 100 ký tự.
options
Tùy chỉnh hình học tùy chọn. Mỗi trường đều có giá trị mặc định đã được hiệu chỉnh — chỉ cần gửi những trường bạn muốn ghi đè.
Name
base_model
Type
string
mặc định cherry-mx-1x1-r1
Description
Nền keycap để build lên. Hiện tại giá trị duy nhất khả dụng là
cherry-mx-1x1-r1 — một keycap 1u chuẩn profile Cherry MX. Dự kiến sẽ có thêm 3–5
kích thước chuẩn phổ biến khác; không hỗ trợ kích thước tùy chỉnh.
Name
head_size_mm
Type
number
mặc định 23
Description
Kích thước mục tiêu của phần đầu điêu khắc, tính bằng milimet: kích thước dài nhất của nó được scale theo giá trị này. Phạm vi: [10, 40]. Các giá trị lớn hơn khoảng 32.9 có thể bị giảm để phần đầu vẫn vừa với giới hạn diện tích bảo vệ của nền, do đó kích thước dài nhất được trả về có thể nhỏ hơn giá trị yêu cầu. Giá trị đã áp dụng hiện chưa được trả lại trong task object — nếu bạn cần xác nhận kích thước thực tế nhận được, hãy đo hộp bao của lưới keycap-head trong mô hình đã tải về.
Name
vertical_offset_mm
Type
number
mặc định 0
Description
Độ dịch chuyển theo phương thẳng đứng áp dụng cho phần đầu trước khi đặt lên nền, tính bằng milimet. Phạm vi: [-5, 5].
Kết quả trả về
Thuộc tính result của phản hồi chứa id tác vụ của tác vụ build keycap vừa được tạo. Poll endpoint Get a Task hoặc đăng ký stream cho đến khi tác vụ đạt trạng thái SUCCEEDED, sau đó tải các artifact từ model_urls.glb và model_urls.obj_zip.
Cả GLB và gói OBJ đều được xuất ở tỷ lệ milimet thực tế, với
hệ tọa độ Y-up và mặt trước của
keycap hướng về +Z.
Các trường hợp lỗi
Name
400 - Bad Request
Description
Yêu cầu không hợp lệ. Các nguyên nhân phổ biến:
Thiếu tham số: input_task_id và candidate_id là bắt buộc.
UUID không hợp lệ: input_task_id không phải là một UUID hợp lệ.
Tác vụ cha chưa thành công: Tác vụ prototype được tham chiếu chưa đạt trạng thái SUCCEEDED.
Không có candidate: Tác vụ prototype đã thành công nhưng không tạo ra candidate nào.
Candidate không xác định: candidate_id không phải là một trong các candidate của tác vụ đầu vào.
Options nằm ngoài phạm vi: Một trong các trường của options nằm ngoài phạm vi cho phép hoặc tập enum cho phép.
Name
401 - Unauthorized
Description
Xác thực thất bại. Vui lòng kiểm tra khóa API của bạn.
Name
402 - Payment Required
Description
Tài khoản đang dùng gói miễn phí (cần có gói trả phí để tạo tác vụ) hoặc không đủ tín dụng.
Name
404 - Not Found
Description
Tác vụ prototype được tham chiếu không tồn tại, thuộc về người dùng khác, hoặc được tạo qua webapp (chỉ các tác vụ prototype ở chế độ API mới có thể nối tiếp sang build).
Name
429 - Too Many Requests
Description
Bạn đã vượt quá giới hạn tốc độ.
Name
500 - Internal Server Error
Description
Đã xảy ra lỗi phía máy chủ ngoài dự kiến — ví dụ dịch vụ moderation nội dung không khả dụng, việc staging ảnh đầu vào thất bại, hoặc tác vụ không thể được tạo. Trong trường hợp này không có tác vụ nào được tạo ra, vì vậy việc thử lại là an toàn.
Request
POST
/openapi/creative-lab/keycap/v1/build
# Stage 2: build the chosen candidate into a 3D keycapcurlhttps://api.meshy.ai/openapi/creative-lab/keycap/v1/build \-XPOST \-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 } }'
Truy xuất một tác vụ prototype hoặc build với một id tác vụ hợp lệ. Đường dẫn URL
phải khớp với giai đoạn của tác vụ — một tác vụ build được lấy qua
/prototype/:id sẽ trả về 404, và ngược lại.
Hủy một keycap task. Nếu task vẫn đang ở trạng thái PENDING, số tín dụng
đã tiêu tốn tại thời điểm tạo sẽ được hoàn lại. Các task đã ở trạng thái
IN_PROGRESS sẽ bị hủy nhưng không được hoàn tiền (worker có thể đã bắt
đầu tiêu tốn tài nguyên). Các task đã đạt đến trạng thái cuối cùng
(SUCCEEDED, FAILED, CANCELED) không thể bị hủy.
Đường dẫn URL phải khớp với giai đoạn của task — gọi DELETE trên
/prototype/:buildId sẽ trả về 404.
Tham số đường dẫn
Name
id
Type
path
Description
Định danh duy nhất của keycap task cần hủy.
Kết quả trả về
Trả về 204 No Content khi thành công với nội dung phản hồi trống.
Các trường hợp lỗi
Name
400 - Bad Request
Description
Task đã ở trạng thái cuối cùng và không thể bị hủy.
Name
404 - Not Found
Description
Task không tồn tại, thuộc về một người dùng khác, hoặc giai đoạn của nó không khớp với đường dẫn URL.
Name
500 - Internal Server Error
Description
Đã xảy ra lỗi phía máy chủ ngoài dự kiến trong quá trình hủy. Task có thể đã bị hủy hoặc chưa — hãy đọc lại để xác nhận trước khi thử lại.
Truyền trực tuyến các cập nhật theo thời gian thực cho một tác vụ keycap thông qua Server-Sent Events (SSE).
Đường dẫn URL phải khớp với giai đoạn của tác vụ — mở một luồng tại
/prototype/:buildId/stream sẽ phát ra một event: error duy nhất với
status_code: 404 rồi đóng luồng lại.
Tham số
Name
id
Type
path
Description
Định danh duy nhất của tác vụ keycap cần truyền trực tuyến.
Giá trị trả về
Trả về một luồng các đối tượng tác vụ Keycap Prototype
hoặc Keycap Build dưới dạng
Server-Sent Events. Mỗi khung dữ liệu đều mang toàn bộ đối tượng tác vụ cho giai đoạn đó — cùng cấu trúc mà
endpoint Get trả về — vì vậy khi tác vụ đang ở trạng thái PENDING hoặc IN_PROGRESS, các
trường đầu ra đơn giản là chưa được điền dữ liệu (null, [] hoặc {}) và
finished_at là null.
// Error event example (wrong stage or task not found)event: errordata: {"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: messagedata: {"id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af","progress": 0,"status": "PENDING"}event: messagedata: {"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=***" }}
Truy xuất một danh sách đã phân trang các tác vụ keycap của bạn cho một giai đoạn duy nhất. Đường dẫn URL
chọn giai đoạn — /prototype trả về các tác vụ nguyên mẫu; /build
trả về các tác vụ dựng. Các tác vụ từ giai đoạn còn lại không được bao gồm trong bất kỳ
phản hồi nào.
Tham số đường dẫn
Name
stage
Type
path
Bắt buộc
Description
Hoặc prototype hoặc build. Tập hợp chỉ trả về các tác vụ
có giai đoạn khớp với URL — việc lấy /prototype không bao giờ trả về
các tác vụ dựng và ngược lại.
Tham số truy vấn
Name
page_num
Type
integer
mặc định 1
Description
Số trang cho việc phân trang.
Name
page_size
Type
integer
mặc định 10
Description
Giới hạn kích thước trang. Tối đa cho phép là 100 mục.
Name
sort_by
Type
string
mặc định -created_at
Description
Trường để sắp xếp theo. Các giá trị khả dụng:
+created_at: Sắp xếp theo thời gian tạo theo thứ tự tăng dần.
-created_at: Sắp xếp theo thời gian tạo theo thứ tự giảm dần.
Đối tượng Keycap Prototype Task là một đơn vị công việc mà Meshy theo dõi để
tạo ra một hình ảnh thiết kế keycap hoàn chỉnh từ một ảnh chụp nguồn. Đầu
ra của giai đoạn này được nối chuỗi sang giai đoạn build
thông qua input_task_id cùng với candidate_id.
Thuộc tính
Name
id
Type
string
Description
Định danh duy nhất cho tác vụ. Mặc dù chúng tôi sử dụng UUID có thể sắp xếp theo k (k-sortable) làm chi tiết triển khai cho id tác vụ, bạn không nên đưa ra bất kỳ giả định nào về định dạng của id.
Name
type
Type
string
Description
Loại của tác vụ. Giá trị là creative-lab-keycap-prototype.
Name
name
Type
string
Description
Tên tác vụ được cung cấp khi tác vụ được tạo. Là chuỗi rỗng nếu không có tên nào được cung cấp.
Name
status
Type
string
Description
Trạng thái của tác vụ. Các giá trị có thể là một trong các giá trị PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
Tiến trình (progress) của tác vụ. Nếu tác vụ chưa bắt đầu, thuộc tính này sẽ là 0. Khi tác vụ đã thành công, giá trị này sẽ trở thành 100.
Name
created_at
Type
timestamp
Description
Dấu thời gian khi tác vụ được tạo, tính bằng mili giây.
Một dấu thời gian biểu thị số mili giây đã trôi qua kể từ ngày 1 tháng 1 năm 1970 UTC, theo
tiêu chuẩn RFC 3339.
Ví dụ, Thứ Sáu, ngày 1 tháng 9 năm 2023 lúc 12:00:00 CH GMT được biểu diễn là 1693569600000. Điều này áp dụng
cho tất cả các dấu thời gian trong Meshy API.
Name
started_at
Type
timestamp
Description
Dấu thời gian khi tác vụ được bắt đầu, tính bằng mili giây. Nếu tác vụ chưa được bắt đầu, thuộc tính này sẽ là 0.
Name
finished_at
Type
timestamp
Description
Dấu thời gian khi tác vụ hoàn tất, tính bằng mili giây. Nếu tác vụ chưa hoàn tất, thuộc tính này sẽ là 0.
Name
expires_at
Type
timestamp
Description
Dấu thời gian khi kết quả tác vụ hết hạn, tính bằng mili giây.
Name
preceding_tasks
Type
integer
Description
Số lượng tác vụ đứng trước.
Giá trị của trường này chỉ có ý nghĩa nếu trạng thái tác vụ là PENDING.
Name
task_error
Type
object
Description
Chi tiết lỗi cho các tác vụ thất bại. Xem Lỗi để biết tham chiếu đầy đủ về đối tượng task_error.
Name
consumed_credits
Type
integer
Description
Số lượng tín dụng đã tiêu thụ bởi tác vụ này. Một tác vụ đạt trạng thái SUCCEEDED sẽ bị tính đầy đủ chi phí cho giai đoạn của nó. Một tác vụ chưa từng được tạo ra (một lỗi 4xx tại thời điểm yêu cầu, bao gồm cả việc bị từ chối bởi moderation) sẽ hoàn toàn không bị tính phí. Một tác vụ đạt trạng thái FAILED trả về 0 — khoản phí sẽ được hoàn lại, bao gồm cả trường hợp bị chặn bởi moderation không đồng bộ. Việc hủy thông qua DELETE chỉ hoàn tiền khi tác vụ vẫn đang ở trạng thái PENDING; một tác vụ đã ở trạng thái IN_PROGRESS vẫn sẽ bị tính phí, vì công việc đã được thực hiện.
Name
image_urls
Type
array of strings
Description
URL có thể tải xuống của bản render thiết kế keycap hoàn chỉnh — thể hiện phương án ứng viên trông như thế nào khi trở thành một keycap hoàn chỉnh. Chỉ chứa một mục duy nhất; image_urls[i] tương ứng với candidate_ids[i]. Trống cho đến khi tác vụ đạt trạng thái SUCCEEDED. URL này chỉ dùng để hiển thị; endpoint build tiêu thụ candidate_ids, chứ không phải các URL này. Vòng đời URL giống như của model_urls: đã được ký, không có tiêu đề Authorization, có hiệu lực cho đến expires_at, và ổn định khi tác vụ được đọc lại.
Name
candidate_ids
Type
array of strings
Description
Các định danh ứng viên không minh bạch (opaque), song song với image_urls. Truyền mục tương ứng với thiết kế bạn đã chọn làm candidate_id của yêu cầu build. Không đưa ra bất kỳ giả định nào về định dạng của các id này.
Đối tượng Keycap Build Task là một đơn vị công việc được Meshy theo dõi để
tạo ra keycap 3D đã phủ texture cuối cùng từ một prototype task đã thành công và một
candidate được chọn. Một lần build sẽ chạy toàn bộ pipeline — tạo mô hình trắng
(white-model), tự động canh khớp và cắt, tô màu, lắp ráp, và xuất file.
Thuộc tính
Name
id
Type
string
Description
Định danh duy nhất cho task.
Name
type
Type
string
Description
Loại của task. Giá trị là creative-lab-keycap-build.
Name
name
Type
string
Description
Tên task được cung cấp khi task được tạo. Là chuỗi rỗng nếu không có tên nào được cung cấp.
Name
status
Type
string
Description
Trạng thái của task. Các giá trị có thể là một trong PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.
Name
progress
Type
integer
Description
progress của task. Nếu task chưa bắt đầu, thuộc tính này sẽ là 0. Khi task đã thành công, giá trị này sẽ trở thành 100.
Name
created_at
Type
timestamp
Description
Dấu thời gian khi task được tạo, tính bằng mili giây.
Name
started_at
Type
timestamp
Description
Dấu thời gian khi task được bắt đầu, tính bằng mili giây.
Name
finished_at
Type
timestamp
Description
Dấu thời gian khi task được hoàn thành, tính bằng mili giây.
Name
expires_at
Type
timestamp
Description
Dấu thời gian khi kết quả của task hết hạn, tính bằng mili giây.
Name
preceding_tasks
Type
integer
Description
Số lượng các task đứng trước. Chỉ có ý nghĩa khi status là PENDING.
Name
task_error
Type
object
Description
Chi tiết lỗi cho các task thất bại. Xem Lỗi để biết đầy đủ tham chiếu đối tượng task_error.
Name
consumed_credits
Type
integer
Description
Số lượng tín dụng đã bị tiêu thụ bởi task này. Một task đạt trạng thái SUCCEEDED sẽ bị tính đầy đủ số tín dụng cho giai đoạn của nó. Một task không bao giờ được tạo ra (một lỗi 4xx tại thời điểm gửi yêu cầu, bao gồm cả việc bị từ chối do moderation) sẽ hoàn toàn không bị tính phí. Một task đạt trạng thái FAILED trả về 0 — khoản phí sẽ được hoàn lại, bao gồm cả trường hợp bị chặn bởi moderation không đồng bộ. Việc hủy qua DELETE chỉ hoàn tiền khi task vẫn đang ở trạng thái PENDING; một task đã ở trạng thái IN_PROGRESS vẫn sẽ bị tính phí, vì công việc đã được thực hiện.
Name
model_urls
Type
object
Description
Các URL có thể tải xuống cho các sản phẩm mô hình được tạo ra. Cả gói GLB và OBJ đều được xuất theo tỷ lệ milimét thực tế, trục Y hướng lên, với mặt trước của keycap hướng về +Z. Các lưới được đặt tên là keycap-head và keycap-base; khi phần đế (base) chuyển sang dùng kiểu lấp đầy hoa văn (pattern fill), một lưới thứ ba keycap-base-interior cũng sẽ xuất hiện cho khoang chứa trục phím (stem cavity). Đừng giả định rằng luôn chỉ có đúng hai lưới.
Đây là các URL đã được ký (signed URLs): hãy lấy chúng mà không cần header Authorization. Chúng vẫn còn hiệu lực cho đến expires_at, tức là 3 ngày sau finished_at, và việc đọc lại task trong khoảng thời gian đó sẽ trả về đúng cùng một URL thay vì một URL mới được ký. Hãy tự tải xuống và lưu trữ các tệp trước thời điểm đó — không có cách nào để làm mới một liên kết đã hết hạn.
Name
glb
Type
string
Description
URL có thể tải xuống cho tệp model.glb đã phủ texture cuối cùng.
Name
obj_zip
Type
string
Description
URL có thể tải xuống cho gói zip chứa model.obj, model.mtl, và các tệp PNG texture mà file MTL của nó thực sự tham chiếu tới. Một phần đế màu đơn sắc chỉ đi kèm keycap-head.png; một phần đế có hoa văn cũng sẽ đi kèm keycap-base.png.
Name
process_image_urls
Type
object
Description
Các URL có thể tải xuống cho các hình ảnh quá trình xử lý trung gian, được đánh khóa theo loại (kind). Vòng đời URL giống với model_urls: đã được ký, không cần header Authorization, có hiệu lực đến expires_at, và ổn định khi task được đọc lại. Các loại (kind) hiện đang được tạo ra:
head_design — hình ảnh thiết kế của candidate được chọn mà quá trình build đã sử dụng (luôn có mặt).
composite — bản render hiển thị keycap hoàn thiện của candidate được chọn (có mặt khi khả dụng).
base_canvas — canvas phần đế keycap đã được vẽ (có mặt khi khả dụng).
Hãy coi tập hợp các khóa (key) này là mở, có thể mở rộng; các loại (kind) mới có thể được thêm vào mà không gây ra thay đổi phá vỡ (breaking change).
Quy trình hoàn chỉnh: tạo một prototype từ một bức ảnh, poll nó cho đến khi
SUCCEEDED, chọn một candidate từ candidate_ids, tạo một build với
candidate đó, poll build cho đến khi SUCCEEDED, sau đó tải xuống GLB và
gói OBJ từ model_urls.
Ví dụ này chọn candidate đầu tiên một cách tự động. Trong một tích hợp
thực tế, bạn nên hiển thị mục image_urls cho người dùng cuối và để họ
lựa chọn; chỉ số được chọn sẽ ánh xạ 1:1 vào candidate_ids.
Complete flow
POST
/openapi/creative-lab/keycap/v1
#!/usr/bin/env bashset-euopipefail# Requires curl and jq. Point IMAGE_PATH at a local photo, or IMAGE_URL at a public one:# export MESHY_API_KEY=msy_...# export IMAGE_PATH=./portrait.jpg # or: export IMAGE_URL=https://...:"${MESHY_API_KEY:?export MESHY_API_KEY first}"if [[ -z"${IMAGE_PATH:-}"&&-z"${IMAGE_URL:-}" ]]; thenecho"export IMAGE_PATH (local file) or IMAGE_URL (public url) first">&2exit1fiBASE="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 bodyshift2 out=$(curl--silent--show-error--max-time60--write-out$'\n%{http_code}' \-X"$method""$url"-H"$AUTH""$@") ||return1 http_code=${out##*$'\n'} body=${out%$'\n'*}if ((http_code >=400)); thenecho"HTTP $http_code for $url: $body">&2return1fiprintf'%s'"$body"}# Each task gets its own 40-minute budget.poll() {local kind=$1 id=$2 delay=5 task_status deadline deadline=$(($(date+%s) + 2400))while:; doif (($(date +%s) >= deadline)); thenecho"gave up waiting for $kind $id">&2return1fi task_status=$(apiGET"$BASE/$kind/$id"|jq-r'.status')echo"$kind: $task_status"case"$task_status"inSUCCEEDED)return0 ;;FAILED|CANCELED)return1 ;;esacsleep"$delay" delay=$((delay*2>30?30:delay*2))done}# Build the request body in a file. A base64 data URI must never go on the# command line or into an exported variable - a photo of any real size will# exceed the OS argument limit.BODY=$(mktemp)trap'rm -f "$BODY"'EXITif [[ -n"${IMAGE_PATH:-}" ]]; then# Declare the real type: the API accepts JPEG, PNG and WebP.case"$(printf '%s' "${IMAGE_PATH##*.}" |tr 'A-Z' 'a-z')"inpng) MIME=image/png ;;webp) MIME=image/webp ;;*) MIME=image/jpeg ;;esac {printf'{"image_url":"data:%s;base64,'"$MIME"base64<"$IMAGE_PATH"|tr-d'\n'printf'"}' } >"$BODY"elseprintf'{"image_url":"%s"}'"$IMAGE_URL">"$BODY"fi# 1. Create the prototype taskPROTO_ID=$(apiPOST"$BASE/prototype" \-H'Content-Type: application/json'--data-binary@"$BODY"|jq-r'.result')# 2. Wait for the design renderpollprototype"$PROTO_ID"# 3. Pick a candidate (first one here; show image_urls to a user in production)CANDIDATE_ID=$(apiGET"$BASE/prototype/$PROTO_ID"|jq-r'.candidate_ids[0]')# 4. Create the build taskjq-n--argp"$PROTO_ID"--argc"$CANDIDATE_ID" \'{input_task_id: $p, candidate_id: $c}'>"$BODY"BUILD_ID=$(apiPOST"$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)pollbuild"$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=$(apiGET"$BASE/build/$BUILD_ID")curl--silent--show-error--fail--max-time900 \-okeycap.glb"$(jq-r '.model_urls.glb' <<<"$TASK")"curl--silent--show-error--fail--max-time900 \-okeycap-obj.zip"$(jq-r '.model_urls.obj_zip' <<<"$TASK")"echo"Done: keycap.glb + keycap-obj.zip"