Ontwikkelaars

API-referentie

Elk endpoint hier accepteert JSON via HTTPS en een API-key in de Authorization-header. Een key werkt in één workspace en bereikt alleen de endpoints die zijn rechten toestaan.

Bijgewerkt 1 oktober 2026

De API is dezelfde die de Gradiently-app gebruikt, dus een key ziet dezelfde gegevens en doorloopt dezelfde controles als zijn maker in de app, beperkt tot één workspace en tot zijn rechten. Een key die een endpoint aanroept dat door geen van zijn rechten wordt gedekt, krijgt een 403.

Basis-URL en authenticatie

Alle paden hieronder vallen onder https://gradiently.design. Stuur je key bij elke request mee als bearer-token. Bodies zijn JSON met Content-Type: application/json, behalve bij uploads.

bash
curl https://gradiently.design/api/marks/mine \
  -H "Authorization: Bearer gr_live_…"
  • Een key is altijd gebonden aan de workspace waarin hij is aangemaakt. Je hoeft de workspace niet te noemen; stuur je X-Workspace of ?workspace= mee, dan moet dat die van de key zijn, anders faalt de request met 403.
  • Request-bodies worden streng gecontroleerd: een veld dat het endpoint niet kent, faalt met 422.
  • Antwoorden zijn JSON, tenzij anders vermeld (afbeeldingen, redirects en de stream van de Designer). Foutmeldingen aan API-keys zijn in het Engels.
  • Een key handelt als zijn maker. Ontwerpen en merken die hij maakt, horen bij de workspace; Marks die hij claimt, staan op naam van zijn maker.

Workspace

MethodePadRechtWat het doet
GET/api/meworkspaces:read en designs:readJij, de workspace van de key en de merken ervan.
GET/api/workspacesworkspaces:readDe workspace van de key en jouw rol.
GET/api/workspaces/:idworkspaces:readEén workspace.
GET/api/workspaces/:id/membersworkspaces:readLeden met naam, e-mailadres en rol.
GET/api/workspaces/:id/auditworkspaces:readHet auditlog van de workspace.
POST/api/workspaces/:id/invitesmembers:writeMailt een uitnodiging die zeven dagen geldig is.
json
GET /api/me

{
  "viewer": { "id": "…", "name": "Ada Moss", "handle": "ada", "workspaceId": "…" },
  "workspaces": [{ "id": "…", "name": "Hearth", "role": "owner" }],
  "activeWorkspaceId": "…",
  "personalities": [{ "id": "…", "slug": "hearth", "name": "Hearth", "markId": "…" }]
}
Ingekort. In de API heten merken personalities.
json
POST /api/workspaces/:id/invites
{ "email": "sam@example.com", "role": "editor" }

{ "id": "…", "expiresInDays": 7 }
role is admin, editor of viewer. De persoon moet hetzelfde e-mailadres bevestigen voordat hij de uitnodiging kan accepteren.

Merken

MethodePadRechtWat het doet
GET/api/personalitiesdesigns:readDe merken van de workspace, als { items }.
POST/api/personalitiespersonalities:writeMaakt een merk.
PATCH/api/personalities/:idpersonalities:writeHernoemt een merk, of stelt de Mark, het profiel of de stijl in.
DELETE/api/personalities/:idpersonalities:writeVerwijdert een merk en de ontwerpen ervan. Een workspace houdt er altijd minstens één.
GET/api/personalities/:id/designsdesigns:readDe ontwerpen van een merk, de nieuwste eerst.
GET/api/personalities/:id/branddesigns:readDe lettertypen, logo’s en opgeslagen kleuren van een merk. Een key kan ze lezen, nooit wijzigen.
json
POST /api/personalities
{ "name": "Hearth Bakery", "markId": "…" }

PATCH /api/personalities/:id
{ "profile": { "about": "A neighbourhood bakery", "voice": "warm, plain" } }

{ "id": "…", "slug": "hearth-bakery", "name": "Hearth Bakery", "markId": "…", "profile": { … } }
markId is bij het aanmaken optioneel. Een profiel kan ook audience, uses, keywords, dos, donts, website, handle en fonts bevatten.

De lijst met ontwerpen accepteert ?q= om op titel te zoeken en ?mark= om op Mark te filteren. Elk item heeft id, personalityId, markId, title, form, thumb, shared en updatedAt, zonder het document.

Ontwerpen

