L’API est celle qu’utilise l’application Gradiently : une clé voit donc les mêmes données et passe les mêmes contrôles que son créateur dans l’application, dans la limite d’un espace de travail et de ses permissions. Une clé qui appelle un point de terminaison qu’aucune de ses permissions ne couvre reçoit une erreur 403.
URL de base et authentification
Tous les chemins ci-dessous se trouvent sous https://gradiently.design. Envoyez votre clé comme jeton bearer avec chaque requête. Les corps sont en JSON avec Content-Type: application/json, sauf pour les imports.
curl https://gradiently.design/api/marks/mine \
-H "Authorization: Bearer gr_live_…"- Une clé est toujours liée à l’espace de travail où elle a été créée. Inutile de nommer l’espace de travail ; si vous envoyez
X-Workspaceou?workspace=, ce doit être celui de la clé, sinon la requête échoue avec 403. - Les corps de requête sont vérifiés strictement : un champ que le point de terminaison ne connaît pas échoue avec 422.
- Les réponses sont en JSON, sauf indication contraire (images, redirections et flux du Designer). Les messages d’erreur adressés aux clés API sont en anglais.
- Une clé agit au nom de son créateur. Les créations et marques qu’elle réalise appartiennent à l’espace de travail ; les Marks qu’elle réserve sont détenus par son créateur.
Espace de travail
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| GET | /api/me | workspaces:read et designs:read | Vous, l’espace de travail de la clé et ses marques. |
| GET | /api/workspaces | workspaces:read | L’espace de travail de la clé et votre rôle. |
| GET | /api/workspaces/:id | workspaces:read | Un espace de travail. |
| GET | /api/workspaces/:id/members | workspaces:read | Les membres avec leur nom, leur e-mail et leur rôle. |
| GET | /api/workspaces/:id/audit | workspaces:read | Le journal d’audit de l’espace de travail. |
| POST | /api/workspaces/:id/invites | members:write | Envoie par e-mail une invitation valable sept jours. |
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 vaut admin, editor ou viewer. La personne doit vérifier la même adresse e-mail avant d’accepter.Marques
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| GET | /api/personalities | designs:read | Les marques de l’espace de travail, sous la forme { items }. |
| POST | /api/personalities | personalities:write | Crée une marque. |
| PATCH | /api/personalities/:id | personalities:write | Renomme une marque, définit son Mark, son profil ou son style. |
| DELETE | /api/personalities/:id | personalities:write | Supprime une marque et ses créations. Un espace de travail en garde au moins une. |
| GET | /api/personalities/:id/designs | designs:read | Les créations d’une marque, de la plus récente à la plus ancienne. |
| GET | /api/personalities/:id/brand | designs:read | Les polices, les logos et les couleurs enregistrées d’une marque. Une clé peut les lire, jamais les modifier. |
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 est facultatif à la création. Un profil peut aussi contenir audience, uses, keywords, dos, donts, website, handle et fonts.La liste des créations accepte ?q= pour chercher dans les titres et ?mark= pour filtrer par Mark. Chaque élément contient id, personalityId, markId, title, form, thumb, shared et updatedAt, sans le document.
Créations
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| POST | /api/agent/compose | designs:write | Met en page du texte, réinterprète un modèle ou applique des modifications, puis enregistre. |
| POST | /api/designs | designs:write | Crée une création à partir d’un document. |
| GET | /api/designs/:id | designs:read | Une création avec son document. |
| PATCH | /api/designs/:id | designs:write | Modifie son titre, son document, son Mark ou son partage. |
| DELETE | /api/designs/:id | designs:write | Supprime une création. |
| POST | /api/designs/:id/duplicate | designs:write | Enregistre une copie à côté. |
| GET | /api/designs/:id/thumb | designs:read | Sa miniature. |
| POST | /api/designs/:id/render | designs:read | La rend en PNG ou en PDF. |
Le plus simple pour réaliser une création depuis le code est POST /api/agent/compose : vous décrivez le contenu et le moteur de mise en page le place avec le Mark de la marque. Le même point de terminaison réinterprète un modèle (template avec text, photos, icons, hide) ou, avec designId et ops, modifie une création enregistrée.
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 liste ce que la vérification a relevé (marges, chevauchements, hiérarchie, contraste).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 est facultatif ; sans lui, la création porte le Mark de la marque. Lisez une création avec GET /api/designs/:id pour voir un document complet.PATCH /api/designs/:id accepte title, doc, markId et shared, dans n’importe quelle combinaison. Passer shared à true publie un lien de consultation à /d/:id. Envoyez baseUpdatedAt, la valeur updatedAt que vous avez lue en dernier, pour que l’enregistrement soit refusé avec 409 si quelqu’un a modifié la création entre-temps.
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 compte à partir de 0 ; un PDF sans page contient toutes les pages, chacune à sa taille dans le Studio, à laquelle la requête doit correspondre. Prévoyez jusqu’à trois minutes.Le rendu exige la même licence d’export pour le Mark de la création que dans le Studio ; sans elle, la réponse est 402. Le rendu ne publie jamais la création et ne stocke aucun fichier.
Imports
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| POST | /api/uploads | designs:write | Importe une image pour les créations. |
| GET | /api/uploads | designs:read | Les imports de l’espace de travail, du plus récent au plus ancien. |
| GET | /api/uploads/:id | designs:read | Redirige vers l’image. ?w= demande une largeur. |
| DELETE | /api/uploads/:id | designs:write | Supprime l’un de vos imports. |
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 ou AVIF, 8 Mo au plus, avec un type qui correspond à son contenu. Utilisez l’url renvoyée comme src d’image ou comme photo de modèle.Marks
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| GET | /api/marks | marks:read | Recherche dans le Marché. |
| GET | /api/marks/:code | marks:read | Un Mark avec sa recette, par code ou par id. |
| GET | /api/marks/mine | marks:read | Les Marks détenus pour l’espace de travail, et vos brouillons qui s’y trouvent. |
| POST | /api/agent/mark | marks:read | Construit ou modifie une recette et la vérifie. N’enregistre rien. |
| POST | /api/marks | brand:generate | Enregistre une recette comme Mark brouillon. |
| PATCH | /api/marks/:id | brand:generate | Modifie un brouillon que vous avez créé. |
| POST | /api/marks/:code/claim | marks:claim | Réserve un Mark disponible. |
| POST | /api/marks/:code/buy | marks:claim | Réserve un Mark mis en vente par un autre détenteur. |
GET /api/marks accepte q (nom ou code), tone (dark ou light), material, status (listed, house ou sale) et cursor. La réponse est { "items": [ … ], "nextCursor": "…" }, avec 24 Marks par page. Un Mark contient id, code, name, recipe, status, creator, holder et createdAt.
POST /api/marks
{ "name": "Night Harbour", "recipe": { … }, "personalityId": "…" }
{ "id": "…", "code": "GR·K7Q2·MX", "name": "Night Harbour", "status": "draft", "recipe": { … } }recipe valide avec POST /api/agent/mark et un spec. personalityId enregistre le brouillon dans cette marque. Sans lui, une clé enregistre le brouillon dans la première marque de son espace de travail, et échoue avec 404 s’il n’y en a aucune. Une personne peut garder jusqu’à 50 brouillons.Une réservation est faite pour le créateur de la clé, jamais pour l’espace de travail. Les réservations gratuites, et celles couvertes par un crédit de réservation, aboutissent immédiatement. Une réservation qui demande un paiement répond 402 avec checkout: true, et buy répond 409 avec checkout: true ; terminez-les dans Gradiently, car une clé ne peut pas payer. buy accepte { "priceCents": … }, le prix affiché que vous avez vu, et échoue avec 409 s’il a changé.
Versions de Marks
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| GET | /api/marks/:code/versions | marks:read | Les versions, de la plus récente à la plus ancienne, sous la forme { items, next, canEdit }. |
| GET | /api/marks/:code/versions/:vid | marks:read | Une version. |
| POST | /api/marks/:code/versions | brand:generate | Enregistre une version : { label, recipe }, tous deux facultatifs. |
| PATCH | /api/marks/:code/versions/:vid | brand:generate | Renomme ou marque d’une étoile : { label, starred }. |
| DELETE | /api/marks/:code/versions/:vid | brand:generate | Supprime une version. |
| POST | /api/marks/:code/versions/:vid/restore | brand:generate | Rétablit la version comme brouillon. |
Génération de marque
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| POST | /api/brand/generate | brand:generate | Renvoie des propositions de marque. N’écrit rien. |
| POST | /api/brand/adopt | brand:generate | Crée un Mark brouillon, une marque et trois créations de départ à partir d’une proposition. |
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": [ … ] }Le Designer
| Méthode | Chemin | Permission | Ce qu’il fait |
|---|---|---|---|
| POST | /api/agent | designs:write | Un tour du Designer, diffusé en JSON délimité par des sauts de ligne. |
| POST | /api/batches | designs:write | Lance une série de créations à partir d’un seul brief. |
| GET | /api/batches | designs:read | Vos séries, en cours et récentes. |
| GET | /api/batches/:id | designs:read | La progression d’une série. |
| DELETE | /api/batches/:id | designs:write | Arrête une série. Les créations déjà dessinées restent. |
| GET | /api/agent/runs?designId= | designs:read | Les tours du Designer encore en cours pour une création. |
| DELETE | /api/agent/runs/:id | designs:write | Arrête un tour en cours. |
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 ; chaque élément reçoit un designId et une url une fois enregistré. state se termine par done, stopped ou failed.Le Designer consomme les crédits IA de l’espace de travail. Quand le solde est inférieur à ce qu’exige un tour, /api/agent et /api/batches répondent 402 avec code: "credits". Deux séries au plus tournent en même temps par personne. L’outil design de MCP et assistants IA lit le flux du Designer et enregistre le résultat pour vous, ce qui est plus simple que de gérer le flux vous-même.
Erreurs
Une erreur répond avec un code de statut et un corps JSON contenant un message error lisible. Certaines ajoutent des champs, indiqués ci-dessous. Seule exception, /api/mcp : un corps qui n’est pas du JSON valide répond 400 avec un objet d’erreur JSON-RPC à la place, { "jsonrpc": "2.0", "id": null, "error": { "code": -32700, "message": "Parse error" } }.
{ "error": "API key lacks required scope for this endpoint." }| Statut | Quand |
|---|---|
| 401 | Aucune clé, une clé mal formée, ou une clé révoquée ou dont le créateur n’est plus propriétaire ou admin. |
| 402 | Un paiement ou des crédits sont nécessaires : une réservation payante (checkout: true), pas de licence d’export, ou des crédits IA insuffisants (code: "credits"). |
| 403 | Il manque une permission à la clé, elle appartient à un autre espace de travail, ou le rôle de son créateur n’autorise pas l’action. |
| 404 | L’élément n’existe pas ou la clé ne peut pas le voir. |
| 409 | Un conflit : l’élément a changé depuis votre lecture, un nom est déjà pris, ou l’action doit passer par le paiement. |
| 422 | La requête n’a pas passé la validation. Le message indique quel champ et pourquoi. |
| 429 | Trop de requêtes. Attendez le nombre de secondes indiqué dans Retry-After et réessayez. |
| 503 | Occupé ou temporairement indisponible, par exemple le Designer ou les exports. Respectez Retry-After. |
| 504 | Un rendu a pris trop de temps. Essayez une taille plus petite ou une seule page. |
Limites de débit
Sauf mention contraire, les limites se comptent sur une fenêtre glissante d’une minute. Les dépasser renvoie 429 avec un en-tête Retry-After en secondes et un champ retryAfter dans le corps. Ralentissez et réessayez après ce délai ; ne réessayez pas tout de suite.
| Limite | Quota |
|---|---|
| Chaque requête avec une clé | 120 par minute et par clé |
| Écritures (POST, PATCH, DELETE) | 90 par minute et par compte, partagées avec l’application |
| Rendus | 10 par minute et par compte |
| Nouvelles créations et duplications | 60 par minute et par compte |
| Imports | 60 par minute et par compte |
| Réservations | 20 toutes les dix minutes et 100 par jour et par compte |
| Invitations | 30 par heure et par compte |
Les exports et le Designer ont aussi une capacité partagée. Quand elle est saturée, la réponse est 503 ou 429 avec Retry-After, même sous vos propres limites. Via MCP, un appel d’outil compte une fois pour la requête MCP, puis une fois pour chaque requête API que fait l’outil.
Pagination
Les listes renvoient une page à la fois. Demandez la page suivante avec ?cursor=.
- Recherche dans le Marché (
/api/marks) : 24 par page. Passez lenextCursorde la réponse ; il vaut null sur la dernière page. - Versions de Marks : passez la valeur
nextde la réponse ; elle vaut null sur la dernière page. - Créations d’une marque : 100 par page, de la plus récente à la plus ancienne. Passez l’
idde la dernière création reçue. - Imports : 60 par page, du plus récent au plus ancien. Passez l’
iddu dernier import. - Marques, espaces de travail, membres et journal d’audit : 100 par page. Passez l’
iddu dernier élément (userIdpour les membres). Les marques sont listées par/api/personalitiessous la forme{ items }.
Les clés, les permissions et leur renouvellement sont traités dans Clés API et permissions. S’il vous manque un point de terminaison, dites-le-nous.

