Entwickler

API-Referenz

Jeder Endpunkt hier nimmt JSON über HTTPS und einen API-Schlüssel im Authorization-Header. Ein Schlüssel arbeitet in einem Arbeitsbereich und erreicht nur die Endpunkte, die seine Scopes erlauben.

Aktualisiert am 1. Oktober 2026

Die API ist dieselbe, die auch die Gradiently-App nutzt. Ein Schlüssel sieht also dieselben Daten und durchläuft dieselben Prüfungen wie sein Ersteller in der App, beschränkt auf einen Arbeitsbereich und seine Scopes. Ein Schlüssel, der einen Endpunkt aufruft, den keiner seiner Scopes abdeckt, bekommt 403.

Basis-URL und Authentifizierung

Alle Pfade unten liegen unter https://gradiently.design. Schick deinen Schlüssel bei jeder Anfrage als Bearer-Token mit. Anfragekörper sind JSON mit Content-Type: application/json, außer bei Uploads.

bash
curl https://gradiently.design/api/marks/mine \
  -H "Authorization: Bearer gr_live_…"
  • Ein Schlüssel ist immer an den Arbeitsbereich gebunden, in dem er erstellt wurde. Du musst den Arbeitsbereich nicht angeben; wenn du X-Workspace oder ?workspace= schickst, muss es der des Schlüssels sein, sonst scheitert die Anfrage mit 403.
  • Anfragekörper werden streng geprüft: Ein Feld, das der Endpunkt nicht kennt, führt zu 422.
  • Antworten sind JSON, sofern nicht anders angegeben (Bilder, Weiterleitungen und der Stream des Designers). Fehlermeldungen an API-Schlüssel sind auf Englisch.
  • Ein Schlüssel handelt als sein Ersteller. Designs und Marken, die er erstellt, gehören dem Arbeitsbereich; Marks, die er sichert, hält sein Ersteller.

Arbeitsbereich

MethodePfadScopeWas er tut
GET/api/meworkspaces:read und designs:readDu, der Arbeitsbereich des Schlüssels und seine Marken.
GET/api/workspacesworkspaces:readDer Arbeitsbereich des Schlüssels und deine Rolle.
GET/api/workspaces/:idworkspaces:readEin Arbeitsbereich.
GET/api/workspaces/:id/membersworkspaces:readMitglieder mit Name, E-Mail und Rolle.
GET/api/workspaces/:id/auditworkspaces:readDas Audit-Log des Arbeitsbereichs.
POST/api/workspaces/:id/invitesmembers:writeVerschickt per E-Mail eine sieben Tage gültige Einladung.
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": "…" }]
}
Gekürzt. Marken heißen in der API personalities.
json
POST /api/workspaces/:id/invites
{ "email": "sam@example.com", "role": "editor" }

{ "id": "…", "expiresInDays": 7 }
role ist admin, editor oder viewer. Die Person muss dieselbe E-Mail-Adresse bestätigen, bevor sie annimmt.

Marken

MethodePfadScopeWas er tut
GET/api/personalitiesdesigns:readDie Marken des Arbeitsbereichs, als { items }.
POST/api/personalitiespersonalities:writeErstellt eine Marke.
PATCH/api/personalities/:idpersonalities:writeBenennt eine Marke um, setzt ihren Mark, ihr Profil oder ihren Stil.
DELETE/api/personalities/:idpersonalities:writeLöscht eine Marke und ihre Designs. Ein Arbeitsbereich behält mindestens eine.
GET/api/personalities/:id/designsdesigns:readDie Designs einer Marke, die neuesten zuerst.
GET/api/personalities/:id/branddesigns:readDie Schriften, Logos und gespeicherten Farben einer Marke. Ein Schlüssel kann sie lesen, aber nie ändern.
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 ist beim Erstellen optional. Ein Profil kann außerdem audience, uses, keywords, dos, donts, website, handle und fonts enthalten.

Die Designliste nimmt ?q= für die Suche in Titeln und ?mark= als Filter nach Mark. Jeder Eintrag hat id, personalityId, markId, title, form, thumb, shared und updatedAt, ohne das Dokument.

