Creative Lab Keycap API
Перетворіть фотографію на повнокольорову кастомну клавішу (кейкап) для механічної клавіатури у два етапи. Завдання прототипу генерує зображення готової клавіші з фотографії. Завдання збірки перетворює це зображення на текстуровану 3D-модель клавіші. Воно приймає ID завдання прототипу як input_task_id та ID кандидата зображення як candidate_id.
POST /openapi/creative-lab/keycap/v1/prototypePOST /openapi/creative-lab/keycap/v1/build
Обидва POST endpoint потребують платного плану. Запит з облікового запису безкоштовного плану повертає 402.
Створення завдання прототипу Keycap
Генерує одне зображення готового ковпачка клавіші (keycap) із фотографії. Поле image_urls завдання містить зображення, а candidate_ids містить його ID, по одному запису в кожному. Якщо дизайн вам не сподобався, створіть інше завдання прототипу. Meshy стягує плату за кожне завдання прототипу окремо.
Щоб побудувати 3D-ковпачок клавіші, передайте ID цього завдання до кінцевої точки побудови як input_task_id, разом із записом candidate_ids як candidate_id. Про поля завдання читайте в розділі Об'єкт завдання прототипу Keycap.
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 МБ (20 000 000 байт). Кожна сторона має бути не менше 32 пікселів, а загальна кількість пікселів у зображенні не повинна перевищувати 178 956 970. Зображення, що виходить за ці межі, повертає
400.Meshy визначає формат за даними зображення, а не за розширенням файлу в URL. URL без розширення теж працює, і Meshy переходить за HTTP-перенаправленнями. Meshy враховує орієнтацію EXIF, тому перевернуте фото з телефону виглядає правильно.
Data URI має бути закодований у base64 з типом зображення, наприклад
data:image/png;base64,..., а декодоване зображення має бути у форматі JPEG, PNG або WebP. Обмеження у 20 МБ застосовується до декодованого зображення, тому текст у base64 може бути приблизно на третину більшим.
- Name
- name
- Type
- string
- Description
Назва завдання, до 100 символів. Вона повертається в полі
nameзавдання. Довша назва повертає400.
- Name
- remove_background
- Type
- boolean
- за замовчуванням false
- Description
Чи потрібно видалити фон із зображення прототипу.
trueповертає прозорий PNG у форматі RGBA, щоб ви могли розмістити ковпачок клавіші на будь-якому фоні. Якщо Meshy не може видалити фон, повертається зображення з фоном, і завдання все одно завершується успішно.Дизайн верхньої частини, який при побудові перетворюється на 3D, зберігає свій фон у будь-якому випадку. Побудова малює основу ковпачка клавіші із зображення в
image_urls, без фону, якщо ви передалиtrue. Побудова повертає це зображення якprocess_image_urls.composite.
Результати
Поле result містить ID нового завдання прототипу. Отримайте завдання або транслюйте його, доки status не стане SUCCEEDED. Потім передайте ID до кінцевої точки побудови як input_task_id, разом із записом із candidate_ids як candidate_id.
Режими збою
- Name
400 - Bad Request- Description
Запит не може бути виконаний. Наприклад:
- Відсутній
image_url. - Зображення не є файлом JPG, JPEG, PNG або WebP.
- Зображення занадто мале, перевищує 20 МБ або максимальну кількість пікселів.
- 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
Генерує текстурований 3D-ковпачок клавіші на основі успішної задачі-прототипу та одного з її кандидатів. Опис полів див. у розділі Об'єкт задачі побудови Keycap.
Одна задача побудови виконує всі кроки. Вона генерує 3D-модель із дизайну та надає їй кольори. Потім вона розміщує та обрізає модель на основі ковпачка клавіші в каліброваній позі за замовчуванням, тож вам не потрібно коригувати це вручну. Нарешті, вона збирає ковпачок клавіші та експортує файли. Побудова зазвичай триває від 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 задачі-прототипу для побудови. Це має бути задача, яку створив ваш обліковий запис за допомогою
POST /openapi/creative-lab/keycap/v1/prototype, зі статусомSUCCEEDED.ID, що не належить до жодної з ваших задач-прототипів Keycap з API, повертає
404, включно з прототипом, створеним у веб-застосунку.
- Name
- candidate_id
- Type
- string
- Обов'язковий
- Description
Кандидат для побудови, з масиву
candidate_idsзадачі-прототипу. Значення, якого немає в цьому масиві, повертає400.
- Name
- name
- Type
- string
- Description
Назва задачі, до 100 символів. Вона повертається в полі
nameзадачі. Довша назва повертає400.
options
Необов'язкові налаштування геометрії. Кожне поле має каліброване значення за замовчуванням, тому надсилайте лише ті поля, які хочете змінити.
- Name
- base_model
- Type
- string
- за замовчуванням cherry-mx-1x1-r1
- Description
Основа ковпачка клавіші для побудови. Єдине значення —
cherry-mx-1x1-r1, стандартний ковпачок клавіші профілю Cherry MX 1u. Нестандартні розміри не підтримуються, і будь-яке інше значення повертає400.
- Name
- head_size_mm
- Type
- number
- за замовчуванням 23
- Description
Розмір головки вздовж її найдовшого виміру, у міліметрах, від
10до40. Meshy масштабує головку так, щоб її найдовший вимір відповідав цьому значенню. Значення поза межами діапазону повертає400.Для значення вище приблизно
32.9Meshy може зменшити розмір, щоб головка вмістилася в межі захисного периметра основи. У такому разі головка може вийти меншою, ніж ви запитували. Об'єкт задачі не повертає розмір, застосований Meshy. Щоб перевірити його, виміряйте обмежувальний паралелепіпед сіткиkeycap-headу моделі.
- Name
- vertical_offset_mm
- Type
- number
- за замовчуванням 0
- Description
Вертикальне зміщення, яке застосовується до головки перед тим, як Meshy розмістить її на основі, у міліметрах, від
-5до5. Значення поза межами діапазону повертає400.
Повернення
Поле result містить ID нової задачі побудови. Отримайте задачу або передавайте її потоком, доки status не стане SUCCEEDED. Потім завантажте файл GLB з model_urls.glb та пакет OBJ з model_urls.obj_zip.
Meshy експортує файл GLB та пакет OBJ у реальному масштабі в міліметрах. Обидва використовують систему координат з віссю Y вгору, при цьому передня частина ковпачка клавіші спрямована в бік +Z.
Режими відмов
- Name
400 - Bad Request- Description
Запит не може бути виконаний. Наприклад:
input_task_idвідсутній або не є дійсним ID задачі.- Статус задачі-прототипу не
SUCCEEDED. Якщо вона ще виконується, зачекайте та повторіть спробу. Якщо вона завершилася невдало або була скасована, створіть нову задачу-прототип. - Задача-прототип завершилася успішно, але не має кандидатів. Створіть нову задачу-прототип.
candidate_idвідсутній або не входить доcandidate_idsзадачі-прототипу. Надішліть значення з цього масиву.- Поле в
optionsвиходить за межі діапазону, абоbase_modelне є доступним значенням.
Повідомлення про помилку вказує, яку саме проблему виявлено.
- Name
401 - Unauthorized- Description
API-ключ відсутній або недійсний. Перевірте заголовок
Authorization.
- Name
402 - Payment Required- Description
Застосовується один із цих випадків:
- На обліковому записі недостатньо кредитів.
- API-ключ, робоча область або учасник досягли ліміту кредитів.
- Обліковий запис перебуває на безкоштовному плані.
Перевірте свої кредити та план, потім повторіть спробу.
- Name
404 - Not Found- Description
input_task_idне відповідає жодній задачі-прототипу Keycap, яку ваш обліковий запис створив через API. Прототип, створений у веб-застосунку, також повертає404. Надішліть IDresultз відповіді на створення прототипу.
- Name
429 - Too Many Requests- Description
Досягнуто одного з цих обмежень:
- Ви надіслали більше запитів, ніж дозволяє ваше обмеження частоти. Зачекайте кілька секунд, потім повторіть спробу. Див. Обмеження частоти.
- Забагато ваших задач перебувають у черзі або виконуються. Зачекайте, поки деякі з них завершаться, потім повторіть спробу.
- На необмеженому плані без залишку кредитів ви досягли кількості задач, які можуть виконуватися без кредитів. Зачекайте завершення задачі або додайте кредити.
- Name
500 - Internal Server Error- Description
Meshy не вдалося створити задачу через помилку сервера. Meshy повертає будь-які стягнені кредити. Повторіть запит.
Отримати завдання Keycap
Повертає завдання прототипу або збірки. Шлях повинен відповідати стадії завдання. Завдання збірки, запитане через /prototype/:id, повертає 404, так само як і завдання прототипу, запитане через /build/:id.
Щодо полів, див. Об'єкт завдання прототипу Keycap та Об'єкт завдання збірки Keycap.
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
ID завдання з відповіді на створення.
Повертає
Об'єкт завдання прототипу або об'єкт завдання збірки, відповідно до стадії в шляху.
Режими збою
- Name
400 - Bad Request- Description
idне є дійсним ID завдання. Надішліть IDresultз відповіді на створення.
- Name
403 - Forbidden- Description
У вашій команді увімкнено Фільтрацію IP, і Meshy позначив зображення завдання прототипу через права інтелектуальної власності третіх сторін. Завдання збірки та команди на плані Enterprise не отримують цю помилку. Створіть завдання прототипу із зображення, на використання якого ви маєте права.
- Name
404 - Not Found- Description
Завдання Keycap з цим ID не належить вашому акаунту, або стадія завдання не відповідає шляху. Перевірте ID та використовуйте
/prototypeабо/buildвідповідно до завдання.
- Name
500 - Internal Server Error- Description
Meshy не зміг виконати перевірку інтелектуальної власності. Повторіть запит.
Видалення задачі Keycap
Скасовує задачу Keycap. Скасування задачі зі статусом PENDING повертає витрачені кредити. Задача зі статусом IN_PROGRESS скасовується без повернення коштів, оскільки воркер уже почав її виконання. Задачу з фінальним статусом (SUCCEEDED, FAILED або CANCELED) скасувати не можна.
Шлях має відповідати етапу задачі. Наприклад, запит DELETE на /prototype/:id з ідентифікатором задачі build поверне 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, перш ніж повторити спробу.
Потокова передача завдання Keycap
Передає оновлення завдання Keycap у вигляді подій Server-Sent Events (SSE). Шлях має відповідати етапу завдання. Якщо це не так, наприклад, ID завдання build за адресою /prototype/:id/stream, потік надсилає одну подію error зі значенням 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 завдання з відповіді на створення.
Повертає
Потік об'єктів завдання prototype або build. Кожна подія містить повний об'єкт завдання, так само як його повертає Отримати завдання Keycap. Поки завдання має статус PENDING або IN_PROGRESS, його вихідні поля все ще порожні (null, [] або {}), а finished_at дорівнює null.
Якщо IP Filtering блокує результат завдання, потік натомість надсилає одну подію error з кодом status_code, який повернув би get-запит.
Отримання списку завдань Keycap
Повертає ваші завдання Keycap одного етапу, по одній сторінці за раз. Шлях вибирає етап. /prototype повертає лише завдання прототипу, а /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"
]
}
]
Параметри шляху
- Name
- stage
- Type
- path
- Обов'язковий
- Description
Етап для відображення,
prototypeабоbuild.
Параметри запиту
- 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: спочатку найстаріші
Повертає
Масив об’єктів завдань прототипу або об’єктів завдань збірки, відповідно до етапу, вказаного у шляху.
Об'єкт завдання прототипу Keycap
Завдання прототипу генерує одне зображення готового ковпачка клавіші (keycap) з фотографії. Щоб перетворити дизайн на 3D-ковпачок клавіші, передайте ID завдання до кінцевої точки build як input_task_id, разом із відповідним записом candidate_ids як candidate_id.
Властивості
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 завдання. Не покладайтеся на його формат.
- 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
Час, коли воркер почав виконувати завдання, у мілісекундах 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-запит або потоковій відповіді це поле відсутнє, а запит списку повертає500. У такому разі повторіть запит.
- Name
- image_urls
- Type
- array of strings
- Description
URL-адреси для завантаження зображення готового ковпачка клавіші. Масив містить одну URL-адресу після успішного завершення завдання, і є порожнім до цього моменту.
image_urls[i]показує кандидата зcandidate_ids[i].Ці URL-адреси призначені для відображення. Кінцева точка build приймає запис із
candidate_ids, а не URL-адресу. Це підписані URL-адреси, тож отримуйте їх без заголовкаAuthorization. Вони залишаються дійсними доexpires_at, і повторне отримання завдання повертає ті самі URL-адреси.
- Name
- candidate_ids
- Type
- array of strings
- Description
ID кандидатів, у тому ж порядку, що й
image_urls. Щоб побудувати кандидата, надішліть його ID якcandidate_idу запиті build. Не покладайтеся на формат цих ID.
Об'єкт завдання збірки Keycap
Завдання збірки генерує текстурований 3D keycap з успішного завдання прототипування та одного з його кандидатів. Воно генерує 3D-модель, фарбує її, встановлює та врізає її в основу keycap, а потім збирає та експортує keycap.
Властивості
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
Час, коли воркер почав виконувати завдання, у мілісекундах 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 не може прочитати списання, у відповіді на запит отримання або потокову передачу це поле відсутнє, а запит списку повертає500. У такому випадку повторіть запит.
- Name
- model_urls
- Type
- object
- Description
URL-адреси для завантаження 3D-моделі. Meshy експортує файл GLB та пакет OBJ у реальному масштабі в міліметрах, з віссю Y вгору, передньою стороною keycap, спрямованою до +Z.
Модель має сітки з назвами
keycap-headтаkeycap-base. Коли Meshy використовує заливку візерунком для основи як резервний варіант, модель також має сіткуkeycap-base-interiorдля порожнини штока. Не припускайте, що модель має рівно дві сітки.Це підписані URL-адреси, тому отримуйте їх без заголовка
Authorization. Вони залишаються дійсними до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-адреси для завантаження зображень з етапів збірки, з ключами за типом. Як і
model_urls, це підписані URL-адреси, тому отримуйте їх без заголовкаAuthorization. Вони залишаються дійсними доexpires_at, і повторне отримання завдання повертає ті самі URL-адреси.Вона може мати такі ключі:
head_design: дизайн-зображення обраного кандидата, яке збірка перетворила на 3D. Завжди присутнє.composite: зображення готового keycap для обраного кандидата, з якого збірка зафарбувала основу. Може бути відсутнім.base_canvas: зафарбована основа keycap. Може бути відсутньою.
Meshy може додавати ключі, тому ігноруйте ключ, який ви не розпізнаєте.
Наскрізний приклад
Цей приклад виконує весь процес:
- Створення завдання прототипу з фотографії.
- Отримання завдання, доки його
statusне станеSUCCEEDED. - Вибір кандидата з
candidate_ids. - Створення завдання збірки з цим кандидатом.
- Отримання завдання збірки, доки його
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"