lowpoly wird am 30.10.2026 abgeschaltet. Wechseln Sie vor diesen Terminen das Modell, um Fehler bei Anfragen zu vermeiden. Alle Abkündigungen ansehen

Creative Lab Keycap API

Verwandeln Sie ein Foto in zwei Schritten in eine vollfarbige, individuelle Keycap für eine mechanische Tastatur. Ein Prototyp-Task erzeugt aus dem Foto ein Bild der fertigen Keycap. Ein Build-Task verwandelt dieses Bild in ein texturiertes 3D-Keycap-Modell. Dabei wird die ID des Prototyp-Tasks als input_task_id und die Kandidaten-ID des Bildes als candidate_id verwendet.

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

Beide POST-endpoints erfordern einen kostenpflichtigen Plan. Eine Anfrage von einem Konto mit kostenlosem Plan gibt 402 zurück.


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

Erstellen einer Keycap-Prototyp-Aufgabe

Generiert aus einem Foto ein Bild des fertigen Keycaps. Das Feld image_urls der Aufgabe enthält das Bild, und candidate_ids enthält dessen ID, jeweils mit einem Eintrag. Wenn Ihnen das Design nicht gefällt, erstellen Sie eine weitere Prototyp-Aufgabe. Meshy berechnet jede Prototyp-Aufgabe separat.

Um den 3D-Keycap zu erstellen, übergeben Sie die ID dieser Aufgabe an den Build-Endpunkt als input_task_id, mit dem Eintrag aus candidate_ids als candidate_id. Die Felder der Aufgabe finden Sie unter Das Keycap-Prototyp-Aufgabenobjekt.

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

Parameter

  • Name
    image_url
    Type
    string
    Erforderlich
    Description

    Das Foto, das in ein Keycap-Design umgewandelt werden soll, als öffentliche URL oder als Data URI (data:image/jpeg;base64,<Ihre base64-kodierten Bilddaten>).

    Das Bild muss eine JPG-, JPEG-, PNG- oder WebP-Datei von maximal 20 MB (20.000.000 Byte) sein. Jede Seite muss mindestens 32 Pixel groß sein, und das Bild darf insgesamt höchstens 178.956.970 Pixel haben. Ein Bild außerhalb dieser Grenzen liefert 400 zurück.

    Meshy erkennt das Format anhand der Bilddaten, nicht anhand der Dateiendung in der URL. Eine URL ohne Dateiendung funktioniert, und Meshy folgt HTTP-Weiterleitungen. Meshy wendet die EXIF-Ausrichtung an, sodass ein gedrehtes Handyfoto so herauskommt, wie es aussieht.

    Eine Data URI muss base64-kodiert sein und einen Bildtyp angeben, wie zum Beispiel data:image/png;base64,..., und das dekodierte Bild muss JPEG, PNG oder WebP sein. Das Limit von 20 MB gilt für das dekodierte Bild, sodass der base64-Text etwa ein Drittel größer sein kann.

  • Name
    name
    Type
    string
    Description

    Ein Name für die Aufgabe, bis zu 100 Zeichen. Er wird im Feld name der Aufgabe zurückgegeben. Ein längerer Name liefert 400 zurück.

  • Name
    remove_background
    Type
    boolean
    Standard false
    Description

    Ob der Hintergrund aus dem Prototyp-Bild entfernt werden soll. true liefert ein transparentes RGBA-PNG zurück, sodass Sie den Keycap vor jedem beliebigen Hintergrund platzieren können. Wenn Meshy den Hintergrund nicht entfernen kann, wird das Bild mit seinem Hintergrund zurückgegeben, und die Aufgabe ist trotzdem erfolgreich.

    Das Kopfdesign, das der Build in 3D umwandelt, behält seinen Hintergrund in jedem Fall. Der Build bemalt die Keycap-Basis anhand des Bildes in image_urls, ohne dessen Hintergrund, falls Sie true gesendet haben. Der Build gibt dieses Bild als process_image_urls.composite zurück.

Rückgabewerte

Das Feld result enthält die ID der neuen Prototyp-Aufgabe. Rufen Sie die Aufgabe ab oder streamen Sie sie, bis status den Wert SUCCEEDED hat. Übergeben Sie dann die ID an den Build-Endpunkt als input_task_id, mit dem Eintrag aus candidate_ids als candidate_id.