Designs

MethodePfadScopeWas er tut
POST/api/agent/composedesigns:writeSetzt Text, remixt eine Vorlage oder wendet Änderungen an, und speichert.
POST/api/designsdesigns:writeErstellt ein Design aus einem Dokument.
GET/api/designs/:iddesigns:readEin Design mit seinem Dokument.
PATCH/api/designs/:iddesigns:writeÄndert Titel, Dokument, Mark oder Freigabe.
DELETE/api/designs/:iddesigns:writeLöscht ein Design.
POST/api/designs/:id/duplicatedesigns:writeSpeichert eine Kopie daneben.
GET/api/designs/:id/thumbdesigns:readSein Vorschaubild.
POST/api/designs/:id/renderdesigns:readRendert es als PNG oder PDF.

Am einfachsten erstellst du ein Design per Code mit POST /api/agent/compose: Du beschreibst den Inhalt, und die Layout-Engine platziert ihn mit dem Mark der Marke. Derselbe Endpunkt remixt eine Vorlage (template mit text, photos, icons, hide) oder bearbeitet mit designId und ops ein gespeichertes Design.

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 listet, was die Prüfung gefunden hat (Ränder, Überschneidungen, Hierarchie, Kontrast).
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 ist optional; ohne diese Angabe trägt das Design den Mark der Marke. Lies ein Design mit GET /api/designs/:id, um ein vollständiges Dokument zu sehen.

PATCH /api/designs/:id nimmt beliebige von title, doc, markId und shared. Wenn du shared auf true setzt, wird ein Ansichtslink unter /d/:id veröffentlicht. Schick baseUpdatedAt, also das updatedAt, das du zuletzt gelesen hast, damit das Speichern mit 409 abgelehnt wird, falls jemand das Design inzwischen geändert hat.

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 }
Breite und Höhe liegen zwischen 1 und 4096. page zählt ab 0; ein PDF ohne page enthält jede Seite, jeweils in ihrer Größe aus dem Studio, zu der die Anfrage passen muss. Rechne mit bis zu drei Minuten.

Zum Rendern braucht es für den Mark des Designs dieselbe Exportlizenz wie im Studio; ohne sie lautet die Antwort 402. Beim Rendern wird das Design nie veröffentlicht und keine Datei gespeichert.

Uploads

MethodePfadScopeWas er tut
POST/api/uploadsdesigns:writeLädt ein Bild für Designs hoch.
GET/api/uploadsdesigns:readDie Uploads des Arbeitsbereichs, die neuesten zuerst.
GET/api/uploads/:iddesigns:readLeitet zum Bild weiter. ?w= fragt eine Breite an.
DELETE/api/uploads/:iddesigns:writeLöscht einen deiner 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/…" }
Eine Datei im Feld file: PNG, JPEG, WebP, GIF oder AVIF, höchstens 8 MB, mit einem Typ, der zum Inhalt passt. Nutze die zurückgegebene url als src eines Bildes oder als Foto in einer Vorlage.

Marks

MethodePfadScopeWas er tut
GET/api/marksmarks:readDurchsucht den Markt.
GET/api/marks/:codemarks:readEin Mark mit seinem Rezept, per Code oder ID.
GET/api/marks/minemarks:readMarks, die für den Arbeitsbereich gehalten werden, und deine Entwürfe darin.
POST/api/agent/markmarks:readBaut oder bearbeitet ein Rezept und prüft es. Speichert nichts.
POST/api/marksbrand:generateSpeichert ein Rezept als Mark-Entwurf.
PATCH/api/marks/:idbrand:generateÄndert einen Entwurf, den du gemacht hast.
POST/api/marks/:code/claimmarks:claimSichert einen verfügbaren Mark.
POST/api/marks/:code/buymarks:claimSichert einen Mark, den ein anderer Inhaber anbietet.

GET /api/marks nimmt q (Name oder Code), tone (dark oder light), material, status (listed, house oder sale) und cursor. Die Antwort ist { "items": [ … ], "nextCursor": "…" } mit 24 Marks pro Seite. Ein Mark hat id, code, name, recipe, status, creator, holder und createdAt.

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

