Creative Lab — Keycap API

Trasforma una foto sorgente in un keycap personalizzato per tastiera meccanica a colori in due fasi: prototipo genera un rendering del design del "keycap finito" dalla tua foto di input. Una volta confermato quel rendering, costruzione lo trasforma in un modello 3D del keycap con texture in un'unica esecuzione — generazione del modello bianco, posizionamento e taglio automatici su una posa predefinita calibrata, colorazione del modello completo e assemblaggio finale avvengono tutti all'interno di un'unica attività di costruzione. Le due fasi sono collegate tramite input_task_id più candidate_id.

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

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

Crea un'attività di prototipo di Keycap

Genera un render del design del keycap finito dalla foto sorgente. Il risultato dell'attività contiene un array image_urls (il render di visualizzazione del keycap finito) e un array parallelo candidate_ids; entrambi contengono una singola voce. Chiama di nuovo questo endpoint per un altro render se il risultato non è quello che desideri — ogni chiamata è fatturata separatamente. Passa il candidate_id insieme all'ID dell'attività di prototipo all'endpoint di build. Consulta L'oggetto dell'attività di prototipo di Keycap per la forma della risposta.

Parametri

  • Name
    image_url
    Type
    string
    Obbligatorio
    Description

    Foto sorgente per Meshy da trasformare in immagini di design del keycap. Attualmente supportiamo i formati .jpg, .jpeg, .png e .webp.

    Il formato è rilevato decodificando i dati dell'immagine, non dall'estensione del file dell'URL — un URL senza estensione, o uno che reindirizza, funziona finché i byte decodificano in un formato supportato. I reindirizzamenti HTTP sono seguiti. L'orientamento EXIF è normalizzato, quindi una foto ruotata del telefono viene utilizzata come appare.

    Limiti: almeno 32 pixel su ciascun lato, al massimo 178,956,970 pixel in totale e al massimo 20,000,000 byte una volta scaricati. Per un Data URI il limite si applica ai byte decodificati, quindi il file sorgente stesso può essere fino a quella dimensione — è il testo base64 che è circa un terzo più grande, il che conta per il corpo della tua richiesta, non per questo limite. Un Data URI deve dichiarare un tipo di contenuto image/* e ;base64.

    Ci sono due modi per fornire l'immagine:

    • URL accessibile pubblicamente: Un URL accessibile da internet pubblica.
    • Data URI: Un Data URI codificato in base64 dell'immagine. Esempio di un Data URI: data:image/jpeg;base64,<your base64-encoded image data>.
  • Name
    name
    Type
    string
    Description

    Nome dell'attività opzionale per scopi di visualizzazione. Massimo 100 caratteri.

  • Name
    remove_background
    Type
    boolean
    predefinito false
    Description

    Quando impostato su true, il render di visualizzazione restituito in image_urls è un PNG RGBA trasparente con lo sfondo rimosso, così puoi comporlo su qualsiasi sfondo.

    Questo si applica solo al render di visualizzazione. Il candidato che l'endpoint di build consuma non è influenzato, quindi il risultato 3D è identico in entrambi i casi.

Restituisce

La proprietà result della risposta contiene l'id dell'attività del prototipo di keycap appena creato. Interroga l'endpoint Ottieni un'attività o iscriviti al flusso fino a quando l'attività raggiunge SUCCEEDED, quindi prendi la voce da candidate_ids e passala, insieme all'ID dell'attività, all'endpoint di build.

Modalità di fallimento

  • Name
    400 - Bad Request
    Description

    La richiesta non era accettabile. Cause comuni:

    • Parametro mancante: image_url è richiesto.
    • Formato immagine non valido: L'image_url fornito non è un formato supportato (.jpg, .jpeg, .png, .webp).
    • Dimensioni immagine fuori intervallo: L'immagine è troppo piccola, supera la dimensione massima del file o supera il conteggio massimo dei pixel.
    • URL irraggiungibile: L'image_url non può essere scaricato (404 o timeout).
    • Data URI non valido: La stringa base64 è malformata.
    • Contenuto segnalato: L'immagine di input è stata segnalata dalla moderation NSFW.
  • Name
    401 - Unauthorized
    Description

    Autenticazione fallita. Si prega di controllare la tua chiave API.

  • Name
    402 - Payment Required
    Description

    L'account è sul piano gratuito (è richiesto un piano a pagamento per creare attività) o non ha crediti sufficienti.

  • Name
    403 - Forbidden
    Description

    L'immagine di input è stata segnalata dalla moderation della proprietà intellettuale.

  • Name
    429 - Too Many Requests
    Description

    Hai superato il tuo limite di frequenza.

  • Name
    500 - Internal Server Error
    Description

    Si è verificato un errore imprevisto lato server — ad esempio il servizio di moderation dei contenuti non era disponibile, la messa in scena dell'immagine di input è fallita, o l'attività non può essere creata. In questo caso non viene creata alcuna attività, quindi riprovare è sicuro.

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

Crea un Task di Costruzione Keycap

Genera il modello 3D finale del keycap texturizzato da un task di prototipo riuscito e uno dei suoi candidati. Un singolo task di costruzione esegue l'intera pipeline dall'inizio alla fine — generazione del modello bianco dal design scelto, posizionamento e taglio automatico sulla base del keycap utilizzando una posa predefinita calibrata (non è necessario alcun aggiustamento interattivo), colorazione del modello completo, e assemblaggio finale ed esportazione. Una costruzione tipicamente richiede 3–7 minuti, verso l'estremità superiore quando diversi task di costruzione vengono eseguiti contemporaneamente. Consulta L'oggetto Task di Costruzione Keycap per la forma della risposta.

Parametri

  • Name
    input_task_id
    Type
    string
    Obbligatorio
    Description

    L'ID del task di un prototipo creato tramite questo stesso endpoint OpenAPI. Il prototipo deve essere stato creato dallo stesso account Meshy, deve aver raggiunto SUCCEEDED, e deve aver prodotto almeno un candidato.

    I task di prototipo creati tramite l'app web non sono accettati — l'endpoint di costruzione accetta solo task di prototipo prodotti da POST /openapi/creative-lab/keycap/v1/prototype e rifiuta qualsiasi altra fonte con 404.

  • Name
    candidate_id
    Type
    string
    Obbligatorio
    Description

    Il candidato da costruire, preso dall'array candidate_ids del task di prototipo riuscito. Deve appartenere a quel task; qualsiasi altro valore viene rifiutato con 400.

  • Name
    name
    Type
    string
    Description

    Nome del task opzionale per scopi di visualizzazione. Massimo 100 caratteri.

options

Regolazione opzionale della geometria. Ogni campo ha un valore predefinito calibrato — invia solo quelli che desideri sovrascrivere.

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

    La base del keycap su cui costruire. Attualmente l'unico valore disponibile è cherry-mx-1x1-r1 — un keycap standard Cherry MX profilo 1u. Sono pianificate 3–5 dimensioni standard principali aggiuntive; le dimensioni personalizzate non sono supportate.

  • Name
    head_size_mm
    Type
    number
    predefinito 23
    Description

    Dimensione target della testa scolpita, in millimetri: la sua dimensione più lunga è scalata a questo valore. Intervallo: [10, 40]. I valori superiori a circa 32.9 possono essere ridotti in modo che la testa rientri ancora nel limite dell'impronta protettiva della base, quindi la dimensione più lunga consegnata può essere inferiore a quella richiesta. Il valore applicato non viene restituito oggi sull'oggetto del task — se hai bisogno di confermare la dimensione effettivamente ricevuta, misura il bounding box della mesh keycap-head nel modello scaricato.

  • Name
    vertical_offset_mm
    Type
    number
    predefinito 0
    Description

    Offset verticale applicato alla testa prima che venga posizionata sulla base, in millimetri. Intervallo: [-5, 5].

Restituisce

La proprietà result della risposta contiene l'id del task del nuovo task di costruzione keycap creato. Interroga l'endpoint Ottieni un Task o iscriviti al stream fino a quando il task raggiunge SUCCEEDED, quindi scarica gli artefatti da model_urls.glb e model_urls.obj_zip.

Modalità di Fallimento

  • Name
    400 - Bad Request
    Description

    La richiesta non era accettabile. Cause comuni:

    • Parametro mancante: input_task_id e candidate_id sono richiesti.
    • UUID non valido: L'input_task_id non è un UUID valido.
    • Genitore non riuscito: Il task di prototipo di riferimento non ha ancora raggiunto SUCCEEDED.
    • Nessun candidato: Il task di prototipo è riuscito ma non ha prodotto candidati.
    • Candidato sconosciuto: candidate_id non è uno dei candidati del task di input.
    • Opzioni fuori intervallo: Uno dei campi options è caduto al di fuori del suo intervallo consentito o set di enumerazione.
  • Name
    401 - Unauthorized
    Description

    Autenticazione fallita. Si prega di controllare la tua chiave API.

  • Name
    402 - Payment Required
    Description

    L'account è sul piano gratuito (è richiesto un piano a pagamento per creare task) o ha crediti insufficienti.

  • Name
    404 - Not Found
    Description

    Il task di prototipo di riferimento non esiste, appartiene a un altro utente, o è stato creato tramite l'app web (solo i task di prototipo in modalità API si concatenano nella costruzione).

  • Name
    429 - Too Many Requests
    Description

    Hai superato il tuo limite di frequenza.

  • Name
    500 - Internal Server Error
    Description

    Si è verificato un errore inaspettato lato server — ad esempio il servizio di moderazione dei contenuti non era disponibile, la messa in scena dell'immagine di input è fallita, o il task non poteva essere creato. Nessun task viene creato in questo caso, quindi riprovare è sicuro.

Richiesta

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

Risposta

{
  "result": "019c9a52-7d18-7e2b-9f01-6e3b98c4d2af"
}

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

Recupera un Task Keycap

Recupera un task di prototipo o build dato un valido id del task. Il percorso URL deve corrispondere alla fase del task — un task di build recuperato tramite /prototype/:id restituisce 404, e viceversa.

Consulta L'Oggetto Task Prototipo Keycap e L'Oggetto Task Build Keycap per le forme di risposta.

Parametri

  • Name
    id
    Type
    path
    Description

    Identificatore univoco per il task keycap da recuperare.

Restituisce

La risposta contiene l'oggetto task keycap. La forma dipende da quale fase è stata richiesta.

Richiesta

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

Risposta Prototipo

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

Risposta Build

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

Elimina un'attività Keycap

Annulla un'attività keycap. Se l'attività è ancora PENDING, i crediti consumati al momento della creazione vengono rimborsati. Le attività che sono già IN_PROGRESS vengono annullate senza rimborso (il lavoratore potrebbe già essere in fase di utilizzo delle risorse). Le attività che hanno già raggiunto uno stato terminale (SUCCEEDED, FAILED, CANCELED) non possono essere annullate.

Il percorso URL deve corrispondere alla fase dell'attività — DELETE su /prototype/:buildId restituisce 404.

Parametri del Percorso

  • Name
    id
    Type
    path
    Description

    Identificatore univoco per l'attività keycap da annullare.

Restituisce

Restituisce 204 No Content in caso di successo con un corpo vuoto.

Modalità di Fallimento

  • Name
    400 - Bad Request
    Description

    L'attività è già in uno stato terminale e non può essere annullata.

  • Name
    404 - Not Found
    Description

    L'attività non esiste, appartiene a un altro utente o la sua fase non corrisponde al percorso URL.

  • Name
    500 - Internal Server Error
    Description

    Si è verificato un errore imprevisto lato server durante l'annullamento. L'attività potrebbe essere stata o meno annullata — rileggila per confermare prima di riprovare.

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

Trasmetti un Task Keycap

Trasmetti aggiornamenti in tempo reale per un task keycap tramite Server-Sent Events (SSE). Il percorso URL deve corrispondere alla fase del task — aprire uno stream su /prototype/:buildId/stream emette un singolo event: error payload con status_code: 404 e chiude lo stream.

Parametri

  • Name
    id
    Type
    path
    Description

    Identificatore univoco per il task keycap da trasmettere.

Restituisce

Restituisce uno stream di oggetti task Keycap Prototype o Keycap Build come Server-Sent Events. Per i task PENDING o IN_PROGRESS, il flusso di risposta includerà solo i campi necessari progress e status.

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

Elenco delle Attività Keycap

Recupera un elenco paginato delle tue attività keycap per una singola fase. Il percorso URL seleziona la fase — /prototype restituisce le attività di prototipo; /build restituisce le attività di costruzione. Le attività dell'altra fase non sono incluse in nessuna delle risposte.

Parametri del Percorso

  • Name
    stage
    Type
    path
    Obbligatorio
    Description

    O prototype o build. La raccolta restituisce solo le attività la cui fase corrisponde all'URL — il recupero di /prototype non restituisce mai attività di costruzione e viceversa.

Parametri di Query

  • Name
    page_num
    Type
    integer
    predefinito 1
    Description

    Numero di pagina per la paginazione.

  • Name
    page_size
    Type
    integer
    predefinito 10
    Description

    Limite della dimensione della pagina. Il massimo consentito è di 100 elementi.

  • Name
    sort_by
    Type
    string
    predefinito -created_at
    Description

    Campo per l'ordinamento. Valori disponibili:

    • +created_at: Ordina per tempo di creazione in ordine crescente.
    • -created_at: Ordina per tempo di creazione in ordine decrescente.

Restituisce

Restituisce un elenco paginato dell'oggetto attività per fase — o l'oggetto attività prototipo keycap quando si elenca /prototype o l'oggetto attività di costruzione keycap quando si elenca /build.

Richiesta

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

Risposta (Elenco Attività Prototipo)

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

L'oggetto Task Prototipo Keycap

L'oggetto Task Prototipo Keycap è un'unità di lavoro che Meshy tiene traccia per generare un'immagine di design del keycap finito da una foto sorgente. L'output di questa fase è collegato alla fase di costruzione tramite input_task_id più candidate_id.

Proprietà

  • Name
    id
    Type
    string
    Description

    Identificatore univoco per il task. Anche se utilizziamo un UUID ordinabile per k per gli id dei task come dettaglio di implementazione, non dovresti fare alcuna assunzione sul formato dell'id.

  • Name
    type
    Type
    string
    Description

    Tipo di task. Il valore è creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    Il nome del task fornito quando il task è stato creato. Stringa vuota se non è stato fornito alcun nome.

  • Name
    status
    Type
    string
    Description

    Stato del task. I valori possibili sono uno di PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Avanzamento del task. Se il task non è ancora iniziato, questa proprietà sarà 0. Una volta che il task è riuscito, questo diventerà 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato creato, in millisecondi.

  • Name
    started_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato avviato, in millisecondi. Se il task non è ancora iniziato, questa proprietà sarà 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato completato, in millisecondi. Se il task non è ancora completato, questa proprietà sarà 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Timestamp di quando il risultato del task scade, in millisecondi.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Il conteggio dei task precedenti.

  • Name
    task_error
    Type
    object
    Description

    Dettagli dell'errore per i task falliti. Vedi Errori per il riferimento completo all'oggetto task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    Il numero di crediti consumati da questo task. Un task che raggiunge SUCCEEDED viene addebitato l'intero importo per la sua fase. Un task che non viene mai creato (un 4xx al momento della richiesta, inclusa una moderazione rifiutata) non viene addebitato affatto. Un task che raggiunge FAILED restituisce 0 — l'addebito viene rimborsato, inclusa una moderazione asincrona bloccata. La cancellazione tramite DELETE rimborsa solo mentre il task è ancora PENDING; un task già IN_PROGRESS rimane addebitato, perché il lavoro è stato speso.

  • Name
    image_urls
    Type
    array of strings
    Description

    URL scaricabile del rendering del design del keycap finito — come appare il candidato come keycap finito. Contiene una sola voce; image_urls[i] corrisponde a candidate_ids[i]. Vuoto fino a quando il task non raggiunge SUCCEEDED. L'URL è solo per la visualizzazione; l'endpoint di costruzione consuma candidate_ids, non questi URL. Stesso ciclo di vita degli URL di model_urls: firmato, senza intestazione Authorization, valido fino a expires_at, e stabile quando il task viene riletto.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Identificatori opachi dei candidati, paralleli a image_urls. Passa la voce che corrisponde al design scelto come candidate_id della richiesta di costruzione. Non fare alcuna assunzione sul formato di questi id.

Esempio di Oggetto Task Prototipo Keycap

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

L'oggetto Task di Costruzione Keycap

L'oggetto Task di Costruzione Keycap è un'unità di lavoro che Meshy tiene traccia per generare il keycap 3D finale con texture da un task prototipo riuscito e un candidato scelto. Una singola costruzione esegue l'intera pipeline — generazione del modello bianco, posizionamento e taglio automatico, colorazione, assemblaggio ed esportazione.

Proprietà

  • Name
    id
    Type
    string
    Description

    Identificatore univoco per il task.

  • Name
    type
    Type
    string
    Description

    Tipo di task. Il valore è creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    Il nome del task fornito quando il task è stato creato. Stringa vuota se non è stato fornito alcun nome.

  • Name
    status
    Type
    string
    Description

    Stato del task. I valori possibili sono uno di PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Avanzamento del task. Se il task non è ancora iniziato, questa proprietà sarà 0. Una volta che il task è riuscito, questo diventerà 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato creato, in millisecondi.

  • Name
    started_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato avviato, in millisecondi.

  • Name
    finished_at
    Type
    timestamp
    Description

    Timestamp di quando il task è stato completato, in millisecondi.

  • Name
    expires_at
    Type
    timestamp
    Description

    Timestamp di quando il risultato del task scade, in millisecondi.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Il conteggio dei task precedenti. Significativo solo quando lo stato è PENDING.

  • Name
    task_error
    Type
    object
    Description

    Dettagli degli errori per i task falliti. Vedi Errori per il riferimento completo all'oggetto task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    Il numero di crediti consumati da questo task. Un task che raggiunge SUCCEEDED viene addebitato l'intero importo per la sua fase. Un task che non viene mai creato (un 4xx al momento della richiesta, inclusa una moderazione rifiutata) non viene addebitato affatto. Un task che raggiunge FAILED restituisce 0 — l'addebito viene rimborsato, inclusa una moderazione asincrona bloccata. La cancellazione tramite DELETE rimborsa solo mentre il task è ancora PENDING; un task già IN_PROGRESS rimane addebitato, perché il lavoro è stato speso.

  • Name
    model_urls
    Type
    object
    Description

    URL scaricabili per gli artefatti del modello generato. Sia il pacchetto GLB che quello OBJ sono esportati a scala millimetrica reale, Y-up, con la parte anteriore del keycap rivolta verso +Z. I mesh sono denominati keycap-head e keycap-base; quando la base ricade su un riempimento a motivo, è presente anche un terzo mesh keycap-base-interior per la cavità dello stelo. Non assumere esattamente due mesh.

    Questi sono URL firmati: recuperali senza un'intestazione Authorization. Rimangono validi fino a expires_at, che è 3 giorni dopo finished_at, e rileggendo il task all'interno di quella finestra restituisce l'URL identico piuttosto che uno appena firmato. Scarica e archivia i file prima di allora — non c'è modo di aggiornare un link scaduto.

    • Name
      glb
      Type
      string
      Description

      URL scaricabile per il model.glb finale con texture.

    • Name
      obj_zip
      Type
      string
      Description

      URL scaricabile per un pacchetto zip contenente model.obj, model.mtl, e i PNG delle texture a cui il suo MTL fa effettivamente riferimento. Una base a colore solido spedisce solo keycap-head.png; una base a motivo spedisce anche keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    URL scaricabili per le immagini di processo intermedie, indicizzate per tipo. Stesso ciclo di vita degli URL come model_urls: firmati, nessuna intestazione Authorization, validi fino a expires_at, e stabili quando il task viene riletto. Tipi attualmente emessi:

    • head_design — l'immagine del design del candidato scelto che la costruzione ha consumato (sempre presente).
    • composite — il render di visualizzazione del keycap finito del candidato scelto (presente quando disponibile).
    • base_canvas — la tela della base del keycap dipinta (presente quando disponibile).

    Tratta il set di chiavi come aperto; nuovi tipi possono essere aggiunti senza una modifica di rottura.

Esempio di Oggetto Task di Costruzione 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=***"
  }
}

Esempio End-to-End

Il flusso completo: crea un prototipo da una foto, controlla che sia SUCCEEDED, scegli un candidato da candidate_ids, crea una build con quel candidato, controlla che la build sia SUCCEEDED, quindi scarica il GLB e il pacchetto OBJ da model_urls.

L'esempio sceglie il primo candidato in modo programmatico. In una vera integrazione, mostreresti l'elemento image_urls all'utente finale e lasceresti che scelga; l'indice scelto mappa 1:1 su candidate_ids.

Flusso completo

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"