lowpoly は 2026/10/30 に廃止されます。 リクエストエラーを避けるため、これらの日付までにモデルを切り替えてください。 非推奨の一覧を見る

Creative Lab キーキャップ API

写真を2段階でメカニカルキーボード用のフルカラーカスタムキーキャップに変換します。プロトタイプタスクは、写真から完成したキーキャップの画像を生成します。ビルドタスクは、その画像をテクスチャ付きの3Dキーキャップモデルに変換します。プロトタイプタスクのIDを input_task_id として、画像の候補IDを candidate_id として受け取ります。

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

両方の POST endpoint には有料プランが必要です。無料プランのアカウントからのリクエストは 402 を返します。


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

Keycapプロトタイプタスクを作成する

写真から完成したキーキャップの画像を1枚生成します。タスクのimage_urlsにはその画像が、candidate_idsにはそのIDが、それぞれ1件ずつ格納されます。デザインが気に入らない場合は、別のプロトタイプタスクを作成してください。Meshyはプロトタイプタスクごとに個別に課金します。

3Dキーキャップを作成するには、このタスクのIDをinput_task_idとしてbuildエンドポイントに渡し、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

    キーキャップデザインに変換する写真を、公開URLまたはData URI(data:image/jpeg;base64,<your base64-encoded image data>)として指定します。

    画像はJPG、JPEG、PNG、またはWebPファイルで、最大20 MB(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 MBの制限はデコード後の画像に適用されるため、base64テキストは約3分の1大きくなる場合があります。

  • Name
    name
    Type
    string
    Description

    タスクの名前で、最大100文字です。タスクのnameフィールドに返されます。これより長い名前を指定すると400が返されます。

  • Name
    remove_background
    Type
    boolean
    デフォルト false
    Description

    プロトタイプ画像の背景を除去するかどうかを指定します。trueを指定すると透過RGBA PNGが返されるため、任意の背景にキーキャップを配置できます。Meshyが背景を除去できない場合は、背景付きの画像を返し、タスクは引き続き成功します。

    buildが3Dに変換するヘッド部分のデザインは、いずれの場合も背景を保持します。buildはimage_urlsの画像からキーキャップのベースを描画し、trueを送信した場合はその背景を除いて描画します。buildはその画像をprocess_image_urls.compositeとして返します。

返り値

resultフィールドには、新しいプロトタイプタスクのIDが格納されます。statusがSUCCEEDEDになるまでタスクを取得するか、ストリーミングで取得してください。その後、IDをinput_task_idとしてbuildエンドポイントに渡し、candidate_idsのエントリをcandidate_idとして渡します。

失敗モード

  • Name
    400 - Bad Request
    Description

    リクエストを実行できません。たとえば次のような場合です。

    • image_urlが指定されていない。
    • 画像がJPG、JPEG、PNG、またはWebPファイルではない。
    • 画像が小さすぎる、20 MBを超えている、または最大ピクセル数を超えている。
    • Meshyが画像をダウンロードできない。たとえばURLが404を返す場合やタイムアウトする場合。
    • Data URIが有効なbase64ではない。
    • 画像がNSFWとしてフラグ付けされた。

    エラーメッセージには、検出された問題の内容が記載されています。リクエストを修正してから、再度送信してください。

  • Name
    401 - Unauthorized
    Description

    APIキーが指定されていないか、無効です。Authorizationヘッダーを確認してください。

  • Name
    402 - Payment Required
    Description

    次のいずれかに該当します。

    • アカウントのクレジットが不足している。
    • APIキー、ワークスペース、またはメンバーがクレジット上限に達した。
    • アカウントが無料プランである。

    クレジットとプランを確認してから、再試行してください。

  • Name
    403 - Forbidden
    Description

    あなたのチームでIPフィルタリングが有効になっており、Meshyがその画像をサードパーティの知的財産としてフラグ付けしました。使用権を持つ画像を送信してください。

  • Name
    429 - Too Many Requests
    Description

    次のいずれかの上限に達しました。

    • レート制限で許可されている数を超えるリクエストを送信した。数秒待ってから再試行してください。レート制限を参照してください。
    • キューに入っている、または実行中のタスクが多すぎる。いくつか完了するのを待ってから再試行してください。
    • クレジットを使い切った無制限プランで、クレジットなしで実行できるタスク数に達した。タスクが完了するのを待つか、クレジットを追加してください。
  • Name
    500 - Internal Server Error
    Description

    Meshyでサーバーエラーが発生しました。たとえばコンテンツmoderationや知的財産チェックを実行できなかった、またはMeshyが画像を保存できなかった場合です。Meshyはタスクを作成せず、課金されたクレジットがあれば返金します。リクエストを再試行してください。


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

Keycapビルドタスクを作成する

成功したプロトタイプタスクとそのキャンディデートの1つから、テクスチャ付きの3Dキーキャップを生成します。フィールドについては、The Keycap build task objectを参照してください。

1つのビルドタスクで、すべてのステップが実行されます。デザインから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のタスクである必要があります。

    APIから作成されたあなたのKeycapプロトタイプタスクに一致しないIDは、ウェブアプリで作成されたプロトタイプを含め、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になるまでタスクを取得するか、ストリーミングで取得してください。その後、model_urls.glbからGLBファイルを、model_urls.obj_zipからOBJバンドルをダウンロードしてください。

失敗モード

  • 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が、あなたのアカウントがAPIで作成したどのKeycapプロトタイプタスクとも一致しません。ウェブアプリで作成されたプロトタイプも404を返します。プロトタイプ作成レスポンスのresult IDを送信してください。

  • Name
    429 - Too Many Requests
    Description

    以下のいずれかの制限に達しました:

    • レート制限で許可されている数を超えるリクエストを送信した。数秒待ってから再試行してください。Rate limitsを参照してください。
    • キューに入っているか実行中のタスクが多すぎる。いくつか完了するのを待ってから再試行してください。
    • クレジットが残っていない無制限プランで、クレジットなしで実行できるタスク数の上限に達した。タスクが完了するのを待つか、クレジットを追加してください。
  • Name
    500 - Internal Server Error
    Description

    サーバーエラーのため、Meshyはタスクを作成できませんでした。Meshyは課金されたクレジットを払い戻します。リクエストを再試行してください。


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

Keycapタスクを取得

プロトタイプまたはビルドタスクを返します。パスはタスクのステージと一致している必要があります。/prototype/:id でリクエストされたビルドタスクは 404 を返し、/build/:id でリクエストされたプロトタイプタスクも同様に 404 を返します。

各フィールドについては、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ではありません。作成レスポンスの result IDを送信してください。

  • Name
    403 - Forbidden
    Description

    あなたのチームでIPフィルタリングが有効になっており、Meshyがプロトタイプタスクの画像を第三者の知的財産としてフラグ付けしました。ビルドタスクおよびEnterpriseプランのチームでは、このエラーは発生しません。使用権のある画像からプロトタイプタスクを作成してください。

  • Name
    404 - Not Found
    Description

    このIDのKeycapタスクがあなたのアカウントに属していないか、タスクのステージがパスと一致していません。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)のタスクはキャンセルできません。