MethodePadRechtWat het doet
POST/api/agent/composedesigns:writeMaakt de opmaak van tekst, remixt een template of past bewerkingen toe, en slaat op.
POST/api/designsdesigns:writeMaakt een ontwerp van een document.
GET/api/designs/:iddesigns:readEen ontwerp met zijn document.
PATCH/api/designs/:iddesigns:writeWijzigt de titel, het document, de Mark of het delen.
DELETE/api/designs/:iddesigns:writeVerwijdert een ontwerp.
POST/api/designs/:id/duplicatedesigns:writeSlaat er een kopie naast op.
GET/api/designs/:id/thumbdesigns:readDe miniatuur ervan.
POST/api/designs/:id/renderdesigns:readRendert het naar PNG of PDF.

De makkelijkste manier om vanuit code een ontwerp te maken is POST /api/agent/compose: je beschrijft de inhoud en de layout-engine plaatst die met de Mark van het merk. Hetzelfde endpoint remixt een template (template met text, photos, icons, hide) of bewerkt, met designId en ops, een opgeslagen ontwerp.

json
POST /api/agent/compose
{
  "personalityId": "…",
  "composition": {
    "size": "ig-post",
    "layout": "statement",
    "blocks": [
      { "role": "headline", "text": "Fresh bread from 7am" },
      { "role": "cta", "text": "Visit us" }
    ]
  }
}

{ "id": "…", "url": "/studio/…", "issues": [ … ], "elements": [ … ] }
issues somt op wat de beoordeling vond (marges, overlappingen, hiërarchie, contrast).
json
POST /api/designs
{
  "personalityId": "…",
  "form": "blank",
  "title": "Launch post",
  "doc": { "ratio": "custom", "width": 1080, "height": 1350, "shift": [0.5, 0.5, 0.5, 0.5], "elements": [] }
}

{ "id": "…", "personalityId": "…", "markId": null, "title": "Launch post", "form": "blank", "doc": { … }, "updatedAt": "…", "thumb": null, "shared": false }
markId is optioneel; zonder krijgt het ontwerp de Mark van het merk. Lees een ontwerp via GET /api/designs/:id om een volledig document te zien.

PATCH /api/designs/:id accepteert title, doc, markId en shared, in elke combinatie. Zet je shared op true, dan wordt er een bekijklink gepubliceerd op /d/:id. Stuur baseUpdatedAt mee, de updatedAt die je het laatst las, om het opslaan met 409 te laten weigeren als iemand het ontwerp intussen heeft gewijzigd.

json
POST /api/designs/:id/render
{ "width": 1080, "height": 1350, "format": "png", "page": 0 }

{ "id": "…", "data": "iVBORw0KGgo…", "encoding": "base64", "mimeType": "image/png", "width": 1080, "height": 1350, "pages": 1 }
Breedte en hoogte zijn 1 tot 4096. page telt vanaf 0; een PDF zonder page bevat alle pagina’s, elk op het formaat uit de Studio, waar de request bij moet passen. Reken op maximaal drie minuten.

Voor renderen is dezelfde exportlicentie voor de Mark van het ontwerp nodig als in de Studio; zonder licentie is het antwoord 402. Renderen publiceert het ontwerp nooit en slaat geen bestand op.

Uploads

MethodePadRechtWat het doet
POST/api/uploadsdesigns:writeUploadt een afbeelding voor ontwerpen.
GET/api/uploadsdesigns:readDe uploads van de workspace, de nieuwste eerst.
GET/api/uploads/:iddesigns:readStuurt door naar de afbeelding. ?w= vraagt om een breedte.
DELETE/api/uploads/:iddesigns:writeVerwijdert een van je uploads.
bash
curl https://gradiently.design/api/uploads \
  -H "Authorization: Bearer $GRADIENTLY_API_KEY" \
  -F "file=@shopfront.jpg;type=image/jpeg"

# { "id": "…", "url": "/api/uploads/…" }
Eén bestand in het veld file: PNG, JPEG, WebP, GIF of AVIF, hoogstens 8 MB, met een type dat bij de inhoud past. Gebruik de teruggegeven url als src van een afbeelding of als foto in een template.

Marks

