Creative Lab — Keycap API

Przekształć zdjęcie źródłowe w pełnokolorowy, niestandardowy klawisz mechanicznej klawiatury w dwóch etapach: prototyp generuje render projektu "gotowego klawisza" z Twojego zdjęcia wejściowego. Po potwierdzeniu tego renderu, budowa przekształca go w teksturowany model 3D klawisza w jednym przebiegu — generowanie modelu białego, automatyczne osadzanie i cięcie na skalibrowanej domyślnej pozycji, kolorowanie pełnego modelu i ostateczny montaż odbywają się w ramach jednego zadania budowy. Oba etapy są połączone za pomocą input_task_id oraz candidate_id.

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

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

Utwórz zadanie prototypu Keycap

Wygeneruj render projektu gotowego keycapu z oryginalnego zdjęcia. Wynik zadania zawiera tablicę image_urls (render wyświetlania gotowego keycapu) oraz równoległą tablicę candidate_ids; obie zawierają pojedynczy wpis. Wywołaj ten punkt końcowy ponownie dla innego renderu, jeśli wynik nie jest tym, czego oczekujesz — każde wywołanie jest rozliczane osobno. Przekaż candidate_id razem z identyfikatorem zadania prototypu do punktu końcowego budowy. Odnieś się do Obiektu zadania prototypu Keycap dla kształtu odpowiedzi.