パスはタスクのステージと一致している必要があります。例えば、ビルドタスクの ID を使って /prototype/:id に対して DELETE を実行すると 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 ではありません。作成レスポンスの result ID を送信してください。
    • タスクはすでに最終ステータス(SUCCEEDED、FAILED、または CANCELED)であるため、キャンセルできません。
  • Name
    404 - Not Found
    Description

    この ID の Keycap タスクがあなたのアカウントに属していないか、タスクのステージがパスと一致していません。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)としてストリーミングします。パスはタスクのステージと一致している必要があります。一致しない場合、例えばbuildタスクのIDを/prototype/:id/streamに指定した場合、ストリームはstatus_code: 404を持つerrorイベントを1つ送信してクローズします。

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 Filtering がタスクの結果をブロックする場合、ストリームはその代わりに、getリクエストが返すであろうstatus_codeを持つerrorイベントを1つ送信します。


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

Keycapタスクの一覧取得

1つのステージのKeycapタスクを、1回につき1ページ分返します。パスでステージを選択します。/prototype はprototypeタスクのみを返し、/build は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

    1ページあたりのタスク数。最大 100。101 から 255 の値は100件のタスクを返し、0 はデフォルト値を使用します。0 から 255 の範囲外の値は 400 を返します。

  • Name
    sort_by
    Type
    string
    デフォルト -created_at
    Description

    ソート順。

    利用可能な値:

    • -created_at: 新しい順
    • +created_at: 古い順

戻り値

パス内のステージに一致する、prototypeタスクオブジェクト または buildタスクオブジェクト の配列。


Keycapプロトタイプタスクオブジェクト

プロトタイプタスクは、写真から完成したキーキャップの画像を1枚生成します。デザインを3Dのキーキャップに変換するには、タスクのIDを input_task_id として、そしてその candidate_ids のエントリを candidate_id として、buildエンドポイントに渡します。