MethodePadRechtWat het doet
GET/api/marksmarks:readDoorzoekt de Markt.
GET/api/marks/:codemarks:readEén Mark met zijn recept, op code of id.
GET/api/marks/minemarks:readMarks die voor de workspace worden gehouden, en je concepten erin.
POST/api/agent/markmarks:readBouwt of bewerkt een recept en beoordeelt het. Slaat niets op.
POST/api/marksbrand:generateSlaat een recept op als concept-Mark.
PATCH/api/marks/:idbrand:generateWijzigt een concept dat jij hebt gemaakt.
POST/api/marks/:code/claimmarks:claimClaimt een beschikbare Mark.
POST/api/marks/:code/buymarks:claimClaimt een Mark die een andere eigenaar te koop heeft gezet.

GET /api/marks accepteert q (naam of code), tone (dark of light), material, status (listed, house of sale) en cursor. Het antwoordt met { "items": [ … ], "nextCursor": "…" }, 24 Marks per pagina. Een Mark heeft id, code, name, recipe, status, creator, holder en createdAt.

json
POST /api/marks
{ "name": "Night Harbour", "recipe": { … }, "personalityId": "…" }

{ "id": "…", "code": "GR·K7Q2·MX", "name": "Night Harbour", "status": "draft", "recipe": { … } }
Haal een geldig recipe op via POST /api/agent/mark met een spec. Met personalityId wordt het concept in dat merk opgeslagen. Zonder dat veld slaat een key het concept op in het eerste merk van zijn workspace, en mislukt de request met 404 als er geen is. Iemand kan tot 50 concepten bewaren.

Een claim wordt gedaan voor de maker van de key, nooit voor de workspace. Gratis claims, en claims die worden gedekt door een claimtegoed, zijn meteen rond. Een claim waarvoor betaald moet worden, antwoordt met 402 en checkout: true, en buy antwoordt met 409 en checkout: true; rond die af in Gradiently, want een key kan niet betalen. buy accepteert { "priceCents": … }, de vraagprijs die je zag, en faalt met 409 als die is veranderd.

Markversies

MethodePadRechtWat het doet
GET/api/marks/:code/versionsmarks:readVersies, de nieuwste eerst, als { items, next, canEdit }.
GET/api/marks/:code/versions/:vidmarks:readEén versie.
POST/api/marks/:code/versionsbrand:generateSlaat een versie op: { label, recipe }, allebei optioneel.
PATCH/api/marks/:code/versions/:vidbrand:generateHernoemt of geeft een ster: { label, starred }.
DELETE/api/marks/:code/versions/:vidbrand:generateVerwijdert een versie.
POST/api/marks/:code/versions/:vid/restorebrand:generateZet de versie terug als concept.

Merken genereren

MethodePadRechtWat het doet
POST/api/brand/generatebrand:generateGeeft merkkandidaten terug. Schrijft niets weg.
POST/api/brand/adoptbrand:generateMaakt van één kandidaat een concept-Mark, een merk en drie startontwerpen.
json
POST /api/brand/generate
{ "name": "Hearth", "description": "A neighbourhood bakery", "tone": ["calm", "warm"], "count": 4 }

[{ "key": "…", "name": "Hearth One", "recipe": { … }, "personality": { "name": "Hearth", "handle": "…" }, "starters": [ … ], "why": "…" }]

POST /api/brand/adopt
{ "input": { "name": "Hearth", "description": "A neighbourhood bakery", "tone": ["calm", "warm"], "count": 4 }, "key": "…" }

{ "mark": { … }, "personality": { … }, "designs": [ … ] }
Neem over met precies de invoer die de kandidaat heeft gemaakt. De server maakt de kandidaten opnieuw en vertrouwt nooit een recept van de client.

De Designer

MethodePadRechtWat het doet
POST/api/agentdesigns:writeEén beurt van de Designer, gestreamd als JSON met één object per regel.
POST/api/batchesdesigns:writeStart een reeks ontwerpen vanuit één briefing.
GET/api/batchesdesigns:readJe reeksen, lopend en recent.
GET/api/batches/:iddesigns:readDe voortgang van een reeks.
DELETE/api/batches/:iddesigns:writeStopt een reeks. Getekende ontwerpen blijven bestaan.
GET/api/agent/runs?designId=designs:readBeurten van de Designer die voor een ontwerp nog lopen.
DELETE/api/agent/runs/:iddesigns:writeStopt een lopende beurt.
json
POST /api/batches
{
  "personalityId": "…",
  "see": false,
  "plan": {
    "brief": "Autumn menu launch, Saturday 4 October",
    "items": [
      { "size": "ig-post", "brief": "The announcement" },
      { "size": "ig-story", "brief": "Three new loaves, one line each" }
    ]
  }
}

