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.
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-Workspaceof?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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| GET | /api/me | workspaces:read en designs:read | Jij, de workspace van de key en de merken ervan. |
| GET | /api/workspaces | workspaces:read | De workspace van de key en jouw rol. |
| GET | /api/workspaces/:id | workspaces:read | Eén workspace. |
| GET | /api/workspaces/:id/members | workspaces:read | Leden met naam, e-mailadres en rol. |
| GET | /api/workspaces/:id/audit | workspaces:read | Het auditlog van de workspace. |
| POST | /api/workspaces/:id/invites | members:write | Mailt een uitnodiging die zeven dagen geldig is. |
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": "…" }]
}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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| GET | /api/personalities | designs:read | De merken van de workspace, als { items }. |
| POST | /api/personalities | personalities:write | Maakt een merk. |
| PATCH | /api/personalities/:id | personalities:write | Hernoemt een merk, of stelt de Mark, het profiel of de stijl in. |
| DELETE | /api/personalities/:id | personalities:write | Verwijdert een merk en de ontwerpen ervan. Een workspace houdt er altijd minstens één. |
| GET | /api/personalities/:id/designs | designs:read | De ontwerpen van een merk, de nieuwste eerst. |
| GET | /api/personalities/:id/brand | designs:read | De lettertypen, logo’s en opgeslagen kleuren van een merk. Een key kan ze lezen, nooit wijzigen. |
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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| POST | /api/agent/compose | designs:write | Maakt de opmaak van tekst, remixt een template of past bewerkingen toe, en slaat op. |
| POST | /api/designs | designs:write | Maakt een ontwerp van een document. |
| GET | /api/designs/:id | designs:read | Een ontwerp met zijn document. |
| PATCH | /api/designs/:id | designs:write | Wijzigt de titel, het document, de Mark of het delen. |
| DELETE | /api/designs/:id | designs:write | Verwijdert een ontwerp. |
| POST | /api/designs/:id/duplicate | designs:write | Slaat er een kopie naast op. |
| GET | /api/designs/:id/thumb | designs:read | De miniatuur ervan. |
| POST | /api/designs/:id/render | designs:read | Rendert 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.
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).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.
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 }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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| POST | /api/uploads | designs:write | Uploadt een afbeelding voor ontwerpen. |
| GET | /api/uploads | designs:read | De uploads van de workspace, de nieuwste eerst. |
| GET | /api/uploads/:id | designs:read | Stuurt door naar de afbeelding. ?w= vraagt om een breedte. |
| DELETE | /api/uploads/:id | designs:write | Verwijdert een van je uploads. |
curl https://gradiently.design/api/uploads \
-H "Authorization: Bearer $GRADIENTLY_API_KEY" \
-F "file=@shopfront.jpg;type=image/jpeg"
# { "id": "…", "url": "/api/uploads/…" }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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| GET | /api/marks | marks:read | Doorzoekt de Markt. |
| GET | /api/marks/:code | marks:read | Eén Mark met zijn recept, op code of id. |
| GET | /api/marks/mine | marks:read | Marks die voor de workspace worden gehouden, en je concepten erin. |
| POST | /api/agent/mark | marks:read | Bouwt of bewerkt een recept en beoordeelt het. Slaat niets op. |
| POST | /api/marks | brand:generate | Slaat een recept op als concept-Mark. |
| PATCH | /api/marks/:id | brand:generate | Wijzigt een concept dat jij hebt gemaakt. |
| POST | /api/marks/:code/claim | marks:claim | Claimt een beschikbare Mark. |
| POST | /api/marks/:code/buy | marks:claim | Claimt 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.
POST /api/marks
{ "name": "Night Harbour", "recipe": { … }, "personalityId": "…" }
{ "id": "…", "code": "GR·K7Q2·MX", "name": "Night Harbour", "status": "draft", "recipe": { … } }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
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| GET | /api/marks/:code/versions | marks:read | Versies, de nieuwste eerst, als { items, next, canEdit }. |
| GET | /api/marks/:code/versions/:vid | marks:read | Eén versie. |
| POST | /api/marks/:code/versions | brand:generate | Slaat een versie op: { label, recipe }, allebei optioneel. |
| PATCH | /api/marks/:code/versions/:vid | brand:generate | Hernoemt of geeft een ster: { label, starred }. |
| DELETE | /api/marks/:code/versions/:vid | brand:generate | Verwijdert een versie. |
| POST | /api/marks/:code/versions/:vid/restore | brand:generate | Zet de versie terug als concept. |
Merken genereren
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| POST | /api/brand/generate | brand:generate | Geeft merkkandidaten terug. Schrijft niets weg. |
| POST | /api/brand/adopt | brand:generate | Maakt van één kandidaat een concept-Mark, een merk en drie startontwerpen. |
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": [ … ] }De Designer
| Methode | Pad | Recht | Wat het doet |
|---|---|---|---|
| POST | /api/agent | designs:write | Eén beurt van de Designer, gestreamd als JSON met één object per regel. |
| POST | /api/batches | designs:write | Start een reeks ontwerpen vanuit één briefing. |
| GET | /api/batches | designs:read | Je reeksen, lopend en recent. |
| GET | /api/batches/:id | designs:read | De voortgang van een reeks. |
| DELETE | /api/batches/:id | designs:write | Stopt een reeks. Getekende ontwerpen blijven bestaan. |
| GET | /api/agent/runs?designId= | designs:read | Beurten van de Designer die voor een ontwerp nog lopen. |
| DELETE | /api/agent/runs/:id | designs:write | Stopt een lopende beurt. |
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": "…" }] }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" } }.
{ "error": "API key lacks required scope for this endpoint." }| Status | Wanneer |
|---|---|
| 401 | Geen key, een ongeldige key, of een key die is ingetrokken of waarvan de maker geen eigenaar of beheerder meer is. |
| 402 | Er is betaling of tegoed nodig: een claim met een prijs (checkout: true), geen exportlicentie, of te weinig AI-credits (code: "credits"). |
| 403 | De key mist een recht, hoort bij een andere workspace, of de rol van zijn maker staat de actie niet toe. |
| 404 | Het item bestaat niet of de key kan het niet zien. |
| 409 | Een conflict: het item is veranderd sinds je het las, een naam is al in gebruik, of de actie vraagt om afrekenen. |
| 422 | De request kwam niet door de validatie. De melding zegt welk veld en waarom. |
| 429 | Te veel requests. Wacht het aantal seconden uit Retry-After af en probeer het opnieuw. |
| 503 | Druk of tijdelijk niet beschikbaar, bijvoorbeeld de Designer of exports. Respecteer Retry-After. |
| 504 | Een 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.
| Limiet | Toegestaan |
|---|---|
| Elke request met een key | 120 per minuut per key |
| Schrijfacties (POST, PATCH, DELETE) | 90 per minuut per account, gedeeld met de app |
| Renders | 10 per minuut per account |
| Nieuwe ontwerpen en duplicaten | 60 per minuut per account |
| Uploads | 60 per minuut per account |
| Claims | 20 per tien minuten en 100 per dag per account |
| Uitnodigingen | 30 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 denextCursoruit het antwoord mee; op de laatste pagina is die null. - Markversies: geef de waarde
nextuit het antwoord mee; op de laatste pagina is die null. - Ontwerpen van een merk: 100 per pagina, de nieuwste eerst. Geef het
idmee van het laatste ontwerp dat je ontving. - Uploads: 60 per pagina, de nieuwste eerst. Geef het
idvan de laatste upload mee. - Merken, workspaces, leden en het auditlog: 100 per pagina. Geef het
idvan het laatste item mee (userIdvoor leden). Merken worden weergegeven via/api/personalitiesals{ 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.