{ "id": "…", "code": "GR·K7Q2·MX", "name": "Night Harbour", "status": "draft", "recipe": { … } }
Ein gültiges recipe bekommst du von POST /api/agent/mark mit einer spec. Mit personalityId wird der Entwurf in dieser Marke gespeichert. Ohne sie speichert ein Schlüssel den Entwurf in der ersten Marke seines Arbeitsbereichs und scheitert mit 404, wenn es keine gibt. Eine Person kann bis zu 50 Entwürfe haben.

Gesichert wird immer für den Ersteller des Schlüssels, nie für den Arbeitsbereich. Kostenloses Sichern und Sichern, das durch ein Guthaben zum Sichern gedeckt ist, wird sofort abgeschlossen. Braucht das Sichern eine Zahlung, antwortet es mit 402 und checkout: true, und buy antwortet mit 409 und checkout: true; schließ diese Fälle in Gradiently ab, denn ein Schlüssel kann nicht bezahlen. buy nimmt { "priceCents": … }, den angebotenen Preis, den du gesehen hast, und scheitert mit 409, wenn er sich geändert hat.

Versionen von Marks

MethodePfadScopeWas er tut
GET/api/marks/:code/versionsmarks:readVersionen, die neuesten zuerst, als { items, next, canEdit }.
GET/api/marks/:code/versions/:vidmarks:readEine Version.
POST/api/marks/:code/versionsbrand:generateSpeichert eine Version: { label, recipe }, beides optional.
PATCH/api/marks/:code/versions/:vidbrand:generateBenennt um oder vergibt einen Stern: { label, starred }.
DELETE/api/marks/:code/versions/:vidbrand:generateLöscht eine Version.
POST/api/marks/:code/versions/:vid/restorebrand:generateMacht die Version wieder zum Entwurf.

Markengenerierung

MethodePfadScopeWas er tut
POST/api/brand/generatebrand:generateGibt Markenvorschläge zurück. Schreibt nichts.
POST/api/brand/adoptbrand:generateErstellt aus einem Vorschlag einen Mark-Entwurf, eine Marke und drei Startdesigns.
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": [ … ] }
Übernimm mit genau der Eingabe, die den Vorschlag erzeugt hat. Der Server erzeugt die Vorschläge neu und vertraut nie einem Rezept vom Client.

Der Designer

MethodePfadScopeWas er tut
POST/api/agentdesigns:writeEin Durchgang des Designers, gestreamt als zeilengetrenntes JSON.
POST/api/batchesdesigns:writeStartet eine Reihe von Designs aus einem Briefing.
GET/api/batchesdesigns:readDeine Reihen, laufende und kürzliche.
GET/api/batches/:iddesigns:readDer Fortschritt einer Reihe.
DELETE/api/batches/:iddesigns:writeStoppt eine Reihe. Fertige Designs bleiben.
GET/api/agent/runs?designId=designs:readDurchgänge des Designers, die für ein Design noch laufen.
DELETE/api/agent/runs/:iddesigns:writeStoppt einen laufenden Durchgang.
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": "…" }] }
Bis zu zwölf Einträge. Frag GET /api/batches/:id regelmäßig ab; jeder Eintrag bekommt eine designId und eine url, sobald er gespeichert ist. state endet als done, stopped oder failed.

Der Designer verbraucht die KI-Credits des Arbeitsbereichs. Liegt das Guthaben unter dem, was ein Durchgang braucht, antworten /api/agent und /api/batches mit 402 und code: "credits". Pro Person laufen höchstens zwei Reihen gleichzeitig. Das Werkzeug design unter MCP und KI-Assistenten liest den Stream des Designers und speichert das Ergebnis für dich, was einfacher ist, als den Stream selbst zu verarbeiten.

Fehler