プロパティ

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ミリ秒)。finished_at の3日後、またはタスクが完了するまでは created_at の3日後です。APIの結果を無期限に保持するEnterpriseアカウントの場合、約100年後になります。アセット保持期間を参照してください。

  • Name
    preceding_tasks
    Type
    integer
    Description

    タスクが PENDING の間のキュー内での位置。1 は次に開始することを意味します。タスクがキューを離れると 0 になり、リスト結果では常に 0 です。

  • Name
    task_error
    Type
    object
    Description

    タスクが失敗した理由。status が FAILED でない限り null です。エラーを参照してください。

  • Name
    consumed_credits
    Type
    integer
    Description

    タスクに対して請求されたクレジット数(返金後)。エラーを返すリクエストには課金されません。失敗したタスクはMeshyが返金するため 0 になります。キャンセルによる返金は、タスクが PENDING の間のみ行われます。Meshyが課金情報を読み取れない場合、getまたはstreamのレスポンスではこのフィールドが省略され、listリクエストは 500 を返します。その場合はリクエストを再試行してください。

  • Name
    image_urls
    Type
    array of strings
    Description

    完成したキーキャップの画像のダウンロードURL。タスクが成功すると配列にはURLが1つ含まれ、それまでは空です。image_urls[i] は candidate_ids[i] の候補を示します。

    これらのURLは表示用です。buildエンドポイントはURLではなく candidate_ids のエントリを受け取ります。これらは署名付きURLのため、Authorization ヘッダーなしで取得してください。expires_at まで有効であり、タスクを再度取得しても同じURLが返されます。

  • Name
    candidate_ids
    Type
    array of strings
    Description

    候補のID。image_urls と同じ順序です。候補をビルドするには、そのIDをbuildリクエストの candidate_id として送信してください。これらのIDのフォーマットに依存しないでください。


Keycapビルドタスクオブジェクト

ビルドタスクは、成功したプロトタイプタスクとそのキャンディダートの1つから、テクスチャ付きの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ミリ秒)。finished_at の3日後、またはタスクが完了するまでは created_at の3日後です。APIの結果を無期限に保持するEnterpriseアカウントの場合、約100年後になります。アセット保持期間を参照してください。

  • Name
    preceding_tasks
    Type
    integer
    Description

    タスクが PENDING の間のキュー内での位置。1 は次に開始することを意味します。タスクがキューを離れた後は 0 になり、リスト結果では常に 0 です。

  • Name
    task_error
    Type
    object
    Description

    タスクが失敗した理由。status が FAILED でない限り null です。エラーを参照してください。

  • Name
    consumed_credits
    Type
    integer
    Description

    返金分を差し引いた後に、タスクに対して請求されたクレジット数。エラーを返すリクエストには課金されません。失敗したタスクはMeshyが返金するため 0 です。キャンセルによる返金は、タスクが PENDING の間のみ行われます。Meshyが課金額を読み取れない場合、getまたはstreamのレスポンスではこのフィールドが省略され、listリクエストでは 500 が返されます。その場合は、リクエストを再試行してください。

  • Name
    model_urls
    Type
    object
    Description

    3Dモデルのダウンロード用URLです。Meshyは、GLBファイルとOBJバンドルを、ミリメートル単位の実寸スケールで、Y-up、キーキャップの正面が+Z方向を向くようにエクスポートします。

    モデルには keycap-head と keycap-base という名前のメッシュがあります。Meshyがベースのパターン塗りつぶしにフォールバックした場合、モデルにはステム空洞用の keycap-base-interior メッシュも含まれます。モデルに必ず2つのメッシュしかないとは想定しないでください。

    これらは署名付きURLのため、Authorization ヘッダーなしで取得してください。expires_at まで有効であり、それまでにタスクを再取得すると同じURLが返されます。期限切れのURLは更新できないため、それより前にファイルをダウンロードして保存してください。

    • Name
      glb
      Type
      string
      Description

      テクスチャ付きGLBファイル model.glb のダウンロード用URL。

    • Name
      obj_zip
      Type
      string
      Description

      OBJバンドルのダウンロード用URL。model.obj、model.mtl、および model.mtl が使用するPNGテクスチャを含むZIPファイルです。単色のベースの場合、テクスチャは 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がキーを追加する場合があるため、認識できないキーは無視してください。


エンドツーエンドの例

この例では、一連のフローをすべて実行します。

  1. 写真からプロトタイプタスクを作成する。
  2. タスクの status が SUCCEEDED になるまで取得する。
  3. candidate_ids から候補を1つ選ぶ。
  4. その候補を使ってビルドタスクを作成する。
  5. ビルドタスクの status が SUCCEEDED になるまで取得する。
  6. model_urls から GLB ファイルと OBJ バンドルをダウンロードする。

この例では最初の候補を選んでいます。実際のアプリでは、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"