Creative Lab — Keycap API

Förvandla ett källfoto till en fullfärgad anpassad mekanisk tangentbordstangent i två steg: prototyp genererar en "färdig tangent"-designrendering från ditt inmatningsfoto. När du har bekräftat den renderingen, bygg omvandlar den till en texturerad 3D-tangentmodell i en enda körning — vitmodellgenerering, automatisk placering och skärning i en kalibrerad standardposition, fullmodellfärgning och slutmontering sker alla inom en byggtask. De två stegen är länkade via input_task_id plus candidate_id.

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

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

Skapa en Keycap Prototypuppgift

Generera en färdig keycap-designrendering från källfotot. Uppgiftsresultatet innehåller en image_urls-array (visningsrenderingen av den färdiga keycapen) och en parallell candidate_ids-array; båda innehåller en enda post. Anropa denna endpoint igen för en annan rendering om resultatet inte är vad du vill ha — varje anrop debiteras separat. Skicka candidate_id tillsammans med prototypuppgiftens ID till bygg-endpointen. Se Keycap Prototypuppgiftsobjektet för svarformatet.

Parametrar

  • Name
    image_url
    Type
    string
    Obligatorisk
    Description

    Källfoto för Meshy att omvandla till keycap-designbilder. Vi stöder för närvarande formaten .jpg, .jpeg, .png och .webp.

    Formatet detekteras genom att avkoda bilddata, inte från URL:ens filändelse — en URL utan ändelse, eller en som omdirigerar, fungerar så länge bytena avkodas till ett stödt format. HTTP-omdirigeringar följs. EXIF-orientering normaliseras, så ett roterat telefonfoto används som det ser ut.

    Begränsningar: minst 32 pixlar på varje sida, högst 178,956,970 pixlar totalt, och högst 20,000,000 byte när det har laddats ner. För en data URI gäller gränsen för de avkodade bytena, så källfilen själv kan vara upp till den storleken — det är base64-texten som är ungefär en tredjedel större, vilket är viktigt för din begäran, inte för denna gräns. En data URI måste deklarera en image/* innehållstyp och ;base64.

    Det finns två sätt att tillhandahålla bilden:

    • Offentligt tillgänglig URL: En URL som är tillgänglig från det offentliga internet.
    • Data URI: En base64-kodad data URI av bilden. Exempel på en data URI: data:image/jpeg;base64,<din base64-kodade bilddata>.
  • Name
    name
    Type
    string
    Description

    Valfritt uppgiftsnamn för visningsändamål. Max 100 tecken.

  • Name
    remove_background
    Type
    boolean
    standard false
    Description

    När den är inställd på true, är visningsrenderingen som returneras i image_urls en transparent RGBA PNG med bakgrunden borttagen, så att du kan komponera den på vilken bakgrund som helst.

    Detta gäller endast visningsrenderingen. Kandidaten som bygg-endpointen använder påverkas inte, så 3D-resultatet är identiskt oavsett.

Returnerar

result-egenskapen i svaret innehåller uppgiftens id för den nyligen skapade keycap-prototypuppgiften. Poll Hämta en uppgift endpointen eller prenumerera på strömmen tills uppgiften når SUCCEEDED, ta sedan posten från candidate_ids och skicka den, tillsammans med uppgifts-ID, till bygg-endpointen.

Felmod

  • Name
    400 - Bad Request
    Description

    Begäran var oacceptabel. Vanliga orsaker:

    • Saknad parameter: image_url krävs.
    • Ogiltigt bildformat: Den angivna image_url är inte ett stödt format (.jpg, .jpeg, .png, .webp).
    • Bilddimensioner utanför räckvidd: Bilden är för liten, överskrider max filstorlek eller överskrider max antal pixlar.
    • Oåtkomlig URL: image_url kunde inte laddas ner (404 eller timeout).
    • Ogiltig Data URI: Base64-strängen är felaktig.
    • Innehåll flaggat: Ingångsbilden flaggades av NSFW-moderation.
  • Name
    401 - Unauthorized
    Description

    Autentisering misslyckades. Kontrollera din API-nyckel.

  • Name
    402 - Payment Required
    Description

    Kontot är på gratisplanen (en betald plan krävs för att skapa uppgifter) eller har otillräckliga credits.

  • Name
    403 - Forbidden
    Description

    Ingångsbilden flaggades av immaterialrättslig moderation.

  • Name
    429 - Too Many Requests
    Description

    Du har överskridit din hastighetsgräns.

  • Name
    500 - Internal Server Error
    Description

    Ett oväntat serverfel inträffade — till exempel var innehållsmoderationstjänsten otillgänglig, staging av ingångsbilden misslyckades, eller uppgiften kunde inte skapas. Ingen uppgift skapas i detta fall, så att försöka igen är säkert.

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

Skapa en Keycap Build Task

Generera den slutliga texturerade 3D keycap-modellen från en lyckad prototyptask och en av dess kandidater. En enda byggtask kör hela processen från början till slut — vitmodellgenerering från den valda designen, automatisk placering och skärning på keycap-basen med en kalibrerad standardposition (ingen interaktiv justering behövs), full modellfärgning och slutlig montering och export. En byggprocess tar vanligtvis 3–7 minuter, mot den övre gränsen när flera byggprocesser körs samtidigt. Se The Keycap Build Task Object för svarformatet.

Parametrar

  • Name
    input_task_id
    Type
    string
    Obligatorisk
    Description

    Task-ID för en prototyptask skapad via denna samma OpenAPI endpoint. Prototypen måste ha skapats av samma Meshy-konto, måste ha nått SUCCEEDED och måste ha producerat minst en kandidat.

    Prototyptasks skapade genom webappen accepteras inte — bygg-endpointen accepterar endast prototyptasks producerade av POST /openapi/creative-lab/keycap/v1/prototype och avvisar alla andra källor med 404.

  • Name
    candidate_id
    Type
    string
    Obligatorisk
    Description

    Kandidaten att bygga, tagen från candidate_ids-arrayen av den lyckade prototyptasken. Måste tillhöra den tasken; alla andra värden avvisas med 400.

  • Name
    name
    Type
    string
    Description

    Valfritt tasknamn för visningsändamål. Max 100 tecken.

options

Valfri geometriinställning. Varje fält har ett kalibrerat standardvärde — skicka endast de du vill åsidosätta.

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

    Keycap-basen att bygga på. För närvarande är det enda tillgängliga värdet cherry-mx-1x1-r1 — en standard Cherry MX profil 1u keycap. 3–5 ytterligare vanliga standardstorlekar planeras; anpassade storlekar stöds inte.

  • Name
    head_size_mm
    Type
    number
    standard 23
    Description

    Målstorlek för det skulpterade huvudet, i millimeter: dess längsta dimension skalas till detta värde. Område: [10, 40]. Värden över ungefär 32.9 kan reduceras så att huvudet fortfarande passar basens skyddande fotavtrycksgräns, så den levererade längsta dimensionen kan vara mindre än begärd. Det tillämpade värdet återges inte i task-objektet idag — om du behöver bekräfta storleken du faktiskt fick, mät begränsningsrutan för keycap-head nätet i den nedladdade modellen.

  • Name
    vertical_offset_mm
    Type
    number
    standard 0
    Description

    Vertikal förskjutning applicerad på huvudet innan det placeras på basen, i millimeter. Område: [-5, 5].

Returnerar

result-egenskapen i svaret innehåller taskens id för den nyligen skapade keycap build tasken. Poll Get a Task endpointen eller prenumerera på stream tills tasken når SUCCEEDED, ladda sedan ner artefakterna från model_urls.glb och model_urls.obj_zip.

Felmod

  • Name
    400 - Bad Request
    Description

    Begäran var oacceptabel. Vanliga orsaker:

    • Saknad parameter: input_task_id och candidate_id är obligatoriska.
    • Ogiltig UUID: input_task_id är inte en giltig UUID.
    • Förälder inte lyckad: Den refererade prototyptasken har inte nått SUCCEEDED än.
    • Inga kandidater: Prototyptasken lyckades men producerade inga kandidater.
    • Okänd kandidat: candidate_id är inte en av input taskens kandidater.
    • Alternativ utanför räckvidd: Ett av options-fälten föll utanför dess tillåtna räckvidd eller enum-set.
  • Name
    401 - Unauthorized
    Description

    Autentisering misslyckades. Kontrollera din API-nyckel.

  • Name
    402 - Payment Required
    Description

    Kontot är på gratisplanen (en betald plan krävs för att skapa tasks) eller har otillräckliga credits.

  • Name
    404 - Not Found
    Description

    Den refererade prototyptasken existerar inte, tillhör en annan användare eller skapades genom webappen (endast API-mode prototyptasks kedjas till bygg).

  • Name
    429 - Too Many Requests
    Description

    Du har överskridit din hastighetsgräns.

  • Name
    500 - Internal Server Error
    Description

    Ett oväntat serverfel inträffade — till exempel var innehållsmodereringstjänsten otillgänglig, staging av inmatningsbilden misslyckades, eller tasken kunde inte skapas. Ingen task skapas i detta fall, så det är säkert att försöka igen.

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

Hämta en Keycap-uppgift

Hämta en prototyp- eller bygguppgift med ett giltigt uppgifts-id. URL-sökvägen måste matcha uppgiftens steg — en bygguppgift hämtad genom /prototype/:id returnerar 404, och vice versa.

Se The Keycap Prototype Task Object och The Keycap Build Task Object för svarens strukturer.

Parametrar

  • Name
    id
    Type
    path
    Description

    Unik identifierare för keycap-uppgiften som ska hämtas.

Returnerar

Svaret innehåller keycap-uppgiftsobjektet. Strukturen beror på vilket steg som begärdes.

Förfrågan

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

Prototypsvar

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

Byggsvar

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

Ta bort en Keycap-uppgift

Avbryt en keycap-uppgift. Om uppgiften fortfarande är PENDING, återbetalas de credits som förbrukades vid skapandet. Uppgifter som redan är IN_PROGRESS avbryts utan återbetalning (arbetaren kan redan använda resurser). Uppgifter som redan har nått ett slutligt tillstånd (SUCCEEDED, FAILED, CANCELED) kan inte avbrytas.

URL-sökvägen måste matcha uppgiftens stadium — DELETE/prototype/:buildId returnerar 404.

Sökvägsparametrar

  • Name
    id
    Type
    path
    Description

    Unik identifierare för keycap-uppgiften som ska avbrytas.

Returnerar

Returnerar 204 No Content vid framgång med en tom kropp.

Feltyper

  • Name
    400 - Bad Request
    Description

    Uppgiften är redan i ett slutligt tillstånd och kan inte avbrytas.

  • Name
    404 - Not Found
    Description

    Uppgiften existerar inte, tillhör en annan användare, eller dess stadium matchar inte URL-sökvägen.

  • Name
    500 - Internal Server Error
    Description

    Ett oväntat serverfel inträffade vid avbrytandet. Uppgiften kan ha avbrutits eller inte — läs om den för att bekräfta innan du försöker igen.

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

Strömma en Keycap-uppgift

Strömma realtidsuppdateringar för en keycap-uppgift via Server-Sent Events (SSE). URL-sökvägen måste matcha uppgiftens steg — att öppna en ström vid /prototype/:buildId/stream sänder en enda event: error payload med status_code: 404 och stänger strömmen.

Parametrar

  • Name
    id
    Type
    path
    Description

    Unik identifierare för keycap-uppgiften att strömma.

Returnerar

Returnerar en ström av Keycap Prototype eller Keycap Build uppgiftsobjekt som Server-Sent Events. För PENDING eller IN_PROGRESS uppgifter kommer svarströmmen endast att inkludera de nödvändiga progress och status fälten.

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)

Lista Keycap-uppgifter

Hämta en paginerad lista över dina keycap-uppgifter för ett enskilt stadium. URL-sökvägen väljer stadiet — /prototype returnerar prototypuppgifter; /build returnerar bygguppgifter. Uppgifter från det andra stadiet ingår inte i något av svaren.

Sökvägsparametrar

  • Name
    stage
    Type
    path
    Obligatorisk
    Description

    Antingen prototype eller build. Samlingen returnerar endast uppgifter vars stadium matchar URL:en — hämtning av /prototype returnerar aldrig bygguppgifter och vice versa.

Frågeparametrar

  • Name
    page_num
    Type
    integer
    standard 1
    Description

    Sidnummer för paginering.

  • Name
    page_size
    Type
    integer
    standard 10
    Description

    Sidstorleksgräns. Max tillåtet är 100 objekt.

  • Name
    sort_by
    Type
    string
    standard -created_at
    Description

    Fält att sortera efter. Tillgängliga värden:

    • +created_at: Sortera efter skapandetid i stigande ordning.
    • -created_at: Sortera efter skapandetid i fallande ordning.

Returnerar

Returnerar en paginerad lista över uppgiftsobjektet per stadium — antingen keycap-prototypuppgiftsobjektet vid listning av /prototype eller keycap-bygguppgiftsobjektet vid listning av /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"
    ]
  }
]

Keycap-prototypsuppgiftens objekt

Keycap-prototypsuppgiftens objekt är en arbetsenhet som Meshy håller reda på för att generera en färdig nyckelkapseldesignbild från ett källfoto. Utdata från detta steg är kopplat till byggsteget via input_task_id plus candidate_id.

Egenskaper

  • Name
    id
    Type
    string
    Description

    Unik identifierare för uppgiften. Även om vi använder en k-sorterbar UUID för uppgifts-id som implementeringsdetalj, bör du inte göra några antaganden om formatet på id.

  • Name
    type
    Type
    string
    Description

    Typ av uppgift. Värdet är creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    Det uppgiftsnamn som angavs när uppgiften skapades. Tom sträng om inget namn angavs.

  • Name
    status
    Type
    string
    Description

    Status för uppgiften. Möjliga värden är en av PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Framsteg för uppgiften. Om uppgiften inte har startat än, kommer denna egenskap att vara 0. När uppgiften har lyckats, kommer detta att bli 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften skapades, i millisekunder.

  • Name
    started_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften startades, i millisekunder. Om uppgiften inte har startat än, kommer denna egenskap att vara 0.

  • Name
    finished_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften avslutades, i millisekunder. Om uppgiften inte har avslutats än, kommer denna egenskap att vara 0.

  • Name
    expires_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiftsresultatet går ut, i millisekunder.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Antalet föregående uppgifter.

  • Name
    task_error
    Type
    object
    Description

    Felformationer för misslyckade uppgifter. Se Fel för fullständig referens av task_error-objektet.

  • Name
    consumed_credits
    Type
    integer
    Description

    Antalet credits som förbrukats av denna uppgift. En uppgift som når SUCCEEDED debiteras hela beloppet för sitt steg. En uppgift som aldrig skapas (en 4xx vid begäran, inklusive en moderation avslag) debiteras inte alls. En uppgift som når FAILED returnerar 0 — avgiften återbetalas, inklusive en asynkron moderation block. Avbokning via DELETE återbetalar endast medan uppgiften fortfarande är PENDING; en uppgift som redan är IN_PROGRESS förblir debiterad, eftersom arbetet har utförts.

  • Name
    image_urls
    Type
    array of strings
    Description

    Nedladdningsbar URL för den färdiga nyckelkapseldesignens rendering — hur kandidaten ser ut som en färdig nyckelkapsel. Innehåller en enda post; image_urls[i] motsvarar candidate_ids[i]. Tom tills uppgiften når SUCCEEDED. URL:en är endast för visning; bygg-endpointen förbrukar candidate_ids, inte dessa URL:er. Samma URL-livscykel som model_urls: signerad, ingen Authorization-header, giltig tills expires_at, och stabil när uppgiften läses om.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Ogenomskinliga kandidatidentifierare, parallella med image_urls. Skicka posten som matchar din valda design som byggbegärans candidate_id. Gör inga antaganden om formatet på dessa id.

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

Objektet för Keycap Build-uppgift

Objektet för Keycap Build-uppgift är en arbetsenhet som Meshy håller reda på för att generera den slutliga texturerade 3D-tangentkappen från en lyckad prototypuppgift och en vald kandidat. En enda byggprocess kör hela pipeline — generering av vit modell, automatisk placering och skärning, färgläggning, montering och export.

Egenskaper

  • Name
    id
    Type
    string
    Description

    Unik identifierare för uppgiften.

  • Name
    type
    Type
    string
    Description

    Typ av uppgift. Värdet är creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    Uppgiftsnamnet som angavs när uppgiften skapades. Tom sträng om inget namn angavs.

  • Name
    status
    Type
    string
    Description

    Status för uppgiften. Möjliga värden är en av PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Framsteg för uppgiften. Om uppgiften inte har startat ännu kommer denna egenskap att vara 0. När uppgiften har lyckats kommer detta att bli 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften skapades, i millisekunder.

  • Name
    started_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften startades, i millisekunder.

  • Name
    finished_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiften avslutades, i millisekunder.

  • Name
    expires_at
    Type
    timestamp
    Description

    Tidsstämpel för när uppgiftsresultatet går ut, i millisekunder.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Antalet föregående uppgifter. Meningsfullt endast när status är PENDING.

  • Name
    task_error
    Type
    object
    Description

    Felformationer för misslyckade uppgifter. Se Fel för fullständig referens av task_error-objektet.

  • Name
    consumed_credits
    Type
    integer
    Description

    Antalet credits som förbrukats av denna uppgift. En uppgift som når SUCCEEDED debiteras fullt belopp för sin fas. En uppgift som aldrig skapas (en 4xx vid begäran, inklusive en moderation avslag) debiteras inte alls. En uppgift som når FAILED returnerar 0 — avgiften återbetalas, inklusive en asynkron moderation blockering. Avbrytande via DELETE återbetalar endast medan uppgiften fortfarande är PENDING; en uppgift som redan är IN_PROGRESS förblir debiterad, eftersom arbetet har utförts.

  • Name
    model_urls
    Type
    object
    Description

    Nedladdningsbara URL:er för de genererade modellartefakterna. Både GLB och OBJ-paketet exporteras i verklig värld millimeterskala, Y-up, med framsidan av tangentkappen vänd mot +Z. Nät är namngivna keycap-head och keycap-base; när basen faller tillbaka till ett mönsterfyllning finns också ett tredje nät keycap-base-interior för stamkaviteten. Förutsätt inte exakt två nät.

    Dessa är signerade URL:er: hämta dem utan en Authorization-header. De förblir giltiga till expires_at, vilket är 3 dagar efter finished_at, och att läsa om uppgiften inom det fönstret returnerar samma URL istället för en ny signerad. Ladda ner och lagra filerna själv innan dess — det finns inget sätt att förnya en utgången länk.

    • Name
      glb
      Type
      string
      Description

      Nedladdningsbar URL till den slutliga texturerade model.glb.

    • Name
      obj_zip
      Type
      string
      Description

      Nedladdningsbar URL till ett zip-paket som innehåller model.obj, model.mtl, och de textur PNG:er som dess MTL faktiskt refererar till. En enfärgad bas levererar endast keycap-head.png; en mönstrad bas levererar också keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    Nedladdningsbara URL:er för mellanliggande processbilder, nycklade efter typ. Samma URL-livscykel som model_urls: signerade, ingen Authorization-header, giltiga till expires_at, och stabila när uppgiften läses om. För närvarande emitterade typer:

    • head_design — den valda kandidatens designbild som byggprocessen förbrukade (alltid närvarande).
    • composite — den färdiga tangentkappens visningsrendering av den valda kandidaten (närvarande när tillgänglig).
    • base_canvas — den målade tangentkappens basduk (närvarande när tillgänglig).

    Behandla nyckeluppsättningen som öppen; nya typer kan läggas till utan en brytande förändring.

Exempel på Keycap Build-uppgiftsobjekt

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

End-to-End Exempel

Det kompletta flödet: skapa en prototyp från ett foto, poll:a den till SUCCEEDED, välj en kandidat från candidate_ids, skapa en build med den kandidaten, poll:a builden till SUCCEEDED, och ladda sedan ner GLB och OBJ-paketet från model_urls.

Exemplet väljer den första kandidaten programmatiskt. I en verklig integration skulle du visa image_urls-posten för slutanvändaren och låta dem välja; det valda indexet mappar 1:1 till candidate_ids.

Komplett flöde

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"