Fehlermodi

  • Name
    400 - Bad Request
    Description

    Die Anfrage kann nicht ausgeführt werden. Zum Beispiel:

    • image_url fehlt.
    • Das Bild ist keine JPG-, JPEG-, PNG- oder WebP-Datei.
    • Das Bild ist zu klein, größer als 20 MB oder überschreitet die maximale Pixelanzahl.
    • Meshy kann das Bild nicht herunterladen, zum Beispiel weil die URL 404 zurückgibt oder eine Zeitüberschreitung auftritt.
    • Die Data URI ist kein gültiges base64.
    • Das Bild wurde als NSFW eingestuft.

    Die Fehlermeldung gibt an, welches Problem gefunden wurde. Beheben Sie die Anfrage und senden Sie sie erneut.

  • Name
    401 - Unauthorized
    Description

    Der API-Schlüssel fehlt oder ist ungültig. Überprüfen Sie den Authorization-Header.

  • Name
    402 - Payment Required
    Description

    Einer der folgenden Fälle trifft zu:

    • Das Konto verfügt nicht über genügend Credits.
    • Der API-Schlüssel, der Arbeitsbereich oder das Mitglied hat das Credit-Limit erreicht.
    • Das Konto nutzt den kostenlosen Plan.

    Überprüfen Sie Ihre Credits und Ihren Plan, und versuchen Sie es erneut.

  • Name
    403 - Forbidden
    Description

    Ihr Team hat IP-Filterung aktiviert, und Meshy hat das Bild wegen geistigen Eigentums Dritter markiert. Senden Sie ein Bild, für das Sie die Nutzungsrechte besitzen.

  • Name
    429 - Too Many Requests
    Description

    Eines dieser Limits wurde erreicht:

    • Sie haben mehr Anfragen gesendet, als Ihre Ratenbegrenzung erlaubt. Warten Sie einige Sekunden und versuchen Sie es erneut. Siehe Ratenbegrenzungen.
    • Zu viele Ihrer Aufgaben sind in der Warteschlange oder werden gerade ausgeführt. Warten Sie, bis einige abgeschlossen sind, und versuchen Sie es erneut.
    • Bei einem unbegrenzten Plan ohne verbleibende Credits haben Sie die Anzahl der Aufgaben erreicht, die ohne Credits laufen können. Warten Sie, bis eine Aufgabe abgeschlossen ist, oder fügen Sie Credits hinzu.
  • Name
    500 - Internal Server Error
    Description

    Bei Meshy ist ein Serverfehler aufgetreten, zum Beispiel weil die Inhaltsmoderation oder die Prüfung des geistigen Eigentums nicht ausgeführt werden konnte oder Meshy das Bild nicht speichern konnte. Meshy erstellt die Aufgabe nicht und erstattet alle dafür berechneten Credits zurück. Versuchen Sie die Anfrage erneut.


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

Einen Keycap-Build-Task erstellen

Generiert die texturierte 3D-Keycap aus einem erfolgreichen Prototyp-Task und einem seiner Kandidaten. Die Felder finden Sie unter Das Keycap-Build-Task-Objekt.

Ein Build-Task durchläuft jeden Schritt. Er erzeugt ein 3D-Modell aus dem Design und koloriert es. Anschließend setzt und schneidet er das Modell in einer kalibrierten Standardpose auf die Keycap-Basis, sodass Sie es nicht von Hand anpassen müssen. Zuletzt setzt er die Keycap zusammen und exportiert die Dateien. Ein Build dauert in der Regel 3 bis 7 Minuten.

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

Parameter

  • Name
    input_task_id
    Type
    string
    Erforderlich
    Description

    Die ID des zu bauenden Prototyp-Tasks. Sie muss zu einem Task gehören, den Ihr Konto mit POST /openapi/creative-lab/keycap/v1/prototype erstellt hat, mit dem Status SUCCEEDED.

    Eine ID, die keinem Ihrer Keycap-Prototyp-Tasks aus der API entspricht, liefert 404, einschließlich eines in der Web-App erstellten Prototyps.

  • Name
    candidate_id
    Type
    string
    Erforderlich
    Description

    Der zu bauende Kandidat, aus dem candidate_ids-Array des Prototyp-Tasks. Ein Wert, der nicht in diesem Array enthalten ist, liefert 400.

  • Name
    name
    Type
    string
    Description

    Ein Name für den Task, bis zu 100 Zeichen. Er wird im name-Feld des Tasks zurückgegeben. Ein längerer Name liefert 400.