Parametry

  • Name
    image_url
    Type
    string
    Wymagane
    Description

    Oryginalne zdjęcie, które Meshy przekształci w obrazy projektu keycapu. Obecnie obsługujemy formaty .jpg, .jpeg, .png i .webp.

    Format jest wykrywany przez dekodowanie danych obrazu, nie na podstawie rozszerzenia pliku URL — URL bez rozszerzenia lub taki, który przekierowuje, działa, o ile bajty dekodują się do obsługiwanego formatu. Przekierowania HTTP są śledzone. Orientacja EXIF jest normalizowana, więc obrócone zdjęcie z telefonu jest używane tak, jak wygląda.

    Limity: co najmniej 32 piksele z każdej strony, maksymalnie 178,956,970 pikseli w sumie i maksymalnie 20,000,000 bajtów po pobraniu. Dla Data URI limit dotyczy zdekodowanych bajtów, więc sam plik źródłowy może mieć do tej wielkości — jest to tekst base64, który jest około jednej trzeciej większy, co ma znaczenie dla treści żądania, a nie dla tego limitu. Data URI musi deklarować typ zawartości image/* i ;base64.

    Istnieją dwa sposoby dostarczenia obrazu:

    • Publicznie dostępny URL: URL, który jest dostępny z publicznego internetu.
    • Data URI: zakodowany w base64 Data URI obrazu. Przykład Data URI: data:image/jpeg;base64,<twoje dane obrazu zakodowane w base64>.
  • Name
    name
    Type
    string
    Description

    Opcjonalna nazwa zadania do celów wyświetlania. Maksymalnie 100 znaków.

  • Name
    remove_background
    Type
    boolean
    domyślne false
    Description

    Gdy ustawione na true, render wyświetlania zwrócony w image_urls jest przezroczystym RGBA PNG z usuniętym tłem, dzięki czemu można go skomponować na dowolnym tle.

    Dotyczy to tylko renderu wyświetlania. Kandydat konsumowany przez punkt końcowy budowy pozostaje niezmieniony, więc wynik 3D jest identyczny w obu przypadkach.

Zwraca

Właściwość result odpowiedzi zawiera identyfikator zadania id nowo utworzonego zadania prototypu keycapu. Sprawdź punkt końcowy Pobierz zadanie lub subskrybuj strumień aż zadanie osiągnie SUCCEEDED, a następnie weź wpis z candidate_ids i przekaż go, razem z identyfikatorem zadania, do punktu końcowego budowy.

Tryby awarii

  • Name
    400 - Bad Request
    Description

    Żądanie było nieakceptowalne. Typowe przyczyny:

    • Brakujący parametr: image_url jest wymagany.
    • Nieprawidłowy format obrazu: Podany image_url nie jest obsługiwanym formatem (.jpg, .jpeg, .png, .webp).
    • Wymiary obrazu poza zakresem: Obraz jest zbyt mały, przekracza maksymalny rozmiar pliku lub przekracza maksymalną liczbę pikseli.
    • Nieosiągalny URL: image_url nie mógł zostać pobrany (404 lub timeout).
    • Nieprawidłowy Data URI: Ciąg base64 jest niepoprawny.
    • Treść oznaczona: Obraz wejściowy został oznaczony przez moderation NSFW.
  • Name
    401 - Unauthorized
    Description

    Uwierzytelnianie nie powiodło się. Proszę sprawdzić swój klucz API.

  • Name
    402 - Payment Required
    Description

    Konto jest na darmowym planie (wymagany jest płatny plan do tworzenia zadań) lub nie ma wystarczających kredytów.

  • Name
    403 - Forbidden
    Description

    Obraz wejściowy został oznaczony przez moderation własności intelektualnej.

  • Name
    429 - Too Many Requests
    Description

    Przekroczyłeś swój limit szybkości.

  • Name
    500 - Internal Server Error
    Description

    Wystąpił nieoczekiwany błąd po stronie serwera — na przykład usługa moderation treści była niedostępna, przygotowanie obrazu wejściowego nie powiodło się lub zadanie nie mogło zostać utworzone. W takim przypadku nie jest tworzone żadne zadanie, więc ponowne próby są bezpieczne.

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

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

Utwórz zadanie budowy nakładki na klawisz

Wygeneruj ostateczny model 3D nakładki na klawisz z teksturą z zakończonego sukcesem zadania prototypowego i jednego z jego kandydatów. Pojedyncze zadanie budowy uruchamia cały proces od początku do końca — generowanie modelu białego z wybranego projektu, automatyczne osadzenie i wycięcie na podstawie nakładki przy użyciu skalibrowanej domyślnej pozy (bez potrzeby interaktywnej regulacji), kolorowanie pełnego modelu oraz ostateczny montaż i eksport. Budowa zazwyczaj trwa 3–7 minut, bliżej górnej granicy, gdy kilka budów jest uruchomionych jednocześnie. Odwołaj się do Obiekt zadania budowy nakładki na klawisz dla kształtu odpowiedzi.

Parametry

  • Name
    input_task_id
    Type
    string
    Wymagane
    Description

    Identyfikator zadania prototypowego utworzonego za pośrednictwem tego samego punktu końcowego OpenAPI. Prototyp musi być utworzony przez to samo konto Meshy, musi osiągnąć SUCCEEDED i musi wygenerować co najmniej jednego kandydata.

    Zadania prototypowe utworzone za pośrednictwem aplikacji webowej nie są akceptowane — punkt końcowy budowy akceptuje tylko zadania prototypowe wygenerowane przez POST /openapi/creative-lab/keycap/v1/prototype i odrzuca każde inne źródło z 404.

  • Name
    candidate_id
    Type
    string
    Wymagane
    Description

    Kandydat do budowy, wybrany z tablicy candidate_ids zakończonego sukcesem zadania prototypowego. Musi należeć do tego zadania; każda inna wartość jest odrzucana z 400.

  • Name
    name
    Type
    string
    Description

    Opcjonalna nazwa zadania do celów wyświetlania. Maksymalnie 100 znaków.

options

Opcjonalne dostrojenie geometrii. Każde pole ma skalibrowaną wartość domyślną — wysyłaj tylko te, które chcesz nadpisać.

  • Name
    base_model
    Type
    string
    domyślne cherry-mx-1x1-r1
    Description

    Podstawa nakładki, na której ma być zbudowana. Obecnie jedyną dostępną wartością jest cherry-mx-1x1-r1 — standardowy profil nakładki Cherry MX 1u. Planowane są 3–5 dodatkowych standardowych rozmiarów; niestandardowe rozmiary nie są obsługiwane.

  • Name
    head_size_mm
    Type
    number
    domyślne 23
    Description

    Docelowy rozmiar rzeźbionej głowy, w milimetrach: jej najdłuższy wymiar jest skalowany do tej wartości. Zakres: [10, 40]. Wartości powyżej około 32.9 mogą zostać zmniejszone, aby głowa nadal mieściła się w ograniczeniu ochronnej powierzchni podstawy, więc dostarczony najdłuższy wymiar może być mniejszy niż żądany. Zastosowana wartość nie jest obecnie zwracana w obiekcie zadania — jeśli potrzebujesz potwierdzić otrzymany rozmiar, zmierz prostopadłościan ograniczający siatki keycap-head w pobranym modelu.

  • Name
    vertical_offset_mm
    Type
    number
    domyślne 0
    Description

    Pionowe przesunięcie zastosowane do głowy przed jej osadzeniem na podstawie, w milimetrach. Zakres: [-5, 5].

Zwraca

Właściwość result odpowiedzi zawiera identyfikator zadania id nowo utworzonego zadania budowy nakładki na klawisz. Odpytywanie punktu końcowego Pobierz zadanie lub subskrybuj strumień aż zadanie osiągnie SUCCEEDED, a następnie pobierz artefakty z model_urls.glb i model_urls.obj_zip.

Tryby awarii

  • Name
    400 - Bad Request
    Description

    Żądanie było nieakceptowalne. Typowe przyczyny:

    • Brakujący parametr: input_task_id i candidate_id są wymagane.
    • Nieprawidłowy UUID: input_task_id nie jest prawidłowym UUID.
    • Rodzic nie zakończony sukcesem: Odwołane zadanie prototypowe nie osiągnęło jeszcze SUCCEEDED.
    • Brak kandydatów: Zadanie prototypowe zakończyło się sukcesem, ale nie wygenerowało żadnych kandydatów.
    • Nieznany kandydat: candidate_id nie jest jednym z kandydatów zadania wejściowego.
    • Opcje poza zakresem: Jedno z pól options wykraczało poza dozwolony zakres lub zestaw enum.
  • Name
    401 - Unauthorized
    Description

    Uwierzytelnianie nie powiodło się. Proszę sprawdzić swój klucz API.

  • Name
    402 - Payment Required
    Description

    Konto jest na darmowym planie (wymagany jest płatny plan do tworzenia zadań) lub ma niewystarczającą ilość kredytów.

  • Name
    404 - Not Found
    Description

    Odwołane zadanie prototypowe nie istnieje, należy do innego użytkownika lub zostało utworzone za pośrednictwem aplikacji webowej (tylko zadania prototypowe w trybie API łączą się w budowę).

  • Name
    429 - Too Many Requests
    Description

    Przekroczyłeś swój limit szybkości.

  • Name
    500 - Internal Server Error
    Description

    Wystąpił nieoczekiwany błąd po stronie serwera — na przykład usługa moderacji treści była niedostępna, nie udało się przygotować obrazu wejściowego lub nie można było utworzyć zadania. W takim przypadku nie jest tworzone żadne zadanie, więc ponowienie jest bezpieczne.

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

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

Pobierz zadanie Keycap

Pobierz zadanie prototypu lub budowy, podając prawidłowy id zadania. Ścieżka URL musi odpowiadać etapowi zadania — zadanie budowy pobrane przez /prototype/:id zwróci 404, i odwrotnie.

Odwołaj się do Obiektu zadania prototypu Keycap oraz Obiektu zadania budowy Keycap dla kształtów odpowiedzi.

Parametry

  • Name
    id
    Type
    path
    Description

    Unikalny identyfikator zadania keycap do pobrania.

Zwraca

Odpowiedź zawiera obiekt zadania keycap. Kształt zależy od tego, który etap został zażądany.

Żądanie

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

Odpowiedź prototypu

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

Odpowiedź budowy

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

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

Usuń zadanie Keycap

Anuluj zadanie keycap. Jeśli zadanie jest nadal PENDING, kredyty zużyte podczas tworzenia są zwracane. Zadania, które są już IN_PROGRESS, są anulowane bez zwrotu (pracownik może już zużywać zasoby). Zadania, które osiągnęły już stan końcowy (SUCCEEDED, FAILED, CANCELED) nie mogą być anulowane.

Ścieżka URL musi odpowiadać etapowi zadania — DELETE na /prototype/:buildId zwraca 404.

Parametry ścieżki

  • Name
    id
    Type
    path
    Description

    Unikalny identyfikator zadania keycap do anulowania.

Zwraca

Zwraca 204 No Content w przypadku sukcesu z pustym ciałem.

Tryby błędów

  • Name
    400 - Bad Request
    Description

    Zadanie jest już w stanie końcowym i nie może być anulowane.

  • Name
    404 - Not Found
    Description

    Zadanie nie istnieje, należy do innego użytkownika lub jego etap nie odpowiada ścieżce URL.

  • Name
    500 - Internal Server Error
    Description

    Wystąpił nieoczekiwany błąd po stronie serwera podczas anulowania. Zadanie mogło zostać anulowane lub nie — odczytaj je ponownie, aby potwierdzić przed ponowną próbą.

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).

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

Transmisja zadania Keycap

Transmituj aktualizacje w czasie rzeczywistym dla zadania keycap za pomocą Server-Sent Events (SSE). Ścieżka URL musi odpowiadać etapowi zadania — otwarcie transmisji na /prototype/:buildId/stream emituje pojedynczy ładunek event: error z status_code: 404 i zamyka transmisję.

Parametry

  • Name
    id
    Type
    path
    Description

    Unikalny identyfikator dla zadania keycap do transmisji.

Zwraca

Zwraca strumień obiektów zadań Keycap Prototype lub Keycap Build jako Server-Sent Events. Dla zadań PENDING lub IN_PROGRESS, strumień odpowiedzi będzie zawierał tylko niezbędne pola progress i status.

Żądanie

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

Strumień odpowiedzi

// 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.
// For PENDING or IN_PROGRESS tasks, the response stream will not include all fields.
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=***"
  }
}

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

Lista zadań Keycap

Pobierz stronicowaną listę swoich zadań keycap dla jednego etapu. Ścieżka URL wybiera etap — /prototype zwraca zadania prototypowe; /build zwraca zadania budowlane. Zadania z innego etapu nie są uwzględniane w żadnej z odpowiedzi.

Parametry ścieżki

  • Name
    stage
    Type
    path
    Wymagane
    Description

    Albo prototype, albo build. Kolekcja zwraca tylko zadania, których etap odpowiada ścieżce URL — pobieranie /prototype nigdy nie zwraca zadań budowlanych i odwrotnie.

Parametry zapytania

  • Name
    page_num
    Type
    integer
    domyślne 1
    Description

    Numer strony dla stronicowania.

  • Name
    page_size
    Type
    integer
    domyślne 10
    Description

    Limit rozmiaru strony. Maksymalnie dozwolone to 100 elementów.

  • Name
    sort_by
    Type
    string
    domyślne -created_at
    Description

    Pole do sortowania. Dostępne wartości:

    • +created_at: Sortuj według czasu utworzenia w porządku rosnącym.
    • -created_at: Sortuj według czasu utworzenia w porządku malejącym.

Zwraca

Zwraca stronicowaną listę obiektów zadań dla danego etapu — albo obiekt zadania prototypu keycap przy wylistowaniu /prototype, albo obiekt zadania budowy keycap przy wylistowaniu /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"
    ]
  }
]

Obiekt Zadania Prototypu Klawisza

Obiekt Zadania Prototypu Klawisza to jednostka pracy, którą Meshy śledzi, aby wygenerować jeden obraz projektu klawisza z zdjęcia źródłowego. Wynik tego etapu jest łączony z etapem budowy za pomocą input_task_id oraz candidate_id.

Właściwości

  • Name
    id
    Type
    string
    Description

    Unikalny identyfikator zadania. Chociaż używamy k-sortowalnego UUID dla identyfikatorów zadań jako szczegółu implementacji, nie powinieneś zakładać żadnych założeń dotyczących formatu tego identyfikatora.

  • Name
    type
    Type
    string
    Description

    Typ zadania. Wartość to creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    Nazwa zadania podana podczas tworzenia zadania. Pusty ciąg, jeśli nie podano nazwy.

  • Name
    status
    Type
    string
    Description

    Status zadania. Możliwe wartości to PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Postęp zadania. Jeśli zadanie jeszcze się nie rozpoczęło, ta właściwość będzie miała wartość 0. Gdy zadanie zakończy się sukcesem, wartość ta wyniesie 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Znacznik czasu utworzenia zadania, w milisekundach.

  • Name
    started_at
    Type
    timestamp
    Description

    Znacznik czasu rozpoczęcia zadania, w milisekundach. Jeśli zadanie jeszcze się nie rozpoczęło, ta właściwość będzie miała wartość 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Znacznik czasu zakończenia zadania, w milisekundach. Jeśli zadanie jeszcze się nie zakończyło, ta właściwość będzie miała wartość 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Znacznik czasu wygaśnięcia wyniku zadania, w milisekundach.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Liczba poprzedzających zadań.

  • Name
    task_error
    Type
    object
    Description

    Szczegóły błędu dla nieudanych zadań. Zobacz Błędy dla pełnej referencji obiektu task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    Liczba kredytów zużytych przez to zadanie. Zadanie, które osiąga SUCCEEDED, jest obciążane pełną kwotą za swój etap. Zadanie, które nigdy nie zostaje utworzone (błąd 4xx w czasie żądania, w tym odrzucenie moderacji) nie jest w ogóle obciążane. Zadanie, które osiąga FAILED, zwraca 0 — opłata jest zwracana, w tym asynchroniczny blok moderacji. Anulowanie za pomocą DELETE zwraca opłatę tylko wtedy, gdy zadanie jest jeszcze PENDING; zadanie już IN_PROGRESS pozostaje obciążone, ponieważ praca została wykonana.

  • Name
    image_urls
    Type
    array of strings
    Description

    Pobieralny URL renderu projektu klawisza — jak wygląda kandydat jako gotowy klawisz. Zawiera jeden wpis; image_urls[i] odpowiada candidate_ids[i]. Pusty, dopóki zadanie nie osiągnie SUCCEEDED. URL jest tylko do wyświetlania; punkt końcowy budowy zużywa candidate_ids, a nie te URL-e. Ten sam cykl życia URL jak model_urls: podpisany, bez nagłówka Authorization, ważny do expires_at i stabilny, gdy zadanie jest ponownie odczytywane.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Nieprzejrzyste identyfikatory kandydatów, równoległe do image_urls. Przekaż wpis odpowiadający wybranemu projektowi jako candidate_id w żądaniu budowy. Nie zakładaj żadnych założeń dotyczących formatu tych identyfikatorów.

Przykład Obiektu Zadania Prototypu Klawisza

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

Obiekt Zadania Budowy Keycap

Obiekt Zadania Budowy Keycap jest jednostką pracy, którą Meshy śledzi, aby wygenerować ostateczny teksturowany trójwymiarowy keycap z zakończonego sukcesem zadania prototypowego i wybranego kandydata. Pojedyncza budowa uruchamia pełny proces — generowanie modelu białego, automatyczne osadzanie i cięcie, kolorowanie, montaż i eksport.

Właściwości

  • Name
    id
    Type
    string
    Description

    Unikalny identyfikator zadania.

  • Name
    type
    Type
    string
    Description

    Typ zadania. Wartość to creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    Nazwa zadania podana podczas tworzenia zadania. Pusty ciąg znaków, jeśli nie podano nazwy.

  • Name
    status
    Type
    string
    Description

    Status zadania. Możliwe wartości to PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Postęp zadania. Jeśli zadanie jeszcze się nie rozpoczęło, ta właściwość będzie miała wartość 0. Po zakończeniu zadania sukcesem, wartość ta wyniesie 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Znacznik czasu utworzenia zadania, w milisekundach.

  • Name
    started_at
    Type
    timestamp
    Description

    Znacznik czasu rozpoczęcia zadania, w milisekundach.

  • Name
    finished_at
    Type
    timestamp
    Description

    Znacznik czasu zakończenia zadania, w milisekundach.

  • Name
    expires_at
    Type
    timestamp
    Description

    Znacznik czasu wygaśnięcia wyniku zadania, w milisekundach.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Liczba poprzedzających zadań. Znaczące tylko, gdy status to PENDING.

  • Name
    task_error
    Type
    object
    Description

    Szczegóły błędu dla nieudanych zadań. Zobacz Błędy dla pełnej referencji obiektu task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    Liczba kredytów zużytych przez to zadanie. Zadanie, które osiąga SUCCEEDED, jest obciążane pełną kwotą za swój etap. Zadanie, które nigdy nie zostaje utworzone (błąd 4xx w czasie żądania, w tym odrzucenie moderacji) nie jest w ogóle obciążane. Zadanie, które osiąga FAILED, zwraca 0 — opłata jest zwracana, w tym asynchroniczna blokada moderacji. Anulowanie za pomocą DELETE zwraca opłatę tylko wtedy, gdy zadanie jest nadal PENDING; zadanie już IN_PROGRESS pozostaje obciążone, ponieważ praca została wykonana.

  • Name
    model_urls
    Type
    object
    Description

    Pobieralne URL-e dla wygenerowanych artefaktów modelu. Zarówno pakiet GLB, jak i OBJ są eksportowane w rzeczywistej skali milimetrowej, Y-up, z przodem keycapu skierowanym na +Z. Siatki są nazwane keycap-head i keycap-base; gdy podstawa wraca do wypełnienia wzorem, obecna jest również trzecia siatka keycap-base-interior dla wnęki trzonu. Nie zakładaj dokładnie dwóch siatek.

    Są to podpisane URL-e: pobieraj je bez nagłówka Authorization. Pozostają ważne do expires_at, co jest 3 dni po finished_at, a ponowne odczytanie zadania w tym oknie zwraca identyczny URL zamiast nowo podpisanego. Pobierz i przechowaj pliki samodzielnie przed tym czasem — nie ma możliwości odświeżenia wygasłego linku.

    • Name
      glb
      Type
      string
      Description

      Pobieralny URL do ostatecznego teksturowanego model.glb.

    • Name
      obj_zip
      Type
      string
      Description

      Pobieralny URL do pakietu zip zawierającego model.obj, model.mtl i tekstury PNG, do których odnosi się jego MTL. Podstawa w jednolitym kolorze zawiera tylko keycap-head.png; podstawa wzorzysta zawiera również keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    Pobieralne URL-e dla pośrednich obrazów procesu, kluczowane według rodzaju. Taki sam cykl życia URL-i jak model_urls: podpisane, bez nagłówka Authorization, ważne do expires_at, i stabilne przy ponownym odczycie zadania. Obecnie emitowane rodzaje:

    • head_design — obraz projektu wybranego kandydata, który budowa zużyła (zawsze obecny).
    • composite — render wyświetlacza zakończonego keycapu wybranego kandydata (obecny, gdy dostępny).
    • base_canvas — pomalowane płótno podstawy keycapu (obecne, gdy dostępne).

    Traktuj zestaw kluczy jako otwarty; nowe rodzaje mogą być dodawane bez zmiany łamiącej.

Przykładowy Obiekt Zadania Budowy Keycap

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

Przykład End-to-End

Kompletny przepływ: utwórz prototyp ze zdjęcia, sprawdź jego status do SUCCEEDED, wybierz kandydata z candidate_ids, utwórz build z tym kandydatem, sprawdź status build do SUCCEEDED, a następnie pobierz pakiet GLB i OBJ z model_urls.

Przykład wybiera pierwszego kandydata programowo. W rzeczywistej integracji wyświetlisz wpis image_urls użytkownikowi końcowemu i pozwolisz mu wybrać; wybrany indeks mapuje się 1:1 na candidate_ids.

Kompletny przepływ

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"