Creative Lab — Keycap API

Zet een bronfoto in twee fasen om in een volledig gekleurde, aangepaste mechanische toetsenbord-keycap: prototype genereert een render van een "afgewerkte keycap"-ontwerp op basis van je invoerfoto. Zodra je die render hebt bevestigd, zet build deze in één run om in een 3D-keycapmodel met textuur — het genereren van het witte model, automatisch plaatsen en snijden op een gekalibreerde standaardpose, kleuring van het volledige model, en de uiteindelijke assemblage gebeuren allemaal binnen één build-taak. De twee fasen worden 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

Een Keycap Prototype-taak aanmaken

Genereer een render van een afgewerkt keycap-ontwerp op basis van de bronfoto. Het taakresultaat bevat een image_urls-array (de weergaverender van de afgewerkte keycap) en een parallelle candidate_ids-array; beide bevatten één enkel item. Roep deze endpoint opnieuw aan voor een andere render als het resultaat niet is wat u wilt — elke aanroep wordt afzonderlijk in rekening gebracht. Geef de candidate_id samen met de prototype-taak-ID door aan de build-endpoint. Raadpleeg Het Keycap Prototype Task Object voor de vorm van de response.

Parameters

  • Name
    image_url
    Type
    string
    Verplicht
    Description

    Bronfoto die Meshy omzet in keycap-ontwerpafbeeldingen. We ondersteunen momenteel de indelingen .jpg, .jpeg, .png en .webp.

    De indeling wordt gedetecteerd door de afbeeldingsgegevens te decoderen, niet aan de hand van de bestandsextensie van de URL — een URL zonder extensie, of een die doorverwijst, werkt zolang de bytes decoderen naar een ondersteunde indeling. HTTP-redirects worden gevolgd. EXIF-oriëntatie wordt genormaliseerd, zodat een gedraaide telefoonfoto wordt gebruikt zoals hij eruitziet.

    Beperkingen: minstens 32 pixels aan elke zijde, hoogstens 178.956.970 pixels in totaal, en hoogstens 20.000.000 bytes na download. 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 relevant is voor uw requestbody, niet voor deze limiet. Een data-URI moet een image/*-content-type en ;base64 bevatten.

    Er zijn twee manieren om de afbeelding aan te leveren:

    • 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,<uw 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 waarvan de achtergrond is verwijderd, zodat u deze op elke achtergrond kunt samenvoegen.

    Dit geldt alleen voor de weergaverender. De kandidaat die de build-endpoint gebruikt, wordt hierdoor niet beïnvloed, dus het 3D-resultaat is in beide gevallen identiek.

Retourwaarden

De result-eigenschap van de response bevat de taak-id van de nieuw aangemaakte keycap-prototypetaak. Poll de endpoint Een taak ophalen of abonneer u op de stream totdat de taak SUCCEEDED bereikt, en neem vervolgens het item uit candidate_ids en geef dit, samen met de taak-ID, door aan de build-endpoint.

Foutmodi

  • Name
    400 - Bad Request
    Description

    Het verzoek was onaanvaardbaar. Veelvoorkomende oorzaken:

    • Ontbrekende parameter: image_url is verplicht.
    • Ongeldige afbeeldingsindeling: de opgegeven image_url heeft geen ondersteunde indeling (.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-tekenreeks is onjuist opgemaakt.
    • Content gemarkeerd: de invoerafbeelding is gemarkeerd door NSFW-moderation.
  • Name
    401 - Unauthorized
    Description

    Authenticatie is mislukt. Controleer uw API-sleutel.

  • Name
    402 - Payment Required
    Description

    Het account heeft een gratis abonnement (een betaald abonnement is vereist om taken aan te maken) of heeft onvoldoende credits.

  • Name
    403 - Forbidden
    Description

    De invoerafbeelding is gemarkeerd door moderation voor intellectueel eigendom.

  • Name
    429 - Too Many Requests
    Description

    U heeft uw rate limit overschreden.

  • Name
    500 - Internal Server Error
    Description

    Er is een onverwachte serverfout opgetreden — bijvoorbeeld doordat de content-moderationservice niet beschikbaar was, het klaarzetten van de invoerafbeelding mislukte, of de taak niet kon worden aangemaakt. In dit geval wordt er 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

Een Keycap Build-taak aanmaken

Genereer het uiteindelijke getextureerde 3D keycap-model op basis van een geslaagde prototypetaak en een van de bijbehorende kandidaten. Eén build-taak doorloopt de volledige pijplijn van begin tot eind — het genereren van een wit model op basis van het gekozen ontwerp, automatisch plaatsen en uitsnijden op de keycap-basis met behulp van een gekalibreerde standaardpositie (geen interactieve aanpassing nodig), volledige modelkleuring, en de uiteindelijke assemblage en export. Een build duurt doorgaans 3–7 minuten, richting het bovenste einde wanneer meerdere builds gelijktijdig draaien. Raadpleeg Het Keycap Build Task-object voor de vorm van de respons.

Parameters

  • Name
    input_task_id
    Type
    string
    Verplicht
    Description

    De task-ID van een prototypetaak die via dezelfde OpenAPI-endpoint is aangemaakt. Het prototype moet zijn aangemaakt door hetzelfde Meshy-account, moet SUCCEEDED hebben bereikt, en moet minstens één kandidaat hebben opgeleverd.

    Prototypetaken die via de webapp zijn aangemaakt, worden niet geaccepteerd — de build-endpoint accepteert alleen prototypetaken die zijn 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, afkomstig uit de candidate_ids-array van de geslaagde prototypetaak. Moet bij die taak horen; elke andere waarde wordt afgewezen met 400.

  • Name
    name
    Type
    string
    Description

    Optionele taaknaam voor weergavedoeleinden. Maximaal 100 tekens.

options

Optionele geometrie-afstemming. Elk veld heeft een gekalibreerde standaardwaarde — stuur alleen degene die u wilt overschrijven.

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

    De keycap-basis waarop wordt gebouwd. Momenteel is de enige beschikbare waarde cherry-mx-1x1-r1 — een standaard Cherry MX-profiel 1u keycap. 3–5 extra mainstream standaardformaten staan gepland; aangepaste formaten worden niet ondersteund.

  • Name
    head_size_mm
    Type
    number
    standaard 23
    Description

    Doelgrootte van de gesculptureerde kop, in millimeters: de langste afmeting ervan wordt geschaald naar deze waarde. Bereik: [10, 40]. Waarden boven ongeveer 32.9 kunnen worden verlaagd 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 momenteel niet teruggegeven op het task-object — als u de daadwerkelijk ontvangen grootte wilt bevestigen, 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 task-id van de nieuw aangemaakte keycap build-taak. Poll de Get a Task-endpoint of abonneer u op de stream totdat de taak SUCCEEDED bereikt, en download vervolgens de artefacten van model_urls.glb en model_urls.obj_zip.

Foutmodi

  • Name
    400 - Bad Request
    Description

    Het verzoek was onaanvaardbaar. Veelvoorkomende oorzaken:

    • Ontbrekende parameter: input_task_id en candidate_id zijn verplicht.
    • Ongeldige UUID: De input_task_id is geen geldige UUID.
    • Ouder niet geslaagd: De verwezen prototypetaak heeft SUCCEEDED nog niet bereikt.
    • Geen kandidaten: De prototypetaak is geslaagd maar heeft geen kandidaten opgeleverd.
    • Onbekende kandidaat: candidate_id behoort niet tot de kandidaten van de invoertaak.
    • Opties buiten bereik: Een van de options-velden viel buiten het toegestane bereik of de toegestane enum-set.
  • Name
    401 - Unauthorized
    Description

    Authenticatie mislukt. Controleer uw API-sleutel.

  • Name
    402 - Payment Required
    Description

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

  • Name
    404 - Not Found
    Description

    De verwezen prototypetaak bestaat niet, behoort tot een andere gebruiker, of is aangemaakt via de webapp (alleen prototypetaken in API-mode kunnen doorschakelen naar build).

  • Name
    429 - Too Many Requests
    Description

    U heeft uw rate limit overschreden.

  • Name
    500 - Internal Server Error
    Description

    Er is een onverwachte serverzijdige fout opgetreden — bijvoorbeeld de content-moderationservice was niet beschikbaar, het klaarzetten van de invoerafbeelding mislukte, of de taak kon niet worden aangemaakt. In dit geval wordt er geen taak aangemaakt, dus het is veilig om het opnieuw te proberen.

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

Een Keycap-taak ophalen

Haal een prototype- of build-taak op aan de hand van een geldige taak-id. Het URL-pad moet overeenkomen met de fase van de taak — een build-taak die wordt opgehaald via /prototype/:id retourneert 404, en omgekeerd.

Raadpleeg The Keycap Prototype Task Object en The Keycap Build Task Object voor de vormen van de respons.

Parameters

  • Name
    id
    Type
    path
    Description

    Unieke identificatie van de op te halen keycap-taak.

Retourneert

De respons bevat het keycap-taakobject. De vorm hangt af van welke fase is 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

Een Keycap-taak verwijderen

Annuleer een keycap-taak. Als de taak nog PENDING is, worden de bij het aanmaken verbruikte credits terugbetaald. Taken die al IN_PROGRESS zijn, worden geannuleerd zonder terugbetaling (de worker 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 retourneert 404.

Padparameters

  • Name
    id
    Type
    path
    Description

    Unieke identifier voor de te annuleren keycap-taak.

Retourneert

Retourneert 204 No Content bij succes met een lege body.

Faalmodi

  • Name
    400 - Bad Request
    Description

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

  • Name
    404 - Not Found
    Description

    De taak bestaat niet, behoort toe aan 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 is mogelijk wel of niet geannuleerd — lees deze opnieuw om dit 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 realtime 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 op /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 die gestreamd moet worden.

Retourwaarden

Retourneert een stream van Keycap Prototype of Keycap Build taakobjecten als Server-Sent Events. Elk frame bevat het volledige taakobject voor die fase — dezelfde vorm die het Get-endpoint retourneert — dus zolang de taak PENDING of IN_PROGRESS is, zijn de outputvelden simpelweg nog niet ingevuld (null, [] of {}) en is 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)

List Keycap Tasks

Haal een gepagineerde lijst op van je keycap-taken voor één fase. Het URL- pad selecteert de fase — /prototype retourneert prototype-taken; /build retourneert build-taken. Taken uit de andere fase worden in geen van beide antwoorden opgenomen.

Padparameters

  • Name
    stage
    Type
    path
    Verplicht
    Description

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

Queryparameters

  • Name
    page_num
    Type
    integer
    standaard 1
    Description

    Paginanummer voor paginering.

  • Name
    page_size
    Type
    integer
    standaard 10
    Description

    Paginagrootte-limiet. Maximaal toegestaan is 100 items.

  • Name
    sort_by
    Type
    string
    standaard -created_at
    Description

    Veld om op te sorteren. Beschikbare waarden:

    • +created_at: Sorteer op aanmaaktijd in oplopende volgorde.
    • -created_at: Sorteer op aanmaaktijd in aflopende volgorde.

Retourneert

Retourneert een gepagineerde lijst van het per-fase taakobject — ofwel het keycap-prototypetaakobject bij het weergeven van /prototype of het keycap-buildtaakobject bij het weergeven 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 (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"
    ]
  }
]

Het Keycap Prototype Task-object

Het Keycap Prototype Task-object is een werkeenheid die Meshy bijhoudt om één afbeelding van het uiteindelijke keycap-ontwerp te genereren op basis van een bronfoto. De output van deze fase wordt gekoppeld aan de buildfase via input_task_id plus candidate_id.

Eigenschappen

  • Name
    id
    Type
    string
    Description

    Unieke identifier voor de taak. Hoewel we als implementatiedetail een k-sorteerbare UUID gebruiken voor taak-id's, mag je geen aannames doen 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 is opgegeven bij het aanmaken van de taak. Lege string als er geen naam is 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

    Progress van de taak. Als de taak nog niet is gestart, is deze eigenschap 0. 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, is deze eigenschap 0.

  • Name
    finished_at
    Type
    timestamp
    Description

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

  • 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 referentie van het task_error-object.

  • 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 die fase in rekening gebracht. Een taak die nooit wordt aangemaakt (een 4xx op het moment van het verzoek, inclusief een afwijzing door moderation) wordt helemaal niet in rekening gebracht. Een taak die FAILED bereikt, geeft 0 terug — het bedrag wordt terugbetaald, ook bij een asynchrone blokkade door moderation. Annuleren via DELETE betaalt alleen terug zolang de taak nog PENDING is; een taak die al IN_PROGRESS is, blijft in rekening gebracht, omdat het werk al is verricht.

  • Name
    image_urls
    Type
    array of strings
    Description

    Downloadbare URL van de render van het uiteindelijke keycap-ontwerp — hoe de kandidaat eruitziet als 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 build-endpoint gebruikt candidate_ids, niet deze URL's. Dezelfde URL-levenscyclus als model_urls: ondertekend, geen Authorization-header, geldig tot expires_at, en stabiel wanneer de taak opnieuw wordt uitgelezen.

  • Name
    candidate_ids
    Type
    array of strings
    Description

    Ondoorzichtige kandidaat-identifiers, parallel aan image_urls. Geef het item dat overeenkomt met je gekozen ontwerp door als candidate_id van het buildverzoek. Doe geen aannames over het formaat van deze id's.

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

Het Keycap Build Task-object

Het Keycap Build Task-object is een werkeenheid die Meshy bijhoudt om de uiteindelijke getextureerde 3D-keycap te genereren op basis van een geslaagde prototype-task en een gekozen kandidaat. Eén build doorloopt de volledige pipeline — white-model- generatie, automatisch passend maken en snijden, kleuring, assemblage en export.

Eigenschappen

  • Name
    id
    Type
    string
    Description

    Unieke identifier voor de task.

  • Name
    type
    Type
    string
    Description

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

  • Name
    name
    Type
    string
    Description

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

  • Name
    status
    Type
    string
    Description

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

  • Name
    progress
    Type
    integer
    Description

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

  • Name
    created_at
    Type
    timestamp
    Description

    Tijdstempel van het moment waarop de task is aangemaakt, in milliseconden.

  • Name
    started_at
    Type
    timestamp
    Description

    Tijdstempel van het moment waarop de task is gestart, in milliseconden.

  • Name
    finished_at
    Type
    timestamp
    Description

    Tijdstempel van het moment waarop de task is voltooid, in milliseconden.

  • Name
    expires_at
    Type
    timestamp
    Description

    Tijdstempel van het moment waarop het taakresultaat verloopt, in milliseconden.

  • Name
    preceding_tasks
    Type
    integer
    Description

    Het aantal voorgaande tasks. Alleen relevant wanneer status PENDING is.

  • Name
    task_error
    Type
    object
    Description

    Foutdetails voor mislukte tasks. Zie Fouten voor de volledige referentie van het task_error-object.

  • Name
    consumed_credits
    Type
    integer
    Description

    Het aantal credits dat door deze task is verbruikt. Een task die SUCCEEDED bereikt, wordt volledig in rekening gebracht voor de betreffende fase. Een task die nooit wordt aangemaakt (een 4xx op het moment van de aanvraag, inclusief een afwijzing door moderation) wordt helemaal niet in rekening gebracht. Een task die FAILED bereikt, geeft 0 terug — de kosten worden terugbetaald, ook bij een asynchrone blokkering door moderation. Annuleren via DELETE betaalt de kosten alleen terug zolang de task nog PENDING is; een task die al IN_PROGRESS is, blijft in rekening gebracht, omdat het werk al is uitgevoerd.

  • Name
    model_urls
    Type
    object
    Description

    Downloadbare URL's voor de gegenereerde modelbestanden. Zowel de GLB- als de OBJ-bundel worden geëxporteerd op schaal van echte millimeters, Y-omhoog, met de voorkant van de keycap gericht op +Z. Meshes hebben de namen 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 er niet van uit dat er precies twee meshes zijn.

    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 uitlezen van de task binnen dat venster levert dezelfde URL op in plaats van een nieuw ondertekende. Download en bewaar de bestanden zelf vóór die tijd — er is geen manier om een verlopen link te vernieuwen.

    • Name
      glb
      Type
      string
      Description

      Downloadbare URL naar de definitieve getextureerde model.glb.

    • Name
      obj_zip
      Type
      string
      Description

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

  • Name
    process_image_urls
    Type
    object
    Description

    Downloadbare URL's voor tussentijdse procesafbeeldingen, gesleuteld op type. Dezelfde URL-levenscyclus als model_urls: ondertekend, geen Authorization-header, geldig tot expires_at, en stabiel wanneer de task opnieuw wordt uitgelezen. Momenteel geleverde typen:

    • head_design — de door de build gebruikte ontwerpafbeelding van de gekozen kandidaat (altijd aanwezig).
    • composite — de render van de afgewerkte keycap van de gekozen kandidaat (aanwezig indien beschikbaar).
    • base_canvas — het beschilderde canvas van de keycap-basis (aanwezig indien beschikbaar).

    Beschouw de set sleutels als open voor uitbreiding; er kunnen nieuwe typen worden toegevoegd zonder een breaking change.

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

End-to-End Example

De volledige flow: maak een prototype van een foto, poll deze tot SUCCEEDED, kies een kandidaat uit candidate_ids, maak een build met die kandidaat, poll de build tot SUCCEEDED, en download vervolgens de GLB- en de OBJ-bundel via model_urls.

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