Ein Fehler antwortet mit einem Statuscode und einem JSON-Körper mit einer lesbaren Meldung in error. Manche fügen Felder hinzu, die unten genannt sind. Die einzige Ausnahme ist /api/mcp: Ein Körper, der kein gültiges JSON ist, antwortet mit 400 und stattdessen einem JSON-RPC-Fehlerobjekt, { "jsonrpc": "2.0", "id": null, "error": { "code": -32700, "message": "Parse error" } }.

json
{ "error": "API key lacks required scope for this endpoint." }
StatusWann
401Kein Schlüssel, ein fehlerhafter Schlüssel oder ein Schlüssel, der widerrufen ist oder dessen Ersteller kein Inhaber oder Admin mehr ist.
402Eine Zahlung oder Credits sind nötig: ein Sichern mit Preis (checkout: true), keine Exportlizenz oder zu wenige KI-Credits (code: "credits").
403Dem Schlüssel fehlt ein Scope, er gehört zu einem anderen Arbeitsbereich, oder die Rolle seines Erstellers erlaubt die Aktion nicht.
404Der Eintrag existiert nicht, oder der Schlüssel kann ihn nicht sehen.
409Ein Konflikt: Der Eintrag hat sich geändert, seit du ihn gelesen hast, ein Name ist vergeben, oder die Aktion braucht einen Checkout.
422Die Anfrage hat die Validierung nicht bestanden. Die Meldung sagt, welches Feld und warum.
429Zu viele Anfragen. Warte die Sekunden aus Retry-After ab und versuch es noch mal.
503Ausgelastet oder vorübergehend nicht verfügbar, zum Beispiel der Designer oder Exporte. Beachte Retry-After.
504Ein Rendering hat zu lange gedauert. Versuch eine kleinere Größe oder eine einzelne Seite.

Ratenlimits

Limits zählen über ein gleitendes Fenster von einer Minute, sofern nicht anders angegeben. Wer darüber liegt, bekommt 429 mit einem Header Retry-After in Sekunden und einem Feld retryAfter im Körper. Werde langsamer und versuch es nach dieser Zeit erneut; wiederhole die Anfrage nicht sofort.

LimitKontingent
Jede Anfrage mit einem Schlüssel120 pro Minute und Schlüssel
Schreibzugriffe (POST, PATCH, DELETE)90 pro Minute und Konto, gemeinsam mit der App
Renderings10 pro Minute und Konto
Neue Designs und Duplikate60 pro Minute und Konto
Uploads60 pro Minute und Konto
Sichern20 alle zehn Minuten und 100 pro Tag und Konto
Einladungen30 pro Stunde und Konto

Exporte und der Designer haben außerdem eine gemeinsame Kapazität. Ist sie ausgeschöpft, lautet die Antwort 503 oder 429 mit Retry-After, auch wenn du unter deinen eigenen Limits liegst. Über MCP zählt ein Werkzeugaufruf einmal für die MCP-Anfrage und einmal für jede API-Anfrage, die das Werkzeug stellt.

Paginierung

Listen liefern eine Seite nach der anderen. Die nächste Seite fragst du mit ?cursor= an.

  • Suche im Markt (/api/marks): 24 pro Seite. Gib den nextCursor aus der Antwort mit; auf der letzten Seite ist er null.
  • Versionen von Marks: Gib den Wert next aus der Antwort mit; auf der letzten Seite ist er null.
  • Designs einer Marke: 100 pro Seite, die neuesten zuerst. Gib die id des letzten Designs mit, das du bekommen hast.
  • Uploads: 60 pro Seite, die neuesten zuerst. Gib die id des letzten Uploads mit.
  • Marken, Arbeitsbereiche, Mitglieder und das Audit-Log: 100 pro Seite. Gib die id des letzten Eintrags mit (userId bei Mitgliedern). Marken werden über /api/personalities als { items } aufgelistet.

Schlüssel, Scopes und Rotation findest du unter API-Schlüssel und Scopes. Fehlt ein Endpunkt, den du brauchst, sag uns Bescheid.

Brauchst du Hilfe?

Schick uns eine Anfrage mit dem Thema „API und MCP“, und ein Mensch antwortet dir.

Anfrage senden