A API é a mesma que a app do Gradiently usa, por isso uma chave vê os mesmos dados e passa pelas mesmas verificações que o seu criador passaria na app, limitada a um espaço de trabalho e aos seus âmbitos. Uma chave que chama um endpoint que nenhum dos seus âmbitos cobre recebe um 403.
URL base e autenticação
Todos os caminhos abaixo estão em https://gradiently.design. Envia a tua chave como token bearer em cada pedido. Os corpos são JSON com Content-Type: application/json, exceto nos carregamentos.
curl https://gradiently.design/api/marks/mine \
-H "Authorization: Bearer gr_live_…"- Uma chave está sempre ligada ao espaço de trabalho em que foi criada. Não precisas de indicar o espaço de trabalho; se enviares
X-Workspaceou?workspace=, tem de ser o da própria chave, senão o pedido falha com 403. - Os corpos dos pedidos são verificados de forma estrita: um campo que o endpoint não conhece falha com 422.
- As respostas são JSON salvo indicação em contrário (imagens, redirecionamentos e o fluxo do Designer). As mensagens de erro para chaves de API estão em inglês.
- Uma chave atua como o seu criador. Os designs e marcas que cria pertencem ao espaço de trabalho; os Marks que reserva ficam com o seu criador.
Espaço de trabalho
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| GET | /api/me | workspaces:read e designs:read | Tu, o espaço de trabalho da chave e as suas marcas. |
| GET | /api/workspaces | workspaces:read | O espaço de trabalho da chave e a tua função. |
| GET | /api/workspaces/:id | workspaces:read | Um espaço de trabalho. |
| GET | /api/workspaces/:id/members | workspaces:read | Membros com nome, email e função. |
| GET | /api/workspaces/:id/audit | workspaces:read | O registo de auditoria do espaço de trabalho. |
| POST | /api/workspaces/:id/invites | members:write | Envia por email um convite válido por sete dias. |
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 é admin, editor ou viewer. A pessoa tem de verificar o mesmo endereço de email antes de aceitar.Marcas
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| GET | /api/personalities | designs:read | As marcas do espaço de trabalho, como { items }. |
| POST | /api/personalities | personalities:write | Cria uma marca. |
| PATCH | /api/personalities/:id | personalities:write | Renomeia uma marca, define o seu Mark, perfil ou estilo. |
| DELETE | /api/personalities/:id | personalities:write | Elimina uma marca e os seus designs. Um espaço de trabalho fica sempre com pelo menos uma. |
| GET | /api/personalities/:id/designs | designs:read | Os designs de uma marca, do mais recente para o mais antigo. |
| GET | /api/personalities/:id/brand | designs:read | Os tipos de letra, os logótipos e as cores guardadas de uma marca. Uma chave pode lê-los, nunca alterá-los. |
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 é opcional ao criar. Um perfil também pode ter audience, uses, keywords, dos, donts, website, handle e fonts.A lista de designs aceita ?q= para pesquisar títulos e ?mark= para filtrar por Mark. Cada item tem id, personalityId, markId, title, form, thumb, shared e updatedAt, sem o documento.
Designs
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| POST | /api/agent/compose | designs:write | Pagina texto, remistura um modelo ou aplica edições, e guarda. |
| POST | /api/designs | designs:write | Cria um design a partir de um documento. |
| GET | /api/designs/:id | designs:read | Um design com o seu documento. |
| PATCH | /api/designs/:id | designs:write | Altera o título, o documento, o Mark ou a partilha. |
| DELETE | /api/designs/:id | designs:write | Elimina um design. |
| POST | /api/designs/:id/duplicate | designs:write | Guarda uma cópia ao lado. |
| GET | /api/designs/:id/thumb | designs:read | A sua miniatura. |
| POST | /api/designs/:id/render | designs:read | Gera-o em PNG ou PDF. |
A forma mais fácil de criar um design a partir de código é POST /api/agent/compose: descreves o conteúdo e o motor de paginação coloca-o com o Mark da marca. O mesmo endpoint remistura um modelo (template com text, photos, icons, hide) ou, com designId e ops, edita um design guardado.
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 lista o que a revisão encontrou (margens, sobreposições, hierarquia, 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 é opcional; sem ele, o design usa o Mark da marca. Lê um design com GET /api/designs/:id para ver um documento completo.PATCH /api/designs/:id aceita qualquer um de title, doc, markId e shared. Definir shared como true publica um link de visualização em /d/:id. Envia baseUpdatedAt, o updatedAt que leste por último, para recusar a gravação com 409 se alguém tiver alterado o design entretanto.
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 conta a partir de 0; um PDF sem page tem todas as páginas, cada uma no seu tamanho do Estúdio, a que o pedido tem de corresponder. Conta com até três minutos.Gerar precisa da mesma licença de exportação para o Mark do design que o Estúdio; sem ela, a resposta é 402. A geração nunca publica o design nem guarda um ficheiro.
Carregamentos
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| POST | /api/uploads | designs:write | Carrega uma imagem para designs. |
| GET | /api/uploads | designs:read | Os carregamentos do espaço de trabalho, do mais recente para o mais antigo. |
| GET | /api/uploads/:id | designs:read | Redireciona para a imagem. ?w= pede uma largura. |
| DELETE | /api/uploads/:id | designs:write | Elimina um dos teus carregamentos. |
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, no máximo 8 MB, com um tipo que corresponda ao conteúdo. Usa o url devolvido como src de uma imagem ou como foto de um modelo.Marks
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| GET | /api/marks | marks:read | Pesquisa o Mercado. |
| GET | /api/marks/:code | marks:read | Um Mark com a sua receita, por código ou id. |
| GET | /api/marks/mine | marks:read | Os Marks detidos para o espaço de trabalho, e os teus rascunhos nele. |
| POST | /api/agent/mark | marks:read | Constrói ou edita uma receita e revê-a. Não guarda nada. |
| POST | /api/marks | brand:generate | Guarda uma receita como Mark em rascunho. |
| PATCH | /api/marks/:id | brand:generate | Altera um rascunho que criaste. |
| POST | /api/marks/:code/claim | marks:claim | Reserva um Mark disponível. |
| POST | /api/marks/:code/buy | marks:claim | Reserva um Mark que outro detentor pôs à venda. |
GET /api/marks aceita q (nome ou código), tone (dark ou light), material, status (listed, house ou sale) e cursor. Responde { "items": [ … ], "nextCursor": "…" } com 24 Marks por página. Um Mark tem id, code, name, recipe, status, creator, holder e createdAt.
POST /api/marks
{ "name": "Night Harbour", "recipe": { … }, "personalityId": "…" }
{ "id": "…", "code": "GR·K7Q2·MX", "name": "Night Harbour", "status": "draft", "recipe": { … } }recipe válida com POST /api/agent/mark e um spec. personalityId guarda o rascunho nessa marca. Sem ele, uma chave guarda o rascunho na primeira marca do seu espaço de trabalho, e falha com 404 se não houver nenhuma. Uma pessoa pode ter até 50 rascunhos.Uma reserva é feita para o criador da chave, nunca para o espaço de trabalho. As reservas grátis, e as cobertas por um crédito de reserva, ficam concluídas de imediato. Uma reserva que exija pagamento responde 402 com checkout: true, e buy responde 409 com checkout: true; conclui-as no Gradiently, porque uma chave não pode pagar. buy aceita { "priceCents": … }, o preço indicado que viste, e falha com 409 se tiver mudado.
Versões de Marks
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| GET | /api/marks/:code/versions | marks:read | Versões, da mais recente para a mais antiga, como { items, next, canEdit }. |
| GET | /api/marks/:code/versions/:vid | marks:read | Uma versão. |
| POST | /api/marks/:code/versions | brand:generate | Guarda uma versão: { label, recipe }, ambos opcionais. |
| PATCH | /api/marks/:code/versions/:vid | brand:generate | Renomeia ou marca com estrela: { label, starred }. |
| DELETE | /api/marks/:code/versions/:vid | brand:generate | Elimina uma versão. |
| POST | /api/marks/:code/versions/:vid/restore | brand:generate | Repõe a versão como rascunho. |
Geração de marcas
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| POST | /api/brand/generate | brand:generate | Devolve propostas de marca. Não escreve nada. |
| POST | /api/brand/adopt | brand:generate | Cria um Mark em rascunho, uma marca e três designs iniciais a partir de uma proposta. |
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": [ … ] }O Designer
| Método | Caminho | Âmbito | O que faz |
|---|---|---|---|
| POST | /api/agent | designs:write | Um turno do Designer, transmitido como JSON delimitado por novas linhas. |
| POST | /api/batches | designs:write | Inicia um conjunto de designs a partir de um só briefing. |
| GET | /api/batches | designs:read | Os teus conjuntos, em curso e recentes. |
| GET | /api/batches/:id | designs:read | O progresso de um conjunto. |
| DELETE | /api/batches/:id | designs:write | Para um conjunto. Os designs já desenhados ficam. |
| GET | /api/agent/runs?designId= | designs:read | Os turnos do Designer ainda em curso para um design. |
| DELETE | /api/agent/runs/:id | designs:write | Para um turno em curso. |
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 periodicamente; cada item ganha um designId e um url assim que é guardado. state termina como done, stopped ou failed.O Designer gasta os créditos de IA do espaço de trabalho. Quando o saldo é inferior ao que um turno precisa, /api/agent e /api/batches respondem 402 com code: "credits". No máximo, correm dois conjuntos de cada vez por pessoa. A ferramenta design em MCP e assistentes de IA lê o fluxo do Designer e guarda o resultado por ti, o que é mais simples do que tratares tu do fluxo.
Erros
Um erro responde com um código de estado e um corpo JSON com uma mensagem error legível. Alguns acrescentam campos, indicados abaixo. A única exceção é /api/mcp: um corpo que não seja JSON válido responde 400 com um objeto de erro JSON-RPC em vez disso, { "jsonrpc": "2.0", "id": null, "error": { "code": -32700, "message": "Parse error" } }.
{ "error": "API key lacks required scope for this endpoint." }| Estado | Quando |
|---|---|
| 401 | Sem chave, uma chave malformada, ou uma chave revogada ou cujo criador já não é proprietário nem admin. |
| 402 | É preciso pagamento ou créditos: uma reserva com preço (checkout: true), sem licença de exportação, ou créditos de IA insuficientes (code: "credits"). |
| 403 | Falta um âmbito à chave, a chave pertence a outro espaço de trabalho, ou a função do seu criador não permite a ação. |
| 404 | O item não existe ou a chave não o consegue ver. |
| 409 | Um conflito: o item mudou desde que o leste, um nome já está ocupado, ou a ação precisa de checkout. |
| 422 | O pedido não passou na validação. A mensagem diz qual o campo e porquê. |
| 429 | Demasiados pedidos. Espera os segundos indicados em Retry-After e tenta novamente. |
| 503 | Ocupado ou temporariamente indisponível, por exemplo o Designer ou as exportações. Respeita o Retry-After. |
| 504 | Uma geração demorou demasiado. Experimenta um tamanho menor ou uma só página. |
Limites de pedidos
Os limites contam numa janela deslizante de um minuto, salvo indicação em contrário. Ultrapassá-los responde 429 com um cabeçalho Retry-After em segundos e um campo retryAfter no corpo. Abranda e tenta novamente depois desse tempo; não tentes de imediato.
| Limite | Quota |
|---|---|
| Cada pedido com uma chave | 120 por minuto por chave |
| Escritas (POST, PATCH, DELETE) | 90 por minuto por conta, partilhados com a app |
| Gerações | 10 por minuto por conta |
| Novos designs e duplicados | 60 por minuto por conta |
| Carregamentos | 60 por minuto por conta |
| Reservas | 20 a cada dez minutos e 100 por dia por conta |
| Convites | 30 por hora por conta |
As exportações e o Designer têm também uma capacidade partilhada. Quando está cheia, a resposta é 503 ou 429 com Retry-After, mesmo dentro dos teus próprios limites. Por MCP, uma chamada de ferramenta conta uma vez pelo pedido MCP e uma vez por cada pedido à API que a ferramenta faz.
Paginação
As listas devolvem uma página de cada vez. Pede a página seguinte com ?cursor=.
- Pesquisa no Mercado (
/api/marks): 24 por página. Passa onextCursorda resposta; é null na última página. - Versões de Marks: passa o valor
nextda resposta; é null na última página. - Designs de uma marca: 100 por página, do mais recente para o mais antigo. Passa o
iddo último design que recebeste. - Carregamentos: 60 por página, do mais recente para o mais antigo. Passa o
iddo último carregamento. - Marcas, espaços de trabalho, membros e registo de auditoria: 100 por página. Passa o
iddo último item (userIdpara membros). As marcas são listadas em/api/personalitiescomo{ items }.
As chaves, os âmbitos e a rotação estão em Chaves de API e âmbitos. Se um endpoint de que precisas não estiver aqui, avisa-nos.

