Creative Lab — Keycap API

Verander een bronfoto in een full-color aangepaste mechanische toetsenbordtoets in twee fasen: prototype genereert een "voltooide toets" ontwerpweergave van uw invoerfoto. Zodra u die weergave hebt bevestigd, verandert build het in een getextureerd 3D-toetsmodel in één enkele run — wit-model generatie, automatische plaatsing en snijden op een gekalibreerde standaardhouding, volledige modelkleuring, en eindassemblage gebeuren allemaal binnen één bouwtaak. De twee fasen zijn gekoppeld 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

Maak een Keycap Prototype Taak

Genereer een render van een afgewerkte keycap-ontwerp vanuit de bronfoto. Het resultaat van de taak bevat een image_urls array (de weergaverender van de afgewerkte keycap) en een parallelle candidate_ids array; beide bevatten één item. Roep deze endpoint opnieuw aan voor een andere render als het resultaat niet is wat je wilt — elke oproep wordt afzonderlijk gefactureerd. Geef de candidate_id samen met de prototype taak-ID door aan de build endpoint. Raadpleeg Het Keycap Prototype Taak Object voor de vorm van de respons.

Parameters

  • Name
    image_url
    Type
    string
    Verplicht
    Description

    Bronfoto voor Meshy om om te zetten in keycap-ontwerpafbeeldingen. We ondersteunen momenteel de formaten .jpg, .jpeg, .png en .webp.

    Het formaat wordt gedetecteerd door het decoderen van de afbeeldingsgegevens, niet van de bestandsextensie van de URL — een URL zonder extensie, of een die omleidt, werkt zolang de bytes decoderen naar een ondersteund formaat. HTTP-omleidingen worden gevolgd. EXIF-oriëntatie wordt genormaliseerd, dus een gedraaide telefoonfoto wordt gebruikt zoals deze eruitziet.

    Limieten: minimaal 32 pixels aan elke zijde, maximaal 178,956,970 pixels in totaal, en maximaal 20,000,000 bytes eenmaal gedownload. Voor een data URI geldt de limiet voor de gedecodeerde bytes, dus het bronbestand zelf mag tot die grootte zijn — het is de base64-tekst die ongeveer een derde groter is, wat van belang is voor je request body, niet voor deze limiet. Een data URI moet een image/* contenttype en ;base64 declareren.

    Er zijn twee manieren om de afbeelding te verstrekken:

    • Publiek toegankelijke URL: Een URL die toegankelijk is vanaf het openbare internet.
    • Data URI: Een base64-gecodeerde data URI van de afbeelding. Voorbeeld van een data URI: data:image/jpeg;base64,<je base64-gecodeerde afbeeldingsgegevens>.
  • Name
    name
    Type
    string
    Description

    Optionele taaknaam voor weergavedoeleinden. Maximaal 100 tekens.

  • Name
    remove_background
    Type
    boolean
    standaard false
    Description

    Wanneer ingesteld op true, is de weergaverender die wordt geretourneerd in image_urls een transparante RGBA PNG met de achtergrond verwijderd, zodat je deze op elke achtergrond kunt samenstellen.

    Dit geldt alleen voor de weergaverender. De kandidaat die de build endpoint verbruikt, blijft onaangetast, dus het 3D-resultaat is in beide gevallen identiek.

Retourneert

De result eigenschap van de respons bevat de taak id van de nieuw aangemaakte keycap prototype taak. Poll de Get a Task endpoint of abonneer je op de stream totdat de taak SUCCEEDED bereikt, neem dan het item uit candidate_ids en geef het, samen met de taak-ID, door aan de build endpoint.

Foutmodi

  • Name
    400 - Bad Request
    Description

    Het verzoek was onacceptabel. Veelvoorkomende oorzaken:

    • Ontbrekende parameter: image_url is vereist.
    • Ongeldig afbeeldingsformaat: De verstrekte image_url is geen ondersteund formaat (.jpg, .jpeg, .png, .webp).
    • Afbeeldingsafmetingen buiten bereik: De afbeelding is te klein, overschrijdt de maximale bestandsgrootte of overschrijdt het maximale aantal pixels.
    • Onbereikbare URL: De image_url kon niet worden gedownload (404 of timeout).
    • Ongeldige Data URI: De base64-string is ongeldig.
    • Inhoud gemarkeerd: De invoerafbeelding is gemarkeerd door NSFW moderation.
  • Name
    401 - Unauthorized
    Description

    Authenticatie mislukt. Controleer je API-sleutel.

  • Name
    402 - Payment Required
    Description

    Het account bevindt zich op het gratis plan (een betaald plan is vereist om taken te maken) of heeft onvoldoende credits.

  • Name
    403 - Forbidden
    Description

    De invoerafbeelding is gemarkeerd door intellectuele eigendom moderation.

  • Name
    429 - Too Many Requests
    Description

    Je hebt je rate limit overschreden.

  • Name
    500 - Internal Server Error
    Description

    Er is een onverwachte server-side fout opgetreden — bijvoorbeeld de content-moderation service was niet beschikbaar, het voorbereiden van de invoerafbeelding is mislukt, of de taak kon niet worden aangemaakt. Er wordt in dit geval geen taak aangemaakt, dus opnieuw proberen is veilig.

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

Maak een Keycap Build Taak

Genereer het uiteindelijke 3D keycap model met textuur van een geslaagde prototype taak en een van zijn kandidaten. Een enkele build taak voert de hele pijplijn van begin tot eind uit — wit-model generatie van het gekozen ontwerp, automatische plaatsing en uitsnijding op de keycap basis met behulp van een gekalibreerde standaardpositie (geen interactieve aanpassing nodig), volledige modelkleuring, en uiteindelijke assemblage en export. Een build duurt doorgaans 3–7 minuten, aan de hogere kant wanneer meerdere builds gelijktijdig worden uitgevoerd. Raadpleeg Het Keycap Build Taak Object voor de vorm van de respons.

Parameters

  • Name
    input_task_id
    Type
    string
    Verplicht
    Description

    De taak-ID van een prototype taak die via dezezelfde OpenAPI endpoint is aangemaakt. Het prototype moet zijn aangemaakt door hetzelfde Meshy-account, moet SUCCEEDED hebben bereikt, en moet ten minste één kandidaat hebben geproduceerd.

    Prototype taken die via de webapp zijn aangemaakt worden niet geaccepteerd — de build endpoint accepteert alleen prototype taken geproduceerd door POST /openapi/creative-lab/keycap/v1/prototype en weigert elke andere bron met 404.

  • Name
    candidate_id
    Type
    string
    Verplicht
    Description

    De kandidaat om te bouwen, genomen uit de candidate_ids array van de geslaagde prototype taak. Moet tot die taak behoren; elke andere waarde wordt afgewezen met 400.

  • Name
    name
    Type
    string
    Description

    Optionele taaknaam voor weergavedoeleinden. Maximum 100 tekens.

options

Optionele geometrie-aanpassing. Elk veld heeft een gekalibreerde standaardwaarde — stuur alleen de velden die je wilt overschrijven.

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

    De keycap basis om op te bouwen. Momenteel is de enige beschikbare waarde cherry-mx-1x1-r1 — een standaard Cherry MX profiel 1u keycap. 3–5 extra gangbare standaardmaten zijn gepland; aangepaste maten worden niet ondersteund.

  • Name
    head_size_mm
    Type
    number
    standaard 23
    Description

    Doelgrootte van de gebeeldhouwde kop, in millimeters: de langste afmeting wordt geschaald naar deze waarde. Bereik: [10, 40]. Waarden boven ongeveer 32.9 kunnen worden verkleind zodat de kop nog steeds binnen de beschermende voetafdruklimiet van de basis past, waardoor de geleverde langste afmeting kleiner kan zijn dan gevraagd. De toegepaste waarde wordt vandaag niet teruggegeven op het taakobject — als je de grootte wilt bevestigen die je daadwerkelijk hebt ontvangen, meet dan de bounding box van de keycap-head mesh in het gedownloade model.

  • Name
    vertical_offset_mm
    Type
    number
    standaard 0
    Description

    Verticale offset toegepast op de kop voordat deze op de basis wordt geplaatst, in millimeters. Bereik: [-5, 5].

Retourneert

De result eigenschap van de respons bevat de taak id van de nieuw aangemaakte keycap build taak. Poll de Get a Task endpoint of abonneer je op de stream totdat de taak SUCCEEDED bereikt, en download dan de artefacten van model_urls.glb en model_urls.obj_zip.

Foutmodi

  • Name
    400 - Bad Request
    Description

    Het verzoek was onacceptabel. Veelvoorkomende oorzaken:

    • Ontbrekende parameter: input_task_id en candidate_id zijn vereist.
    • Ongeldige UUID: De input_task_id is geen geldige UUID.
    • Ouder niet geslaagd: De genoemde prototype taak heeft SUCCEEDED nog niet bereikt.
    • Geen kandidaten: De prototype taak is geslaagd maar heeft geen kandidaten geproduceerd.
    • Onbekende kandidaat: candidate_id is niet een van de kandidaten van de input taak.
    • Opties buiten bereik: Een van de options velden viel buiten het toegestane bereik of enum set.
  • Name
    401 - Unauthorized
    Description

    Authenticatie mislukt. Controleer je API-sleutel.

  • Name
    402 - Payment Required
    Description

    Het account is op het gratis plan (een betaald plan is vereist om taken te maken) of heeft onvoldoende credits.

  • Name
    404 - Not Found
    Description

    De genoemde prototype taak bestaat niet, behoort tot een andere gebruiker, of is aangemaakt via de webapp (alleen API-modus prototype taken schakelen over naar build).

  • Name
    429 - Too Many Requests
    Description

    Je hebt je rate limit overschreden.

  • Name
    500 - Internal Server Error
    Description

    Er is een onverwachte server-side fout opgetreden — bijvoorbeeld de content-moderation service was niet beschikbaar, het voorbereiden van de input afbeelding is mislukt, of de taak kon niet worden aangemaakt. Er wordt in dit geval geen taak aangemaakt, dus opnieuw proberen is veilig.

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

Haal een Keycap Taak op

Haal een prototype- of bouwtaak op met een geldig taak id. Het URL-pad moet overeenkomen met de fase van de taak — een bouwtaak opgehaald via /prototype/:id geeft 404, en vice versa.

Raadpleeg Het Keycap Prototype Taak Object en Het Keycap Bouw Taak Object voor responsvormen.

Parameters

  • Name
    id
    Type
    path
    Description

    Unieke identificatie voor de keycap-taak om op te halen.

Retourneert

De respons bevat het keycap-taakobject. De vorm hangt af van welke fase werd opgevraagd.

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

Verwijder een Keycap Taak

Annuleer een keycap taak. Als de taak nog PENDING is, worden de credits die bij het aanmaken zijn verbruikt, teruggestort. Taken die al IN_PROGRESS zijn, worden geannuleerd zonder terugbetaling (de werknemer kan al bezig zijn met het verbruiken van bronnen). Taken die al een eindstatus hebben bereikt (SUCCEEDED, FAILED, CANCELED) kunnen niet worden geannuleerd.

Het URL-pad moet overeenkomen met de fase van de taak — DELETE op /prototype/:buildId geeft 404 terug.

Pad Parameters

  • Name
    id
    Type
    path
    Description

    Unieke identificatie voor de keycap taak om te annuleren.

Retourneert

Retourneert 204 No Content bij succes met een lege body.

Foutmodi

  • Name
    400 - Bad Request
    Description

    De taak is al in een eindstatus en kan niet worden geannuleerd.

  • Name
    404 - Not Found
    Description

    De taak bestaat niet, behoort tot een andere gebruiker, of de fase komt niet overeen met het URL-pad.

  • Name
    500 - Internal Server Error
    Description

    Er is een onverwachte serverfout opgetreden tijdens het annuleren. De taak kan al dan niet zijn geannuleerd — lees deze opnieuw om te bevestigen voordat u het opnieuw probeert.

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

Stream een Keycap Taak

Stream real-time updates voor een keycap taak via Server-Sent Events (SSE). Het URL-pad moet overeenkomen met de fase van de taak — het openen van een stream bij /prototype/:buildId/stream geeft een enkele event: error payload met status_code: 404 en sluit de stream.

Parameters

  • Name
    id
    Type
    path
    Description

    Unieke identificatie voor de keycap taak om te streamen.

Retourneert

Retourneert een stream van Keycap Prototype of Keycap Build taakobjecten als Server-Sent Events. Voor PENDING of IN_PROGRESS taken, zal de responsstream alleen de noodzakelijke progress en status velden bevatten.

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)

Lijst Keycap Taken

Haal een gepagineerde lijst op van je keycap-taken voor een enkele fase. Het URL-pad selecteert de fase — /prototype retourneert prototype-taken; /build retourneert build-taken. Taken van de andere fase zijn in geen van beide antwoorden inbegrepen.

Padparameters

  • Name
    stage
    Type
    path
    Verplicht
    Description

    Ofwel prototype of build. De collectie retourneert alleen taken waarvan de fase overeenkomt met de URL — het ophalen van /prototype retourneert nooit build-taken en vice versa.

Queryparameters

  • Name
    page_num
    Type
    integer
    standaard 1
    Description

    Paginanummer voor paginering.

  • Name
    page_size
    Type
    integer
    standaard 10
    Description

    Limiet voor paginagrootte. Maximum toegestaan is 100 items.

  • Name
    sort_by
    Type
    string
    standaard -created_at
    Description

    Veld om op te sorteren. Beschikbare waarden:

    • +created_at: Sorteren op creatietijd in oplopende volgorde.
    • -created_at: Sorteren op creatietijd in aflopende volgorde.

Retourneert

Retourneert een gepagineerde lijst van het per-fase taakobject — ofwel het keycap prototype taakobject bij het opvragen van /prototype of het keycap build taakobject bij het opvragen van /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 (Lijst Prototype Taken)

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

Het Keycap Prototype Taakobject

Het Keycap Prototype Taakobject is een werkunit die Meshy bijhoudt om één afgewerkt keycap-ontwerpafbeelding te genereren vanuit een bronfoto. De output van deze fase wordt gekoppeld aan de bouwfase via input_task_id plus candidate_id.

Eigenschappen

  • Name
    id
    Type
    string
    Description

    Unieke identificatie voor de taak. Hoewel we een k-sorteerbare UUID gebruiken voor taak-id's als implementatiedetail, moet je geen aannames maken over het formaat van de id.

  • Name
    type
    Type
    string
    Description

    Type van de taak. De waarde is creative-lab-keycap-prototype.

  • Name
    name
    Type
    string
    Description

    De taaknaam die werd opgegeven toen de taak werd aangemaakt. Lege string als er geen naam werd opgegeven.

  • Name
    status
    Type
    string
    Description

    Status van de taak. Mogelijke waarden zijn een van PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Voortgang van de taak. Als de taak nog niet is gestart, zal deze eigenschap 0 zijn. Zodra de taak is geslaagd, wordt dit 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is aangemaakt, in milliseconden.

  • Name
    started_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is gestart, in milliseconden. Als de taak nog niet is gestart, zal deze eigenschap 0 zijn.

  • Name
    finished_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is voltooid, in milliseconden. Als de taak nog niet is voltooid, zal deze eigenschap 0 zijn.

  • Name
    expires_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer het taakresultaat verloopt, in milliseconden.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Het aantal voorafgaande taken.

  • Name
    task_error
    Type
    object
    Description

    Foutdetails voor mislukte taken. Zie Fouten voor de volledige task_error objectreferentie.

  • Name
    consumed_credits
    Type
    integer
    Description

    Het aantal credits dat door deze taak is verbruikt. Een taak die SUCCEEDED bereikt, wordt het volledige bedrag voor zijn fase in rekening gebracht. Een taak die nooit wordt aangemaakt (een 4xx op het moment van de aanvraag, inclusief een moderatieafwijzing) wordt helemaal niet in rekening gebracht. Een taak die FAILED bereikt, retourneert 0 — de kosten worden terugbetaald, inclusief een asynchrone moderatieblokkering. Annuleren via DELETE wordt alleen terugbetaald zolang de taak nog PENDING is; een taak die al IN_PROGRESS is, blijft in rekening gebracht, omdat het werk is besteed.

  • Name
    image_urls
    Type
    array of strings
    Description

    Downloadbare URL van de afgewerkte keycap-ontwerprender — hoe de kandidaat eruitziet als een afgewerkte keycap. Bevat één item; image_urls[i] komt overeen met candidate_ids[i]. Leeg totdat de taak SUCCEEDED bereikt. De URL is alleen voor weergave; de bouwendpoint verbruikt candidate_ids, niet deze URL's. Zelfde URL-levenscyclus als model_urls: ondertekend, geen Authorization header, geldig tot expires_at, en stabiel wanneer de taak opnieuw wordt gelezen.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Ondoorzichtige kandidaat-identificaties, parallel aan image_urls. Geef de vermelding die overeenkomt met je gekozen ontwerp door als de candidate_id van het bouwverzoek. Maak geen aannames over het formaat van deze id's.

Voorbeeld Keycap Prototype Taakobject

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

Het Keycap Build Task Object

Het Keycap Build Task-object is een werkeenheid die Meshy bijhoudt om de uiteindelijke getextureerde 3D-keycap te genereren vanuit een geslaagde prototype-taak en een gekozen kandidaat. Een enkele build doorloopt de volledige pijplijn — wit-model generatie, automatische plaatsing en snijden, inkleuren, assemblage en export.

Eigenschappen

  • Name
    id
    Type
    string
    Description

    Unieke identificatie voor de taak.

  • Name
    type
    Type
    string
    Description

    Type van de taak. De waarde is creative-lab-keycap-build.

  • Name
    name
    Type
    string
    Description

    De taaknaam die werd opgegeven bij het aanmaken van de taak. Lege string als er geen naam werd opgegeven.

  • Name
    status
    Type
    string
    Description

    Status van de taak. Mogelijke waarden zijn een van PENDING, IN_PROGRESS, SUCCEEDED, FAILED, CANCELED.

  • Name
    progress
    Type
    integer
    Description

    Voortgang van de taak. Als de taak nog niet is gestart, zal deze eigenschap 0 zijn. Zodra de taak is geslaagd, wordt dit 100.

  • Name
    created_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is aangemaakt, in milliseconden.

  • Name
    started_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is gestart, in milliseconden.

  • Name
    finished_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer de taak is voltooid, in milliseconden.

  • Name
    expires_at
    Type
    timestamp
    Description

    Tijdstempel van wanneer het taakresultaat verloopt, in milliseconden.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Het aantal voorafgaande taken. Betekenisvol alleen wanneer de status PENDING is.

  • Name
    task_error
    Type
    object
    Description

    Foutdetails voor mislukte taken. Zie Fouten voor de volledige task_error objectreferentie.

  • Name
    consumed_credits
    Type
    integer
    Description

    Het aantal credits dat door deze taak is verbruikt. Een taak die SUCCEEDED bereikt, wordt het volledige bedrag voor zijn fase in rekening gebracht. Een taak die nooit wordt aangemaakt (een 4xx op het moment van aanvraag, inclusief een moderatie-afwijzing) wordt helemaal niet in rekening gebracht. Een taak die FAILED bereikt, retourneert 0 — de kosten worden terugbetaald, inclusief een asynchrone moderatieblokkering. Annuleren via DELETE geeft alleen een terugbetaling zolang de taak nog PENDING is; een taak die al IN_PROGRESS is, blijft in rekening gebracht, omdat het werk al is verricht.

  • Name
    model_urls
    Type
    object
    Description

    Downloadbare URL's voor de gegenereerde modelartefacten. Zowel de GLB als de OBJ-bundel worden geëxporteerd op echte wereld millimeterschaal, Y-up, met de voorkant van de keycap gericht naar +Z. Meshes worden genoemd keycap-head en keycap-base; wanneer de basis terugvalt op een patroonvulling, is er ook een derde mesh keycap-base-interior aanwezig voor de steelholte. Ga niet uit van precies twee meshes.

    Dit zijn ondertekende URL's: haal ze op zonder een Authorization-header. Ze blijven geldig tot expires_at, wat 3 dagen na finished_at is, en het opnieuw lezen van de taak binnen dat venster retourneert dezelfde URL in plaats van een vers ondertekende. Download en sla de bestanden zelf op voor die tijd — er is geen manier om een verlopen link te vernieuwen.

    • Name
      glb
      Type
      string
      Description

      Downloadbare URL naar de uiteindelijke getextureerde model.glb.

    • Name
      obj_zip
      Type
      string
      Description

      Downloadbare URL naar een zip-bundel die model.obj, model.mtl en de textuur PNG's bevat waarnaar de MTL daadwerkelijk verwijst. Een effen kleur basis levert alleen keycap-head.png; een gepatroonde basis levert ook keycap-base.png.

  • Name
    process_image_urls
    Type
    object
    Description

    Downloadbare URL's voor tussentijdse procesafbeeldingen, gesorteerd op soort. Zelfde URL-levenscyclus als model_urls: ondertekend, geen Authorization-header, geldig tot expires_at, en stabiel wanneer de taak opnieuw wordt gelezen. Momenteel uitgegeven soorten:

    • head_design — het ontwerpbeeld van de gekozen kandidaat dat de build heeft verbruikt (altijd aanwezig).
    • composite — de weergave van de afgewerkte keycap van de gekozen kandidaat (aanwezig wanneer beschikbaar).
    • base_canvas — het geschilderde keycap-basis canvas (aanwezig wanneer beschikbaar).

    Behandel de sleutelset als open-eindig; nieuwe soorten kunnen worden toegevoegd zonder een brekende verandering.

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

End-to-End Voorbeeld

De complete flow: maak een prototype van een foto, poll het naar SUCCEEDED, kies een kandidaat uit candidate_ids, maak een build met die kandidaat, poll de build naar SUCCEEDED, en download vervolgens de GLB en de OBJ bundel van model_urls.

Het voorbeeld kiest de eerste kandidaat programmatisch. In een echte integratie zou je de image_urls vermelding aan de eindgebruiker tonen en hen laten kiezen; de gekozen index komt 1:1 overeen met 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"