options

Optionale Geometrie-Einstellungen. Jedes Feld hat einen kalibrierten Standardwert, senden Sie also nur die Felder, die Sie ändern möchten.

  • Name
    base_model
    Type
    string
    Standard cherry-mx-1x1-r1
    Description

    Die Keycap-Basis, auf der gebaut werden soll. Der einzige Wert ist cherry-mx-1x1-r1, eine Standard-Cherry-MX-Profil-1u-Keycap. Benutzerdefinierte Größen werden nicht unterstützt, und jeder andere Wert liefert 400.

  • Name
    head_size_mm
    Type
    number
    Standard 23
    Description

    Die Größe des Kopfes entlang seiner längsten Abmessung, in Millimetern, von 10 bis 40. Meshy skaliert den Kopf so, dass seine längste Abmessung diesem Wert entspricht. Ein Wert außerhalb des Bereichs liefert 400.

    Bei einem Wert über etwa 32.9 reduziert Meshy möglicherweise die Größe, damit der Kopf in die Schutz-Grundfläche der Basis passt. Der Kopf kann dann kleiner ausfallen, als Sie angefordert haben. Das Task-Objekt gibt die von Meshy angewandte Größe nicht zurück. Um sie zu prüfen, messen Sie den Begrenzungsrahmen des keycap-head-Netzes im Modell.

  • Name
    vertical_offset_mm
    Type
    number
    Standard 0
    Description

    Der vertikale Versatz, der auf den Kopf angewendet wird, bevor Meshy ihn auf der Basis platziert, in Millimetern, von -5 bis 5. Ein Wert außerhalb des Bereichs liefert 400.

Rückgabewerte

Das result-Feld enthält die ID des neuen Build-Tasks. Rufen Sie den Task ab oder streamen Sie ihn, bis status den Wert SUCCEEDED hat. Laden Sie dann die GLB-Datei von model_urls.glb und das OBJ-Bundle von model_urls.obj_zip herunter.

Fehlerfälle

  • Name
    400 - Bad Request
    Description

    Die Anfrage kann nicht ausgeführt werden. Zum Beispiel:

    • input_task_id fehlt oder ist keine gültige Task-ID.
    • Der Status des Prototyp-Tasks ist nicht SUCCEEDED. Wenn er noch läuft, warten Sie und versuchen Sie es erneut. Wenn er fehlgeschlagen oder abgebrochen wurde, erstellen Sie einen neuen Prototyp-Task.
    • Der Prototyp-Task war erfolgreich, hat aber keine Kandidaten. Erstellen Sie einen neuen Prototyp-Task.
    • candidate_id fehlt oder ist nicht in den candidate_ids des Prototyp-Tasks enthalten. Senden Sie einen Wert aus diesem Array.
    • Ein Feld in options liegt außerhalb des gültigen Bereichs, oder base_model ist kein verfügbarer Wert.

    Die Fehlermeldung gibt an, welches Problem gefunden wurde.

  • Name
    401 - Unauthorized
    Description

    Der API-Schlüssel fehlt oder ist ungültig. Überprüfen Sie den Authorization-Header.

  • Name
    402 - Payment Required
    Description

    Einer dieser Fälle trifft zu:

    • Das Konto verfügt nicht über genügend Credits.
    • Der API-Schlüssel, Arbeitsbereich oder das Mitglied hat sein Credit-Limit erreicht.
    • Das Konto nutzt den kostenlosen Plan.

    Prüfen Sie Ihre Credits und Ihren Plan und versuchen Sie es erneut.

  • Name
    404 - Not Found
    Description

    input_task_id entspricht keinem Keycap-Prototyp-Task, den Ihr Konto über die API erstellt hat. Ein in der Web-App erstellter Prototyp liefert ebenfalls 404. Senden Sie die result-ID aus einer Prototyp-Erstellungsantwort.

  • Name
    429 - Too Many Requests
    Description

    Eines dieser Limits wurde erreicht:

    • Sie haben mehr Anfragen gesendet, als Ihre Ratenbegrenzung zulässt. Warten Sie einige Sekunden und versuchen Sie es erneut. Siehe Ratenbegrenzungen.
    • Zu viele Ihrer Tasks sind in der Warteschlange oder laufen bereits. Warten Sie, bis einige abgeschlossen sind, und versuchen Sie es erneut.
    • Bei einem unbegrenzten Plan ohne verbleibende Credits haben Sie die Anzahl der Tasks erreicht, die ohne Credits laufen können. Warten Sie, bis ein Task abgeschlossen ist, oder fügen Sie Credits hinzu.
  • Name
    500 - Internal Server Error
    Description

    Meshy konnte den Task aufgrund eines Serverfehlers nicht erstellen. Meshy erstattet alle berechneten Credits zurück. Versuchen Sie die Anfrage erneut.


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

