lowpoly будет отключён 30 окт. 2026 г.. Перейдите на другую модель до этих дат, чтобы избежать ошибок в запросах. Все устаревшие функции

Keycap API для Creative Lab

Превратите фотографию в полноцветный кастомный колпачок для клавиш механической клавиатуры в два этапа. Задача прототипа генерирует изображение готового колпачка на основе фотографии. Задача сборки превращает это изображение в текстурированную 3D-модель колпачка. Она принимает ID задачи прототипа в качестве input_task_id и ID кандидата изображения в качестве candidate_id.

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

Оба endpoint'а POST требуют платный тариф. Запрос с бесплатного аккаунта возвращает 402.


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

Создать задачу прототипа Keycap

Генерирует одно изображение готового keycap по фото. Поле image_urls задачи содержит изображение, а candidate_ids — его ID, по одной записи в каждом. Если дизайн вам не понравился, создайте ещё одну задачу прототипа. Meshy взимает плату за каждую задачу прототипа отдельно.

Чтобы построить 3D-keycap, передайте ID этой задачи в эндпоинт сборки как input_task_id, а запись из candidate_ids — как candidate_id. Описание полей задачи см. в разделе Объект задачи прототипа Keycap.

Request

POST
/openapi/creative-lab/keycap/v1/prototype
# Stage 1: generate a finished-keycap design render
curl https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype \
  -X POST \
  -H "Authorization: Bearer ${YOUR_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "image_url": "<your publicly accessible image url or base64-encoded data URI>"
  }'

Response

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

Параметры

  • Name
    image_url
    Type
    string
    Обязательный
    Description

    Фото, которое нужно превратить в дизайн keycap, в виде публичного 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, так что вы можете разместить keycap на любом фоне. Если Meshy не может удалить фон, он возвращает изображение с его фоном, и задача всё равно завершается успешно.

    Дизайн головки, который сборка превращает в 3D, сохраняет свой фон в любом случае. Сборка окрашивает основание keycap по изображению из 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 произошла ошибка сервера, например потому что не удалось выполнить модерацию контента или проверку интеллектуальной собственности, либо Meshy не смог сохранить изображение. Meshy не создаёт задачу и возвращает все списанные кредиты. Повторите запрос.


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

Создать задачу сборки Keycap

Генерирует текстурированную 3D-модель клавиши (keycap) на основе успешно выполненной задачи-прототипа и одного из её кандидатов. Описание полей см. в разделе Объект задачи сборки Keycap.

Одна задача сборки выполняет все шаги. Она генерирует 3D-модель из дизайна и раскрашивает её. Затем она устанавливает и обрезает модель на основании клавиши в откалиброванном положении по умолчанию, поэтому вам не нужно корректировать её вручную. Наконец, она собирает клавишу и экспортирует файлы. Сборка обычно занимает от 3 до 7 минут.

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

Параметры

  • 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.9 Meshy может уменьшить размер, чтобы головка помещалась в пределах защитного контура основания. В этом случае головка может оказаться меньше, чем вы запросили. Объект задачи не возвращает размер, применённый 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.

Режимы сбоев

  • 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. Отправьте ID result из ответа на создание прототипа.

  • Name
    429 - Too Many Requests
    Description

    Был достигнут один из следующих лимитов:

    • Вы отправили больше запросов, чем допускает ваше ограничение частоты. Подождите несколько секунд, затем повторите попытку. См. Ограничения частоты.
    • Слишком много ваших задач находится в очереди или выполняется. Подождите, пока некоторые из них завершатся, затем повторите попытку.
    • На безлимитном плане без оставшихся кредитов вы достигли количества задач, которые могут выполняться без кредитов. Подождите завершения задачи или добавьте кредиты.
  • Name
    500 - Internal Server Error
    Description

    Meshy не смогла создать задачу из-за ошибки сервера. Meshy возвращает любые списанные кредиты. Повторите запрос.


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

Получить задачу Keycap

Возвращает задачу прототипа или сборки. Путь должен соответствовать этапу задачи. Задача сборки, запрошенная через /prototype/:id, вернёт 404, и то же самое произойдёт с задачей прототипа, запрошенной через /build/:id.

Описание полей см. в разделах Объект задачи прототипа Keycap и Объект задачи сборки Keycap.

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

Параметры

  • Name
    id
    Type
    path
    Description

    ID задачи из ответа на создание.

Возвращает

Объект задачи прототипа или объект задачи сборки, в зависимости от этапа, указанного в пути.

Возможные ошибки

  • Name
    400 - Bad Request
    Description

    id не является допустимым ID задачи. Укажите ID result из ответа на создание.

  • Name
    403 - Forbidden
    Description

    В вашей команде включена функция IP Filtering, и Meshy пометил изображение задачи прототипа как нарушающее права интеллектуальной собственности третьих лиц. Задачи сборки и команды на тарифе Enterprise не получают эту ошибку. Создавайте задачу прототипа из изображения, на использование которого у вас есть права.

  • Name
    404 - Not Found
    Description

    Задача Keycap с этим ID не принадлежит вашему аккаунту, либо этап задачи не соответствует указанному пути. Проверьте ID и используйте /prototype или /build в соответствии с задачей.

  • Name
    500 - Internal Server Error
    Description

    Meshy не удалось выполнить проверку интеллектуальной собственности. Повторите запрос.


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

Удаление задачи Keycap

Отменяет задачу Keycap. Отмена задачи со статусом PENDING возвращает затраченные кредиты. Задача со статусом IN_PROGRESS отменяется без возврата кредитов, поскольку воркер уже приступил к её выполнению. Задачу с финальным статусом (SUCCEEDED, FAILED или CANCELED) отменить нельзя.

Путь должен соответствовать этапу задачи. Например, запрос DELETE к /prototype/:id с ID задачи этапа build вернёт 404.

