Creative Lab — API de Keycap

Transforme uma fotografia de origem numa keycap de teclado mecânico personalizada, a cores, em duas etapas: prototype gera uma renderização de design de "keycap acabada" a partir da sua fotografia de entrada. Depois de confirmar essa renderização, build transforma-a num modelo 3D de keycap texturizado numa única execução — geração do modelo branco, assentamento e corte automáticos numa pose predefinida calibrada, coloração completa do modelo e montagem final acontecem tudo dentro de uma única tarefa de construção. As duas etapas são associadas através de input_task_id mais candidate_id.

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

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

Criar uma Tarefa de Protótipo de Keycap

Gera uma renderização de design de keycap finalizada a partir da foto de origem. O resultado da tarefa contém um array image_urls (a renderização de exibição do keycap finalizado) e um array paralelo candidate_ids; ambos contêm uma única entrada. Chame este endpoint novamente para obter outra renderização se o resultado não for o que pretende — cada chamada é faturada separadamente. Passe o candidate_id juntamente com o ID da tarefa de protótipo para o endpoint de build. Consulte O Objeto de Tarefa de Protótipo de Keycap para saber o formato da resposta.

Parâmetros

  • Name
    image_url
    Type
    string
    Obrigatório
    Description

    Foto de origem para o Meshy transformar em imagens de design de keycap. Atualmente, suportamos os formatos .jpg, .jpeg, .png e .webp.

    O formato é detetado através da descodificação dos dados da imagem, não a partir da extensão de ficheiro do URL — um URL sem extensão, ou que redirecione, funciona desde que os bytes sejam descodificados para um formato suportado. Os redirecionamentos HTTP são seguidos. A orientação EXIF é normalizada, pelo que uma foto de telemóvel rodada é utilizada tal como é apresentada visualmente.

    Limites: pelo menos 32 pixels em cada lado, no máximo 178.956.970 pixels no total, e no máximo 20.000.000 bytes após a transferência. Para um Data URI, o limite aplica-se aos bytes descodificados, pelo que o ficheiro de origem em si pode ter até esse tamanho — é o texto base64 que fica cerca de um terço maior, o que é relevante para o corpo do seu pedido, não para este limite. Um Data URI deve declarar um tipo de conteúdo image/* e ;base64.

    Existem duas formas de fornecer a imagem:

    • URL publicamente acessível: Um URL que seja acessível a partir da internet pública.
    • Data URI: Um Data URI da imagem codificado em base64. Exemplo de um Data URI: data:image/jpeg;base64,<os seus dados de imagem codificados em base64>.
  • Name
    name
    Type
    string
    Description

    Nome opcional da tarefa para fins de apresentação. Máximo de 100 carateres.

  • Name
    remove_background
    Type
    boolean
    predefinição false
    Description

    Quando definido como true, a renderização de exibição devolvida em image_urls é um PNG RGBA transparente com o fundo removido, para que possa compô-la sobre qualquer fundo.

    Isto aplica-se apenas à renderização de exibição. O candidato consumido pelo endpoint de build não é afetado, pelo que o resultado 3D é idêntico em ambos os casos.

Retorno

A propriedade result da resposta contém o id da tarefa da nova tarefa de protótipo de keycap criada. Consulte periodicamente o endpoint Obter uma Tarefa ou subscreva o stream até a tarefa atingir o estado SUCCEEDED e, em seguida, obtenha a entrada de candidate_ids e passe-a, juntamente com o ID da tarefa, para o endpoint de build.

Modos de Falha

  • Name
    400 - Bad Request
    Description

    O pedido era inaceitável. Causas comuns:

    • Parâmetro em falta: image_url é obrigatório.
    • Formato de imagem inválido: O image_url fornecido não está num formato suportado (.jpg, .jpeg, .png, .webp).
    • Dimensões da imagem fora do intervalo permitido: A imagem é demasiado pequena, excede o tamanho máximo de ficheiro ou excede o número máximo de pixels.
    • URL inacessível: Não foi possível transferir o image_url (404 ou timeout).
    • Data URI inválido: A cadeia base64 está mal formada.
    • Conteúdo assinalado: A imagem fornecida foi assinalada pela moderation de conteúdo impróprio (NSFW).
  • Name
    401 - Unauthorized
    Description

    A autenticação falhou. Verifique a sua chave de API.

  • Name
    402 - Payment Required
    Description

    A conta está no plano gratuito (é necessário um plano pago para criar tarefas) ou não tem créditos suficientes.

  • Name
    403 - Forbidden
    Description

    A imagem fornecida foi assinalada pela moderation de propriedade intelectual.

  • Name
    429 - Too Many Requests
    Description

    Excedeu o seu limite de taxa.

  • Name
    500 - Internal Server Error
    Description

    Ocorreu um erro inesperado do lado do servidor — por exemplo, o serviço de moderation de conteúdo estava indisponível, o carregamento da imagem de entrada falhou, ou não foi possível criar a tarefa. Neste caso, nenhuma tarefa é criada, pelo que é seguro tentar novamente.

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

Criar uma Tarefa de Construção de Keycap

Gera o modelo 3D de keycap com textura final a partir de uma tarefa de protótipo bem-sucedida e um dos seus candidatos. Uma única tarefa de construção executa todo o pipeline de ponta a ponta — geração do modelo em branco a partir do design escolhido, assentamento e corte automáticos na base da keycap usando uma pose predefinida calibrada (sem necessidade de ajuste interativo), coloração do modelo completo, e montagem e exportação finais. Uma construção demora normalmente 3 a 7 minutos, aproximando-se do limite superior quando várias construções são executadas em simultâneo. Consulte O Objeto de Tarefa de Construção de Keycap para conhecer o formato da resposta.

Parâmetros

  • Name
    input_task_id
    Type
    string
    Obrigatório
    Description

    O ID da tarefa de uma tarefa de protótipo criada através deste mesmo endpoint OpenAPI. O protótipo deve ter sido criado pela mesma conta Meshy, deve ter atingido SUCCEEDED e deve ter produzido pelo menos um candidato.

    Tarefas de protótipo criadas através da webapp não são aceites — o endpoint de construção aceita apenas tarefas de protótipo produzidas por POST /openapi/creative-lab/keycap/v1/prototype e recusa qualquer outra origem com 404.

  • Name
    candidate_id
    Type
    string
    Obrigatório
    Description

    O candidato a construir, retirado do array candidate_ids da tarefa de protótipo bem-sucedida. Deve pertencer a essa tarefa; qualquer outro valor é rejeitado com 400.

  • Name
    name
    Type
    string
    Description

    Nome opcional da tarefa para fins de apresentação. Máximo de 100 caracteres.

options

Ajuste opcional da geometria. Cada campo tem um valor predefinido calibrado — envie apenas os que pretende substituir.

  • Name
    base_model
    Type
    string
    predefinição cherry-mx-1x1-r1
    Description

    A base de keycap sobre a qual construir. Atualmente, o único valor disponível é cherry-mx-1x1-r1 — uma keycap padrão de perfil Cherry MX 1u. Estão planeadas 3–5 dimensões padrão adicionais habituais; tamanhos personalizados não são suportados.

  • Name
    head_size_mm
    Type
    number
    predefinição 23
    Description

    Tamanho alvo da cabeça esculpida, em milímetros: a sua dimensão mais longa é escalada para este valor. Intervalo: [10, 40]. Valores acima de aproximadamente 32.9 podem ser reduzidos para que a cabeça continue a caber no limite de área protegida da base, pelo que a dimensão mais longa entregue pode ser inferior à solicitada. O valor aplicado não é atualmente devolvido no objeto da tarefa — se precisar de confirmar o tamanho que realmente recebeu, meça a caixa delimitadora da malha keycap-head no modelo transferido.

  • Name
    vertical_offset_mm
    Type
    number
    predefinição 0
    Description

    Deslocamento vertical aplicado à cabeça antes de esta ser assente na base, em milímetros. Intervalo: [-5, 5].

Retornos

A propriedade result da resposta contém o id da tarefa da nova tarefa de construção de keycap criada. Faça polling ao endpoint Obter uma Tarefa ou subscreva o stream até a tarefa atingir SUCCEEDED e, em seguida, transfira os artefactos a partir de model_urls.glb e model_urls.obj_zip.

Modos de Falha

  • Name
    400 - Bad Request
    Description

    O pedido foi inaceitável. Causas comuns:

    • Parâmetro em falta: input_task_id e candidate_id são obrigatórios.
    • UUID inválido: O input_task_id não é um UUID válido.
    • Tarefa principal não concluída: A tarefa de protótipo referenciada ainda não atingiu SUCCEEDED.
    • Sem candidatos: A tarefa de protótipo foi bem-sucedida, mas não produziu candidatos.
    • Candidato desconhecido: candidate_id não é um dos candidatos da tarefa de entrada.
    • Opções fora do intervalo: Um dos campos de options encontrava-se fora do intervalo permitido ou do conjunto de valores enumerados.
  • Name
    401 - Unauthorized
    Description

    A autenticação falhou. Verifique a sua chave de API.

  • Name
    402 - Payment Required
    Description

    A conta está no plano gratuito (é necessário um plano pago para criar tarefas) ou não tem créditos suficientes.

  • Name
    404 - Not Found
    Description

    A tarefa de protótipo referenciada não existe, pertence a outro utilizador, ou foi criada através da webapp (apenas tarefas de protótipo em modo API podem encadear-se numa construção).

  • Name
    429 - Too Many Requests
    Description

    Excedeu o seu limite de taxa.

  • Name
    500 - Internal Server Error
    Description

    Ocorreu um erro inesperado do lado do servidor — por exemplo, o serviço de moderation estava indisponível, falhou a preparação da imagem de entrada, ou não foi possível criar a tarefa. Neste caso, não é criada nenhuma tarefa, pelo que é seguro tentar novamente.

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

Obter uma Tarefa de Keycap

Obtenha uma tarefa de protótipo ou de build indicando um id de tarefa válido. O caminho do URL tem de corresponder à fase da tarefa — uma tarefa de build obtida através de /prototype/:id devolve 404, e vice-versa.

Consulte O Objeto de Tarefa de Protótipo de Keycap e O Objeto de Tarefa de Build de Keycap para conhecer os formatos de resposta.

Parâmetros

  • Name
    id
    Type
    path
    Description

    Identificador único da tarefa de keycap a obter.

Devoluções

A resposta contém o objeto de tarefa de keycap. O formato depende da fase que foi pedida.

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

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

Eliminar uma Tarefa de Keycap

Cancela uma tarefa de keycap. Se a tarefa ainda estiver PENDING, os créditos consumidos no momento da criação são reembolsados. As tarefas que já estejam IN_PROGRESS são canceladas sem reembolso (o worker pode já estar a consumir recursos). As tarefas que já tenham atingido um estado terminal (SUCCEEDED, FAILED, CANCELED) não podem ser canceladas.

O caminho do URL deve corresponder ao estágio da tarefa — DELETE em /prototype/:buildId retorna 404.

Parâmetros de Caminho

  • Name
    id
    Type
    path
    Description

    Identificador único da tarefa de keycap a cancelar.

Retornos

Retorna 204 No Content em caso de sucesso, com um corpo vazio.

Modos de Falha

  • Name
    400 - Bad Request
    Description

    A tarefa já se encontra num estado terminal e não pode ser cancelada.

  • Name
    404 - Not Found
    Description

    A tarefa não existe, pertence a um utilizador diferente, ou o seu estágio não corresponde ao caminho do URL.

  • Name
    500 - Internal Server Error
    Description

    Ocorreu um erro inesperado do lado do servidor durante o cancelamento. A tarefa pode ou não ter sido cancelada — volte a lê-la para confirmar antes de tentar novamente.

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

Fazer Stream de uma Tarefa de Keycap

Faz stream de atualizações em tempo real para uma tarefa de keycap através de Server-Sent Events (SSE). O caminho do URL deve corresponder à fase da tarefa — abrir um stream em /prototype/:buildId/stream emite um único event: error payload com status_code: 404 e encerra o stream.

Parâmetros

  • Name
    id
    Type
    path
    Description

    Identificador único da tarefa de keycap para fazer stream.

Retorna

Retorna um stream de objetos de tarefa Keycap Prototype ou Keycap Build como Server-Sent Events. Cada frame contém o objeto de tarefa completo para a fase — a mesma forma que o endpoint Get devolve — pelo que, enquanto a tarefa está PENDING ou IN_PROGRESS, os campos de saída simplesmente ainda não estão preenchidos (null, [] ou {}) e finished_at é null.

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 PENDING frame below is abbreviated 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=***"
  }
}

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

Listar Tarefas Keycap

Obtenha uma lista paginada das suas tarefas keycap para um único estágio. O caminho do URL seleciona o estágio — /prototype devolve tarefas de protótipo; /build devolve tarefas de compilação. As tarefas do outro estágio não são incluídas em nenhuma das respostas.

Parâmetros de Caminho

  • Name
    stage
    Type
    path
    Obrigatório
    Description

    prototype ou build. A coleção devolve apenas tarefas cujo estágio corresponda ao URL — obter /prototype nunca devolve tarefas de compilação e vice-versa.

Parâmetros de Consulta

  • Name
    page_num
    Type
    integer
    predefinição 1
    Description

    Número da página para paginação.

  • Name
    page_size
    Type
    integer
    predefinição 10
    Description

    Limite de tamanho da página. O máximo permitido é 100 itens.

  • Name
    sort_by
    Type
    string
    predefinição -created_at
    Description

    Campo pelo qual ordenar. Valores disponíveis:

    • +created_at: Ordena por hora de criação em ordem ascendente.
    • -created_at: Ordena por hora de criação em ordem descendente.

Devolve

Devolve uma lista paginada do objeto de tarefa por estágio — ou o objeto de tarefa de protótipo keycap ao listar /prototype, ou o objeto de tarefa de compilação keycap ao listar /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"
    ]
  }
]

O Objeto de Tarefa de Protótipo de Keycap

O objeto de Tarefa de Protótipo de Keycap é uma unidade de trabalho que a Meshy monitoriza para gerar uma imagem de design de keycap finalizado a partir de uma fotografia de origem. O resultado desta etapa é encadeado na etapa de construção através de input_task_id mais candidate_id.

Propriedades

  • Name
    id
    Type
    string
    Description

    Identificador único da tarefa. Embora utilizemos um UUID k-sortable para os ids das tarefas como detalhe de implementação, não deve fazer quaisquer suposições sobre o formato do id.

  • Name
    type
    Type
    string
    Description

    Tipo da tarefa. O valor é creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    O nome da tarefa fornecido no momento da criação da tarefa. String vazia se não tiver sido fornecido nenhum nome.

  • Name
    status
    Type
    string
    Description

    Estado da tarefa. Os valores possíveis são um de PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Progress da tarefa. Se a tarefa ainda não tiver começado, esta propriedade será 0. Assim que a tarefa for concluída com sucesso, este valor passará a ser 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Carimbo de data/hora de quando a tarefa foi criada, em milissegundos.

  • Name
    started_at
    Type
    timestamp
    Description

    Carimbo de data/hora de quando a tarefa foi iniciada, em milissegundos. Se a tarefa ainda não tiver sido iniciada, esta propriedade será 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Carimbo de data/hora de quando a tarefa foi concluída, em milissegundos. Se a tarefa ainda não tiver sido concluída, esta propriedade será 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Carimbo de data/hora de quando o resultado da tarefa expira, em milissegundos.

  • Name
    preceding_tasks
    Type
    integer
    Description

    A contagem de tarefas precedentes.

  • Name
    task_error
    Type
    object
    Description

    Detalhes de erro para tarefas falhadas. Consulte Erros para a referência completa do objeto task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    O número de créditos consumidos por esta tarefa. Uma tarefa que atinge SUCCEEDED é cobrada na totalidade correspondente à sua etapa. Uma tarefa que nunca chega a ser criada (um 4xx no momento do pedido, incluindo uma rejeição por moderation) não é cobrada de todo. Uma tarefa que atinge FAILED devolve 0 — a cobrança é reembolsada, incluindo um bloqueio de moderation assíncrono. Cancelar através de DELETE só reembolsa enquanto a tarefa ainda estiver PENDING; uma tarefa já IN_PROGRESS mantém-se cobrada, porque o trabalho já foi despendido.

  • Name
    image_urls
    Type
    array of strings
    Description

    URL transferível da renderização do design de keycap finalizado — o aspeto que o candidato tem como keycap acabado. Contém uma única entrada; image_urls[i] corresponde a candidate_ids[i]. Vazio até a tarefa atingir SUCCEEDED. O URL destina-se apenas a exibição; o endpoint de construção consome candidate_ids, não estes URLs. O mesmo ciclo de vida de URL que model_urls: assinado, sem cabeçalho Authorization, válido até expires_at, e estável quando a tarefa é relida.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Identificadores opacos de candidatos, paralelos a image_urls. Passe a entrada correspondente ao design escolhido como o candidate_id do pedido de construção. Não faça quaisquer suposições sobre o formato destes ids.

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

O Objeto Keycap Build Task

O objeto Keycap Build Task é uma unidade de trabalho que a Meshy acompanha para gerar o keycap 3D texturizado final a partir de uma prototype task bem-sucedida e de um candidato escolhido. Uma única build executa o pipeline completo — geração do modelo branco, assentamento e corte automáticos, coloração, montagem e exportação.

Propriedades

  • Name
    id
    Type
    string
    Description

    Identificador único da tarefa.

  • Name
    type
    Type
    string
    Description

    Tipo da tarefa. O valor é creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    O nome da tarefa fornecido no momento da criação da tarefa. Cadeia vazia se não foi fornecido nenhum nome.

  • Name
    status
    Type
    string
    Description

    Estado da tarefa. Os valores possíveis são um de PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Progresso da tarefa. Se a tarefa ainda não tiver sido iniciada, esta propriedade será 0. Assim que a tarefa for bem-sucedida, este valor passará a ser 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Carimbo de data/hora da criação da tarefa, em milissegundos.

  • Name
    started_at
    Type
    timestamp
    Description

    Carimbo de data/hora do início da tarefa, em milissegundos.

  • Name
    finished_at
    Type
    timestamp
    Description

    Carimbo de data/hora da conclusão da tarefa, em milissegundos.

  • Name
    expires_at
    Type
    timestamp
    Description

    Carimbo de data/hora de expiração do resultado da tarefa, em milissegundos.

  • Name
    preceding_tasks
    Type
    integer
    Description

    O número de tarefas precedentes. Só é relevante quando o estado é PENDING.

  • Name
    task_error
    Type
    object
    Description

    Detalhes do erro para tarefas com falha. Consulte Erros para a referência completa do objeto task_error.

  • Name
    consumed_credits
    Type
    integer
    Description

    O número de créditos consumidos por esta tarefa. Uma tarefa que atinge SUCCEEDED é cobrada com o valor total correspondente à sua etapa. Uma tarefa que nunca chega a ser criada (um 4xx no momento do pedido, incluindo uma rejeição de moderation) não é cobrada de todo. Uma tarefa que atinge FAILED devolve 0 — o valor é reembolsado, incluindo um bloqueio de moderation assíncrono. O cancelamento via DELETE só reembolsa enquanto a tarefa ainda estiver PENDING; uma tarefa já IN_PROGRESS mantém-se cobrada, porque o trabalho já foi realizado.

  • Name
    model_urls
    Type
    object
    Description

    URLs transferíveis para os artefactos do modelo gerado. Tanto o GLB como o pacote OBJ são exportados à escala real em milímetros, com o eixo Y para cima, com a frente do keycap virada para +Z. As malhas têm o nome keycap-head e keycap-base; quando a base recorre a um preenchimento em padrão, está também presente uma terceira malha keycap-base-interior para a cavidade da haste. Não presuma que existem exatamente duas malhas.

    Estes são URLs assinados: obtenha-os sem um cabeçalho Authorization. Permanecem válidos até expires_at, que corresponde a 3 dias após finished_at, e reler a tarefa dentro desse período devolve o mesmo URL, e não um novo URL assinado. Transfira e guarde os ficheiros por si mesmo antes disso — não há forma de renovar uma ligação expirada.

    • Name
      glb
      Type
      string
      Description

      URL transferível para o model.glb texturizado final.

    • Name
      obj_zip
      Type
      string
      Description

      URL transferível para um pacote zip que contém model.obj, model.mtl, e os PNGs de textura que o respetivo MTL efetivamente referencia. Uma base de cor sólida inclui apenas keycap-head.png; uma base com padrão inclui também keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    URLs transferíveis para imagens intermédias do processo, organizadas por tipo. O mesmo ciclo de vida de URL que model_urls: assinados, sem cabeçalho Authorization, válidos até expires_at, e estáveis ao reler a tarefa. Tipos atualmente emitidos:

    • head_design — a imagem de design do candidato escolhido que a build consumiu (sempre presente).
    • composite — o render de apresentação do keycap finalizado do candidato escolhido (presente quando disponível).
    • base_canvas — a tela pintada da base do keycap (presente quando disponível).

    Considere o conjunto de chaves como aberto; podem ser adicionados novos tipos sem constituir uma alteração disruptiva.

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

Exemplo completo (ponta a ponta)

O fluxo completo: criar um protótipo a partir de uma fotografia, consultá-lo (poll) até SUCCEEDED, escolher um candidato a partir de candidate_ids, criar uma build com esse candidato, consultar (poll) a build até SUCCEEDED e depois transferir o GLB e o pacote OBJ a partir de model_urls.

O exemplo escolhe programaticamente o primeiro candidato. Numa integração real, mostraria a entrada image_urls ao utilizador final e deixaria-o escolher; o índice escolhido mapeia 1:1 para 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"