Einen Keycap-Task abrufen

Gibt einen Prototype- oder Build-Task zurück. Der Pfad muss zur Stage des Tasks passen. Ein über /prototype/:id angeforderter Build-Task gibt 404 zurück, ebenso ein über /build/:id angeforderter Prototype-Task.

Die Felder finden Sie unter Das Keycap-Prototype-Task-Objekt und Das Keycap-Build-Task-Objekt.

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

Parameter

  • Name
    id
    Type
    path
    Description

    Die Task-ID aus der Create-Antwort.

Rückgabe

Das Prototype-Task-Objekt oder das Build-Task-Objekt, passend zur Stage im Pfad.

Fehlerfälle

  • Name
    400 - Bad Request
    Description

    id ist keine gültige Task-ID. Senden Sie die result-ID aus der Create-Antwort.

  • Name
    403 - Forbidden
    Description

    Ihr Team hat IP Filtering aktiviert, und Meshy hat das Bild des Prototype-Tasks wegen geistigen Eigentums Dritter markiert. Build-Tasks und Teams im Enterprise-Plan erhalten diesen Fehler nicht. Erstellen Sie einen Prototype-Task mit einem Bild, an dem Sie die Nutzungsrechte besitzen.

  • Name
    404 - Not Found
    Description

    Es gehört kein Keycap-Task mit dieser ID zu Ihrem Konto, oder die Stage des Tasks stimmt nicht mit dem Pfad überein. Prüfen Sie die ID und verwenden Sie /prototype oder /build passend zum Task.

  • Name
    500 - Internal Server Error
    Description

    Meshy konnte die Prüfung auf geistiges Eigentum nicht durchführen. Wiederholen Sie die Anfrage.


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

Einen Keycap-Task löschen

Bricht einen Keycap-Task ab. Das Abbrechen eines PENDING-Tasks erstattet dessen Credits zurück. Ein IN_PROGRESS-Task wird ohne Rückerstattung abgebrochen, da bereits ein Worker damit begonnen hat. Ein Task mit einem finalen Status (SUCCEEDED, FAILED oder CANCELED) kann nicht abgebrochen werden.

Der Pfad muss zur Stufe des Tasks passen. Zum Beispiel liefert DELETE auf /prototype/:id mit der ID eines Build-Tasks 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).

Pfadparameter

  • Name
    id
    Type
    path
    Description

    Die ID des abzubrechenden Tasks.

Rückgabewerte

204 No Content mit leerem Body.

Fehlerfälle

  • Name
    400 - Bad Request
    Description

    Einer der folgenden Fälle trifft zu:

    • id ist keine gültige Task-ID. Senden Sie die result-ID aus der Erstellungsantwort.
    • Der Task hat bereits einen finalen Status (SUCCEEDED, FAILED oder CANCELED) und kann daher nicht abgebrochen werden.
  • Name
    404 - Not Found
    Description

    Es gehört kein Keycap-Task mit dieser ID zu Ihrem Konto, oder die Stufe des Tasks stimmt nicht mit dem Pfad überein. Überprüfen Sie die ID und verwenden Sie /prototype oder /build, um den Task zuzuordnen.

  • Name
    500 - Internal Server Error
    Description

    Bei Meshy ist beim Abbrechen des Tasks ein Serverfehler aufgetreten, sodass der Task möglicherweise abgebrochen wurde oder auch nicht. Rufen Sie den Task ab, um dessen status zu prüfen, bevor Sie es erneut versuchen.


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