Request

DELETE
/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef
curl --request DELETE \
  --url https://api.meshy.ai/openapi/creative-lab/keycap/v1/prototype/019c9a4e-2b31-7f6a-8c44-5d2a87b3c1ef \
  -H "Authorization: Bearer ${YOUR_API_KEY}"

Response

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

Параметры пути

  • Name
    id
    Type
    path
    Description

    ID задачи, которую нужно отменить.

Возвращает

204 No Content с пустым телом ответа.

Возможные ошибки

  • Name
    400 - Bad Request
    Description

    Применимо одно из следующего:

    • id не является допустимым ID задачи. Отправьте ID result из ответа на запрос создания.
    • Задача уже имеет финальный статус (SUCCEEDED, FAILED или CANCELED), поэтому её нельзя отменить.
  • Name
    404 - Not Found
    Description

    Задача Keycap с таким ID не принадлежит вашему аккаунту, либо этап задачи не соответствует указанному пути. Проверьте ID и используйте /prototype или /build в соответствии с задачей.

  • Name
    500 - Internal Server Error
    Description

    На стороне Meshy произошла ошибка сервера при отмене задачи, поэтому задача может быть как отменена, так и не отменена. Получите задачу, чтобы проверить её status, прежде чем повторить попытку.


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

Получение обновлений задачи Keycap через поток

Передаёт обновления задачи Keycap в виде Server-Sent Events (SSE). Путь должен соответствовать этапу задачи. Если это не так, например ID задачи build используется по адресу /prototype/:id/stream, поток отправляет одно событие error со status_code: 404 и закрывается.

Request

GET
/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream
curl -N https://api.meshy.ai/openapi/creative-lab/keycap/v1/build/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/stream \
-H "Authorization: Bearer ${YOUR_API_KEY}"

Response Stream

// Error event example (wrong stage or task not found)
event: error
data: {
  "status_code": 404,
  "message": "Task not found"
}

// Message event examples illustrate task progress.
// Every frame is the full task object; fields not yet populated are null / empty.
// The following PENDING frame is shortened to the fields that change.
event: message
data: {
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "progress": 0,
  "status": "PENDING"
}

event: message
data: {
  "id": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af",
  "type": "creative-lab-keycap-build",
  "status": "SUCCEEDED",
  "progress": 100,
  "created_at": 1753142600000,
  "started_at": 1753142610000,
  "finished_at": 1753143050000,
  "expires_at": 1753402250000,
  "task_error": null,
  "consumed_credits": 50,
  "model_urls": {
    "glb": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model.glb?Expires=***",
    "obj_zip": "https://assets.meshy.ai/***/tasks/019c9a52-7d18-7e2b-9f01-6e3b98c4d2af/output/model-obj.zip?Expires=***"
  },
  "process_image_urls": {
    "head_design": "https://assets.meshy.ai/***/head-design.png?Expires=***"
  }
}

Параметры

  • Name
    id
    Type
    path
    Description

    ID задачи из ответа на создание.

Возвращаемые данные

Поток объектов задач prototype или build. Каждое событие содержит полный объект задачи, в том виде, в каком его возвращает Получение задачи Keycap. Пока задача находится в статусе PENDING или IN_PROGRESS, её выходные поля всё ещё пусты (null, [] или {}), а finished_at равно null.

Если Фильтрация по IP блокирует результат задачи, поток отправляет вместо него одно событие error с тем status_code, который вернул бы GET-запрос.


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

Список задач Keycap

Возвращает ваши задачи Keycap одного этапа, по одной странице за раз. Путь определяет этап. /prototype возвращает только задачи прототипа, а /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"
    ]
  }
]

Параметры пути

  • 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 задачи в эндпоинт сборки как 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_error
    • CANCELED: завершено, без результата
  • 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
    image_urls
    Type
    array of strings
    Description

    URL-адреса для скачивания изображения готового колпачка клавиши. Массив содержит один URL после успешного завершения задачи и пуст до этого момента. image_urls[i] показывает кандидата из candidate_ids[i].

    Эти URL предназначены для отображения. Эндпоинт сборки принимает запись из candidate_ids, а не URL. Это подписанные URL, поэтому запрашивайте их без заголовка Authorization. Они остаются действительными до expires_at, и повторное получение задачи возвращает те же URL.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    ID кандидатов, в том же порядке, что и image_urls. Чтобы собрать кандидата, отправьте его ID как candidate_id в запросе сборки. Не полагайтесь на формат этих ID.


Объект задачи сборки Keycap

Задача сборки генерирует текстурированный 3D-колпачок клавиши из успешно выполненной задачи прототипа и одного из её кандидатов. Она генерирует 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_error
    • CANCELED: финальный статус, без результата
  • 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 вверх, при этом передняя часть колпачка направлена вдоль +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: изображение готового колпачка для выбранного кандидата, на основе которого было раскрашено основание. Может отсутствовать.
    • base_canvas: раскрашенное основание колпачка. Может отсутствовать.

    Meshy может добавлять ключи, поэтому игнорируйте неизвестный вам ключ.


End-to-end example

Пример выполняет весь процесс целиком:

  1. Создать задачу прототипа из фотографии.
  2. Получать задачу до тех пор, пока её status не станет SUCCEEDED.
  3. Выбрать кандидата из candidate_ids.
  4. Создать задачу сборки с этим кандидатом.
  5. Получать задачу сборки до тех пор, пока её status не станет SUCCEEDED.
  6. Скачать файл GLB и архив OBJ из model_urls.

В примере выбирается первый кандидат. В вашем приложении показывайте пользователям записи image_urls и дайте им возможность выбора. Индекс выбранного изображения в image_urls совпадает с индексом его ID в 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"