{ "id": "…", "state": "running", "items": [{ "index": 0, "title": "…", "state": "…" }] }
Maximaal twaalf items. Vraag GET /api/batches/:id regelmatig op; elk item krijgt een designId en url zodra het is opgeslagen. state eindigt als done, stopped of failed.

De Designer gebruikt de AI-credits van de workspace. Is het saldo lager dan wat een beurt nodig heeft, dan antwoorden /api/agent en /api/batches met 402 en code: "credits". Per persoon lopen er hoogstens twee reeksen tegelijk. De tool design op MCP en AI-assistenten leest de stream van de Designer en slaat het resultaat voor je op, wat eenvoudiger is dan de stream zelf verwerken.

Fouten

Een fout antwoordt met een statuscode en een JSON-body met een leesbare error-melding. Sommige voegen velden toe, die hieronder worden genoemd. De enige uitzondering is /api/mcp: een body die geen geldige JSON is, antwoordt 400 met in plaats daarvan een JSON-RPC-foutobject, { "jsonrpc": "2.0", "id": null, "error": { "code": -32700, "message": "Parse error" } }.

json
{ "error": "API key lacks required scope for this endpoint." }
StatusWanneer
401Geen key, een ongeldige key, of een key die is ingetrokken of waarvan de maker geen eigenaar of beheerder meer is.
402Er is betaling of tegoed nodig: een claim met een prijs (checkout: true), geen exportlicentie, of te weinig AI-credits (code: "credits").
403De key mist een recht, hoort bij een andere workspace, of de rol van zijn maker staat de actie niet toe.
404Het item bestaat niet of de key kan het niet zien.
409Een conflict: het item is veranderd sinds je het las, een naam is al in gebruik, of de actie vraagt om afrekenen.
422De request kwam niet door de validatie. De melding zegt welk veld en waarom.
429Te veel requests. Wacht het aantal seconden uit Retry-After af en probeer het opnieuw.
503Druk of tijdelijk niet beschikbaar, bijvoorbeeld de Designer of exports. Respecteer Retry-After.
504Een render duurde te lang. Probeer een kleiner formaat of één pagina.

Limieten

Limieten tellen over een verschuivend venster van één minuut, tenzij anders vermeld. Ga je eroverheen, dan krijg je 429 met een Retry-After-header in seconden en een veld retryAfter in de body. Vertraag en probeer het na die tijd opnieuw; probeer het niet meteen opnieuw.

LimietToegestaan
Elke request met een key120 per minuut per key
Schrijfacties (POST, PATCH, DELETE)90 per minuut per account, gedeeld met de app
Renders10 per minuut per account
Nieuwe ontwerpen en duplicaten60 per minuut per account
Uploads60 per minuut per account
Claims20 per tien minuten en 100 per dag per account
Uitnodigingen30 per uur per account

Exports en de Designer hebben daarnaast een gedeelde capaciteit. Is die vol, dan is het antwoord 503 of 429 met Retry-After, ook als je binnen je eigen limieten blijft. Via MCP telt een toolaanroep één keer voor de MCP-request en één keer voor elke API-request die de tool doet.

Paginering

Lijsten geven één pagina tegelijk terug. Vraag de volgende pagina op met ?cursor=.

  • Zoeken in de Markt (/api/marks): 24 per pagina. Geef de nextCursor uit het antwoord mee; op de laatste pagina is die null.
  • Markversies: geef de waarde next uit het antwoord mee; op de laatste pagina is die null.
  • Ontwerpen van een merk: 100 per pagina, de nieuwste eerst. Geef het id mee van het laatste ontwerp dat je ontving.
  • Uploads: 60 per pagina, de nieuwste eerst. Geef het id van de laatste upload mee.
  • Merken, workspaces, leden en het auditlog: 100 per pagina. Geef het id van het laatste item mee (userId voor leden). Merken worden weergegeven via /api/personalities als { items }.

Keys, rechten en vervangen staan op API-keys en rechten. Staat een endpoint dat je nodig hebt hier niet bij, laat het ons weten.

Hulp nodig?

Stuur ons een verzoek met het onderwerp API en MCP, en een mens antwoordt je.

Een verzoek sturen