Einen Keycap-Task streamen

Streamt die Updates eines Keycap-Tasks als Server-Sent Events (SSE). Der Pfad muss zur Stufe des Tasks passen. Falls nicht, zum Beispiel die ID eines Build-Tasks unter /prototype/:id/stream, sendet der Stream ein einzelnes error-Event mit status_code: 404 und wird geschlossen.

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

Parameter

  • Name
    id
    Type
    path
    Description

    Die Task-ID aus der Erstellungsantwort.

Rückgabe

Ein Stream von Prototype- oder Build-Task-Objekten. Jedes Event enthält das vollständige Task-Objekt, so wie es Einen Keycap-Task abrufen zurückgibt. Solange der Task PENDING oder IN_PROGRESS ist, sind seine Ausgabefelder noch leer (null, [] oder {}), und finished_at ist null.

Falls IP Filtering das Ergebnis des Tasks blockiert, sendet der Stream stattdessen ein einzelnes error-Event mit dem status_code, den eine Get-Anfrage zurückgeben würde.


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

Keycap-Tasks auflisten

Gibt Ihre Keycap-Tasks einer Stufe zurück, eine Seite nach der anderen. Der Pfad bestimmt die Stufe. /prototype gibt nur Prototyp-Tasks zurück, und /build gibt nur Build-Tasks zurück.

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

Pfadparameter

  • Name
    stage
    Type
    path
    Erforderlich
    Description

    Die aufzulistende Stufe, prototype oder build.

Abfrageparameter

  • Name
    page_num
    Type
    integer
    Standard 1
    Description

    Die zurückzugebende Seite, von 1 bis 255. 0 gibt die erste Seite zurück. Ein Wert außerhalb von 0 bis 255 gibt 400 zurück.

  • Name
    page_size
    Type
    integer
    Standard 10
    Description

    Anzahl der Tasks pro Seite, bis zu 100. Ein Wert von 101 bis 255 gibt 100 Tasks zurück, und 0 verwendet den Standardwert. Ein Wert außerhalb von 0 bis 255 gibt 400 zurück.

  • Name
    sort_by
    Type
    string
    Standard -created_at
    Description

    Die Sortierreihenfolge.

    Verfügbare Werte:

    • -created_at: neueste zuerst
    • +created_at: älteste zuerst

Rückgabewerte

Ein Array von Prototyp-Task-Objekten oder Build-Task-Objekten, passend zur Stufe im Pfad.


Das Keycap-Prototype-Task-Objekt

Ein Prototype-Task erzeugt ein Bild des fertigen Keycaps aus einem Foto. Um das Design in einen 3D-Keycap zu verwandeln, übergeben Sie die ID des Tasks an den Build-Endpunkt als input_task_id, mit dem zugehörigen Eintrag aus candidate_ids als candidate_id.

Eigenschaften

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

    Die Task-ID. Verlassen Sie sich nicht auf ihr Format.

  • Name
    type
    Type
    string
    Description

    Der Task-Typ, immer creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    Der name, den Sie beim Erstellen des Tasks gesendet haben, oder "", wenn Sie keinen gesendet haben.

  • Name
    status
    Type
    string
    Description

    Der Status des Tasks.

    Verfügbare Werte:

    • PENDING: wartet in der Warteschlange
    • IN_PROGRESS: Ergebnis wird generiert
    • SUCCEEDED: final, mit Ergebnis
    • FAILED: final, mit dem Grund in task_error
    • CANCELED: final, ohne Ergebnis
  • Name
    progress
    Type
    integer
    Description

    Prozentsatz der erledigten Arbeit, von 0 bis 100. Der Wert ist 0, bis der Task beginnt, und 100, wenn er erfolgreich ist.

  • Name
    created_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem der Task erstellt wurde, in Unix-Millisekunden.

  • Name
    started_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem ein Worker den Task gestartet hat, in Unix-Millisekunden. Bis dahin null.

  • Name
    finished_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem der Task einen finalen Status erreicht hat, in Unix-Millisekunden. Bis dahin null.

  • Name
    expires_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem das Ergebnis des Tasks abläuft, in Unix-Millisekunden. Das ist 3 Tage nach finished_at, oder 3 Tage nach created_at, solange der Task noch nicht abgeschlossen ist. Für Enterprise-Konten, die API-Ergebnisse unbegrenzt aufbewahren, liegt dieser Zeitpunkt etwa 100 Jahre später. Siehe Aufbewahrung von Assets.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Die Position des Tasks in der Warteschlange, solange er PENDING ist. 1 bedeutet, dass er als Nächstes startet. 0, nachdem der Task die Warteschlange verlassen hat, und in Listenergebnissen immer 0.

  • Name
    task_error
    Type
    object
    Description

    Warum der Task fehlgeschlagen ist. null, es sei denn, status ist FAILED. Siehe Fehler.

  • Name
    consumed_credits
    Type
    integer
    Description

    Anzahl der für den Task berechneten Credits, nach einer eventuellen Rückerstattung. Eine Anfrage, die einen Fehler zurückgibt, wird nicht berechnet. Ein fehlgeschlagener Task hat den Wert 0, da Meshy ihn erstattet. Ein Abbruch erstattet einen Task nur, solange er PENDING ist. Wenn Meshy die Belastung nicht auslesen kann, lässt eine Get- oder Stream-Antwort das Feld weg, und eine Listenanfrage gibt 500 zurück. Wiederholen Sie die Anfrage in diesem Fall.

  • Name
    image_urls
    Type
    array of strings
    Description

    Download-URLs für das Bild des fertigen Keycaps. Das Array enthält eine URL, nachdem der Task erfolgreich war, und ist bis dahin leer. image_urls[i] zeigt den Kandidaten aus candidate_ids[i].

    Diese URLs dienen der Anzeige. Der Build-Endpunkt erwartet einen Eintrag aus candidate_ids, keine URL. Es handelt sich um signierte URLs, rufen Sie sie daher ohne Authorization-Header ab. Sie bleiben bis expires_at gültig, und ein erneutes Abrufen des Tasks liefert dieselben URLs.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    IDs der Kandidaten, in derselben Reihenfolge wie image_urls. Um einen Kandidaten zu bauen, senden Sie dessen ID als candidate_id in der Build-Anfrage. Verlassen Sie sich nicht auf das Format dieser IDs.


Das Keycap-Build-Task-Objekt

Ein Build-Task generiert die texturierte 3D-Keycap aus einem erfolgreichen Prototype-Task und einem seiner Kandidaten. Er generiert das 3D-Modell, färbt es ein, setzt es ein und schneidet es auf die Keycap-Basis zu, und fügt die Keycap dann zusammen und exportiert sie.

Properties

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

    Die Task-ID. Verlassen Sie sich nicht auf ihr Format.

  • Name
    type
    Type
    string
    Description

    Der Task-Typ, immer creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    Der name, den Sie beim Erstellen des Tasks gesendet haben, oder "", wenn Sie keinen gesendet haben.

  • Name
    status
    Type
    string
    Description

    Der Status des Tasks.

    Verfügbare Werte:

    • PENDING: wartet in der Warteschlange
    • IN_PROGRESS: generiert das Ergebnis
    • SUCCEEDED: final, mit dem Ergebnis
    • FAILED: final, mit dem Grund in task_error
    • CANCELED: final, ohne Ergebnis
  • Name
    progress
    Type
    integer
    Description

    Prozentsatz der erledigten Arbeit, von 0 bis 100. Er ist 0, bis der Task startet, und 100, wenn er erfolgreich ist.

  • Name
    created_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem der Task erstellt wurde, in Unix-Millisekunden.

  • Name
    started_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem ein Worker den Task gestartet hat, in Unix-Millisekunden. Bis dahin null.

  • Name
    finished_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem der Task einen finalen Status erreicht hat, in Unix-Millisekunden. Bis dahin null.

  • Name
    expires_at
    Type
    timestamp
    Description

    Zeitpunkt, zu dem das Ergebnis des Tasks abläuft, in Unix-Millisekunden. Das ist 3 Tage nach finished_at, oder 3 Tage nach created_at, bis der Task abgeschlossen ist. Bei Enterprise-Konten, die API-Ergebnisse unbegrenzt aufbewahren, liegt er etwa 100 Jahre später. Siehe Aufbewahrung von Assets.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Die Position des Tasks in der Warteschlange, solange er PENDING ist. 1 bedeutet, dass er als Nächstes startet. 0, nachdem der Task die Warteschlange verlassen hat, und immer 0 in Listenergebnissen.

  • Name
    task_error
    Type
    object
    Description

    Warum der Task fehlgeschlagen ist. null, es sei denn, status ist FAILED. Siehe Fehler.

  • Name
    consumed_credits
    Type
    integer
    Description

    Anzahl der für den Task berechneten Credits, nach einer eventuellen Rückerstattung. Eine Anfrage, die einen Fehler zurückgibt, wird nicht berechnet. Ein fehlgeschlagener Task hat 0, da Meshy ihn zurückerstattet. Ein Abbruch erstattet einen Task nur, solange er PENDING ist. Wenn Meshy die Belastung nicht auslesen kann, lässt eine Get- oder Stream-Antwort das Feld weg, und eine Listenanfrage gibt 500 zurück. In diesem Fall wiederholen Sie die Anfrage.

  • Name
    model_urls
    Type
    object
    Description

    Download-URLs für das 3D-Modell. Meshy exportiert die GLB-Datei und das OBJ-Bundle im Maßstab 1:1 in Millimetern, Y-up, wobei die Vorderseite der Keycap in Richtung +Z zeigt.

    Das Modell hat Netze mit den Namen keycap-head und keycap-base. Wenn Meshy auf eine Musterfüllung für die Basis zurückgreift, hat das Modell außerdem ein keycap-base-interior-Netz für den Stößel-Hohlraum. Gehen Sie nicht davon aus, dass das Modell genau zwei Netze hat.

    Dies sind signierte URLs, rufen Sie sie also ohne einen Authorization-Header ab. Sie bleiben bis expires_at gültig, und ein erneutes Abrufen des Tasks davor liefert dieselben URLs zurück. Eine abgelaufene URL kann nicht erneuert werden, laden Sie die Dateien also vorher herunter und speichern Sie sie.

    • Name
      glb
      Type
      string
      Description

      Download-URL für die texturierte GLB-Datei, model.glb.

    • Name
      obj_zip
      Type
      string
      Description

      Download-URL für das OBJ-Bundle, eine ZIP-Datei mit model.obj, model.mtl und den PNG-Texturen, die model.mtl verwendet. Bei einer einfarbigen Basis ist keycap-head.png die einzige Textur. Bei einer gemusterten Basis enthält die ZIP-Datei außerdem keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    Download-URLs für Bilder aus den Schritten des Builds, nach Art indiziert. Wie bei model_urls handelt es sich um signierte URLs, rufen Sie sie also ohne einen Authorization-Header ab. Sie bleiben bis expires_at gültig, und ein erneutes Abrufen des Tasks liefert dieselben URLs zurück.

    Es kann folgende Schlüssel enthalten:

    • head_design: das Designbild des gewählten Kandidaten, das der Build in 3D umgewandelt hat. Immer vorhanden.
    • composite: das Bild der fertigen Keycap für den gewählten Kandidaten, aus dem der Build die Basis bemalt hat. Kann fehlen.
    • base_canvas: die bemalte Keycap-Basis. Kann fehlen.

    Meshy kann Schlüssel hinzufügen, ignorieren Sie also einen Schlüssel, den Sie nicht erkennen.


End-to-end example

Das Beispiel führt den gesamten Ablauf aus:

  1. Erstellen einer Prototype-Aufgabe aus einem Foto.
  2. Abrufen der Aufgabe, bis ihr status gleich SUCCEEDED ist.
  3. Auswahl eines Kandidaten aus candidate_ids.
  4. Erstellen einer Build-Aufgabe mit diesem Kandidaten.
  5. Abrufen der Build-Aufgabe, bis ihr status gleich SUCCEEDED ist.
  6. Herunterladen der GLB-Datei und des OBJ-Pakets aus model_urls.

Das Beispiel wählt den ersten Kandidaten aus. Zeigen Sie in Ihrer App die Einträge von image_urls Ihren Nutzern an und lassen Sie sie auswählen. Der Index eines ausgewählten Bildes in image_urls ist der Index seiner ID in 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"