docs · breadcrumb / api
A API do Lutrix
O Lutrix é criação e edição de imagens API/MCP-first: tudo que dá pra fazer no editor também dá por API REST ou direto do Claude via MCP. O diferencial é gerar imagens em lote a partir de um template (data-merge) — 1 arte por linha de dados.
API REST
Endpoints de projetos, export e assets.
Data-merge
Um template → mil peças por linha de dados.
Skills p/ agentes
SKILL.md universal — baixe ou cole em qualquer IA.
conceitos
Visão geral
A hierarquia é Organização → Workspaces → Projetos. Cada projeto guarda um design document (textos, formas, imagens). A partir dele você exporta um PNG ou usa como template para gerar várias peças de uma vez.
Toda requisição roda isolada por organização (multi-tenant por RLS): uma API key só enxerga e altera dados da própria org.
acesso
Autenticação
Gere uma API key no app (painel Chaves de API em /app) — ela aparece uma única vez. Envie no header X-Api-Key. A base URL é https://lutrix-api-739d.onrender.com.
curl -s https://lutrix-api-739d.onrender.com/workspaces \
-H "X-Api-Key: lutrix_sk_xxx"
# Sem chave → HTTP 401rest
API REST
Endpoints principais (todos exigem a API key):
Workspaces
GET/workspaceslista os workspaces da orgPOST/workspacescria — corpo { name }GET/workspaces/roleseu papel na orgDELETE/workspaces/:widexclui (e seus projetos, em cascata)Projetos
GET/workspaces/:wid/projectslista projetosPOST/workspaces/:wid/projectscria — { name, width?, height? }GET/workspaces/:wid/projects/:pidcarrega (com o design document)PUT/workspaces/:wid/projects/:pid/docsubstitui o design documentPOST/workspaces/:wid/projects/:pid/exportrenderiza PNG → { url } (1 crédito)POST/workspaces/:wid/projects/:pid/exportsexport multi-formato — { format, pageIds? } (png/jpg/svg/pdf; 1 créd/página)POST/workspaces/:wid/projects/:pid/previewprévia low-res (carimbo "Prévia") → { url } (grátis)GET/workspaces/:wid/projects/:pid/preflightauditoria do design antes de exportar (grátis)GET/workspaces/:wid/projects/:pid/fieldscampos {{...}} do templatePOST/workspaces/:wid/projects/:pid/mergedata-merge → { results }DELETE/workspaces/:wid/projects/:pidexclui o projetoMarca (kit de marca)
GET/workspaces/:wid/brand-kitlê o kit de marca do workspacePUT/workspaces/:wid/brand-kitsalva o kit — { colors, fonts, logos, voice } (Estúdio)GET/workspaces/:wid/brand-kit/briefbrief pronto p/ a IA (paleta, fontes, voz)Assets & créditos
POST/assetsupload de imagem (multipart)POST/assets/from-urlimporta por URL — { url }POST/assets/remove-backgroundremove o fundo (5 créditos)GET/creditssaldo → { balance }# Criar um projeto 1080x1080
curl -s -X POST $API/workspaces/$WS/projects \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
-d '{"name":"Campanha","width":1080,"height":1080}'
# Exportar PNG (devolve uma URL assinada do R2)
curl -s -X POST $API/workspaces/$WS/projects/$PID/export \
-H "X-Api-Key: $KEY"diferencial
Data-merge (geração em lote)
Coloque marcadores {{campo}} nos textos. Envie N linhas → o Lutrix devolve 1 PNG por linha.
curl -s -X POST $API/workspaces/$WS/projects/$PID/merge \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
-d '{"rows":[
{"nome":"Ana","preco":"R$ 10"},
{"nome":"Bruno","preco":"R$ 20"}
]}'
# → { "results": [ {"index":0,"url":"..."}, ... ] }Custo: 1 crédito por peça gerada.
ia
Remover fundo
Remoção por IA. Passe a URL pública de uma imagem; devolve um asset já salvo.
curl -s -X POST $API/assets/remove-background \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
-d '{"imageUrl":"https://.../foto.png"}'Custo: 5 créditos.
agentes
Skill universal (qualquer IA)
Uma skill portátil no padrão aberto Agent Skills (um SKILL.md): qualquer agente de IA lê e ganha a capacidade de operar o Lutrix pela API. Baixe o arquivo ou copie o conteúdo direto pro seu agente.
O pacote .zip traz a pasta lutrix/ (SKILL.md + README + mcp.json + exemplos) — é só soltar em .claude/skills/. English: SKILL.md · .zip
Ver o SKILL.md completo
---
name: lutrix
description: >-
Cria, edita, exporta e gera imagens em lote (data-merge) no Lutrix — uma
plataforma de design estilo Canva, feita para agentes — pela API REST ou pelo
servidor MCP. Use quando o usuário quiser montar imagens/posts programaticamente
a partir de um documento de design (JSON), preencher um template com dados para
produzir várias peças de uma vez, exportar PNG/JPG/SVG/PDF, gerar imagens por IA,
remover fundo, ou gerenciar projetos de design. A autenticação é uma API key por
organização, enviada no header X-Api-Key.
license: MIT
metadata:
homepage: https://lutrix.app
docs: https://lutrix.app/docs
---
# Lutrix — criação de design via API/MCP
Lutrix é uma plataforma de design **API/MCP-first** (como o Canva, mas feita para
agentes de IA). Tudo que o editor visual faz também dá por HTTP.
## Modelo mental
- Hierarquia: **Organização → Workspaces → Projetos**.
- Um **projeto** guarda um **documento de design** (JSON): uma ou mais **páginas**,
cada uma um canvas com uma lista de **nós** (texto, formas, imagens, vetores).
- A partir do projeto você **exporta** uma imagem (PNG/JPG/SVG/PDF) **ou** usa como
**template** e faz **data-merge**: 1 imagem por linha de dados.
- Tudo é isolado por organização (multi-tenant). Uma API key só enxerga a própria org.
## Fluxo recomendado ao criar com IA
1. **Consulte a marca** — `lutrix_get_brand_kit` (ou GET /workspaces/:id/brand-kit/brief): baseie cores, fontes e voz na identidade do cliente. Para **configurar/atualizar** o kit (plano Estúdio), use `lutrix_set_brand_kit` — logos exigem `assetKey` (suba a imagem antes).
2. **Monte o design** — `lutrix_set_project_doc`.
3. **Mostre a prévia** — `lutrix_render_preview`: devolve a imagem (carimbada "Prévia"), **grátis**. **Exiba ao usuário** para ele aprovar antes de gastar crédito.
4. **Meça** — `GET .../measure` (grátis): as caixas REAIS de cada nó. É o passo que pega texto que não coube (quebrou ou vazou) e elementos sobrepostos — coisas que não dá para prever ao escrever o doc, porque dependem da fonte e do tracking. Corrija com os números e meça de novo.
5. **Audite** — `lutrix_preflight` (grátis): conserte os `warn` (fora da página, baixo contraste, cor/fonte fora do kit de marca).
6. **Só então exporte** — `lutrix_export_png`/exports: o export é o **único** passo que gasta **1 crédito por peça**.
> Prévia, medição e pré-voo **não gastam crédito** — itere à vontade; cobra-se só no export final aprovado. Geração de imagem por IA gasta crédito por tentativa (o prompt é do cliente).
## Setup
- **Base URL:** `https://lutrix-api-739d.onrender.com`
- **Auth:** envie o header `X-Api-Key: lutrix_sk_...` em TODA requisição. Crie uma
chave no app em `https://lutrix.app/app` (painel *Chaves de API*) — ela aparece **uma vez só**.
Sem chave / chave inválida → `401`.
- Corpos são JSON (`Content-Type: application/json`), exceto uploads de arquivo
(`multipart/form-data`).
## Começo rápido (criar → preencher → exportar)
```bash
API="https://lutrix-api-739d.onrender.com"; KEY="lutrix_sk_..."
# 1. escolher um workspace existente
WS=$(curl -s $API/workspaces -H "X-Api-Key: $KEY" | jq -r '.[0].id')
# 2. criar um projeto 1080x1080
PID=$(curl -s -X POST $API/workspaces/$WS/projects \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
-d '{"name":"Promo","width":1080,"height":1080}' | jq -r '.id')
# 3. definir o documento de design (texto com campo {{nome}})
curl -s -X PUT $API/workspaces/$WS/projects/$PID/doc \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" -d '{
"schemaVersion":1,"width":1080,"height":1080,"background":"#0f172a",
"nodes":[{"type":"text","id":"t1","x":80,"y":420,"width":920,"height":240,
"text":"Olá {{nome}}","fontSize":96,"fill":"#ffffff","align":"center"}]}'
# 4a. exportar um PNG (1 crédito) → devolve uma URL assinada
curl -s -X POST $API/workspaces/$WS/projects/$PID/export -H "X-Api-Key: $KEY"
# 4b. OU gerar várias peças de uma vez (1 crédito por linha)
curl -s -X POST $API/workspaces/$WS/projects/$PID/merge \
-H "X-Api-Key: $KEY" -H "Content-Type: application/json" \
-d '{"rows":[{"nome":"Ana"},{"nome":"Bruno"}]}'
```
## Endpoints (todos exigem X-Api-Key)
### Workspaces
- `GET /workspaces` — lista
- `POST /workspaces` — `{ name }` (mín. 2 caracteres)
- `GET /workspaces/role` — seu papel na org
- `DELETE /workspaces/:wid` — exclui + projetos em cascata (admin)
### Projetos
- `GET /workspaces/:wid/projects` — lista (id, nome, tags, tamanho, updatedAt)
- `POST /workspaces/:wid/projects` — `{ name, width?, height?, background?, tags? }`
- `GET /workspaces/:wid/projects/:pid` — inclui o documento de design (`doc`)
- `PATCH /workspaces/:wid/projects/:pid` — `{ name?, tags? }`
- `DELETE /workspaces/:wid/projects/:pid` — exclui
- `PUT /workspaces/:wid/projects/:pid/doc` — substitui o doc (corpo = documento)
- `POST /workspaces/:wid/projects/:pid/export` — renderiza PNG → `{ url }` (1 crédito)
- `POST /workspaces/:wid/projects/:pid/exports` — `{ format:"png|jpg|svg|pdf", pageIds? }` → `{ url }` ou `{ files:[...] }` (1 crédito/página)
- `GET /workspaces/:wid/projects/:pid/fields` — campos `{{...}}` do template → `{ fields:[] }`
- `POST /workspaces/:wid/projects/:pid/merge` — `{ rows:[{ campo:valor }] }` → `{ results:[{ index, url }] }` (1 crédito/linha)
- `POST /workspaces/:wid/projects/:pid/preview` — prévia low-res (carimbo "Prévia") → `{ url }` — GRÁTIS. Mostre ao usuário antes de exportar.
- `GET /workspaces/:wid/projects/:pid/preflight` — audita o design antes de exportar → `{ ok, checks:[{ level, code, message, nodeId? }] }` — GRÁTIS
- `GET /workspaces/:wid/projects/:pid/measure?pageId=` — mede a página com o MOTOR DE DESENHO → `{ pageId, width, height, boxes:[{ id, type, x, y, width, height, lines?, overflow? }], warnings:[{ kind, nodeId, otherId?, message }] }` — GRÁTIS.
A caixa final de um texto depende da fonte carregada, do tracking e da quebra por largura — não dá para prever contando caracteres. Peça a medida, corrija com números e só então exporte. `kind`: `overflow` (o texto não coube: quebrou em mais linhas ou vazou), `collision` (dois textos se sobrepõem), `offcanvas` (saiu da página).
### Marca (kit de marca)
- `GET /workspaces/:wid/brand-kit` — kit do workspace (cores/fontes/logos/voz)
- `PUT /workspaces/:wid/brand-kit` — `{ colors, fonts, logos, voice }` (feature do Estúdio → 402 no Ateliê)
- `GET /workspaces/:wid/brand-kit/brief` — brief legível pela IA (paleta, fontes, voz + texto pronto p/ o contexto)
### Assets & IA
- `POST /assets` — upload multipart (png/jpg/webp/gif/svg) → `{ assetKey, src }`
- `POST /assets/from-url` — `{ url }` → `{ assetKey, src }`
- `GET /assets/ai/models` — modelos de IA + custo em créditos por tamanho
- `POST /assets/generate` — `{ model, prompt, width, height, inputImageUrl? }` → `{ assetKey, src }`
- `POST /assets/remove-background` — `{ imageUrl }` → `{ assetKey, src }` (5 créditos)
- `GET /assets/stock/photos?source=unsplash|pexels&q=` — busca fotos de stock
- `GET /assets/stock/icons?q=` — busca ícones (Iconify)
- `POST /assets/stock/pick` — `{ source, url, downloadLocation? }` — salva um item de stock como asset
- `GET|POST /assets/folders`, `DELETE /assets/folders/:id` — pastas da biblioteca
- `GET /assets/library`, `POST /assets/library` (multipart), `PATCH /assets/library/:id` `{ folderId }`, `DELETE /assets/library/:id`
- `GET|POST /fonts` (multipart ttf/otf/woff/woff2), `DELETE /fonts/:id`
### Conta
- `GET /credits` → `{ balance }`
- `GET /templates` → documentos de design prontos (público)
- `GET|POST /api-keys`, `DELETE /api-keys/:id` (admin)
## Documento de design (schema)
No `PUT .../doc` são aceitas duas formas (ambas normalizadas para v2 na leitura):
**v1 (página única):**
```json
{ "schemaVersion":1, "width":1080, "height":1080, "background":"#ffffff", "nodes":[ ... ] }
```
**v2 (multi-página):**
```json
{ "schemaVersion":2, "layout":"strip", "pages":[
{ "id":"p1", "width":1080, "height":1080, "background":"#ffffff", "x":0, "y":0, "nodes":[ ... ] }
]}
```
**Campos comuns de todo nó:** `id` (string, obrigatório), `x`, `y`, `width`,
`height` (números), `rotation?`, `opacity?` (0–1), `name?`, `hidden?`, `locked?`,
sombra (`shadowColor?`, `shadowBlur?`, `shadowOffsetX?`, ...), `blur?`.
### Layout assistido (evita fazer aritmética de posição)
Montar peça por API significa calcular `x`/`y` de cada elemento, e é aí que nascem os
defeitos clássicos: quatro pontos de partida diferentes na mesma página, e elementos que se
encavalam porque o texto de cima cresceu. Dois atalhos evitam isso:
- **`page.columns`** (array de `x` em px) + **`col`** no nó → o nó recebe `x = columns[col]`.
Em vez de digitar `x` livre, escolha uma coluna: tudo na página parte dos mesmos pontos.
- **`stackAfter`** (id de outro nó) + **`stackGap?`** (px, default 24) → o `y` do nó vira o
rodapé do nó referenciado + o respiro. **A altura considerada é a real** — se o texto de cima
quebrar em duas linhas, o de baixo desce junto.
```json
{ "id":"p1", "width":1080, "height":1080, "background":"#0B0F17", "x":0, "y":0,
"columns":[80, 314, 560],
"nodes":[
{ "id":"rotulo", "type":"text", "text":"25 EMPRESAS PEDIRAM", "col":0, "x":0, "y":402,
"width":760, "height":36, "fontSize":28 },
{ "id":"titulo", "type":"text", "text":"O que elas querem", "col":0,
"stackAfter":"rotulo", "stackGap":16, "x":0, "y":0, "width":920, "height":96, "fontSize":80 }
]}
```
Resolvidos **no save**: o documento gravado volta com `x`/`y` absolutos e sem essas props.
São açúcar de escrita, não estado — mudar `columns` depois não reposiciona o que já foi salvo.
**Tipos de nó:**
- `text` — `text`, `fontSize?`, `fontFamily?`, `fontStyle?` (normal|bold|italic|italic bold),
`fill?`, `align?` (left|center|right), `lineHeight?`, `wrap?` (`word` = quebra em palavras,
o padrão; `none` = não quebra e transborda a caixa). Use `{{campo}}` dentro de `text` para data-merge.
- `rect` — `fill`, `fillGradient?`, `cornerRadius?`, `stroke?`, `strokeWidth?`.
- `ellipse` / `triangle` — `fill`, `fillGradient?`, `stroke?`, `strokeWidth?`.
- `path` — `d` (path SVG em coords do viewBox), `viewWidth`, `viewHeight`, `fill`, `stroke?`,
`strokeWidth?`. O render escala `d` para `width`×`height`.
- `image` — `assetKey` (de um upload/generate/from-url), `src` (URL assinada), `crop?`,
`flipX?`, `flipY?`, `field?` (data-merge: cada linha fornece o assetKey desta imagem).
- `draw` — traço livre: `points` (achatado `[x0,y0,...]`), `stroke`, `strokeWidth`, `tension?`, `lineCap?`.
**`background` e `fillGradient`** podem ser uma string hex OU
`{ "type":"linear", "angle":90, "stops":[{ "color":"#fff", "at":0 }, ...] }`
ou `{ "type":"radial", "stops":[...] }`.
## Data-merge (geração em lote)
Coloque marcadores `{{campo}}` em nós de texto (ou `field` num nó de imagem).
`GET .../fields` lista os marcadores encontrados. `POST .../merge` com `rows`
devolve uma imagem renderizada por linha.
## Imagens por IA
- `GET /assets/ai/models` devolve os modelos (texto→imagem e edição) com o custo em
créditos por tamanho. Mais barato: `flux-schnell`.
- Texto→imagem: `POST /assets/generate { model, prompt, width, height }`.
- Edição de imagem (modelos `mode: "edit"`): passe também `inputImageUrl`.
- Remover fundo: `POST /assets/remove-background { imageUrl }`.
Todos devolvem `{ assetKey, src }` — use em um nó `image`.
## Créditos
export 1 · exports 1/página · merge 1/peça · remover fundo 5 · generate = por
modelo/tamanho (ver `/assets/ai/models`) · importar arquivo 2. Toda org nova começa
com **200**. Saldo em `GET /credits`.
## MCP (para agentes compatíveis com MCP)
Rode o servidor MCP do Lutrix (stdio) e configure o cliente:
```json
{
"mcpServers": {
"lutrix": {
"command": "node",
"args": ["/caminho/lutrix-mcp-server/dist/index.js"],
"env": {
"LUTRIX_API_URL": "https://lutrix-api-739d.onrender.com",
"LUTRIX_API_KEY": "lutrix_sk_..."
}
}
}
}
```
**15 tools:** lutrix_list_workspaces, lutrix_create_workspace, lutrix_list_projects, lutrix_create_project, lutrix_update_project, lutrix_get_project, lutrix_get_brand_kit, lutrix_set_brand_kit, lutrix_set_project_doc, lutrix_render_preview, lutrix_preflight, lutrix_export_png, lutrix_list_template_fields, lutrix_merge, lutrix_upload_asset_from_url.
## Regras para agentes
- Sempre envie `X-Api-Key`. **Nunca** exponha a chave no frontend nem em logs.
- Reaproveite um workspace existente (`GET /workspaces`) em vez de criar novos à toa.
- Depois de `generate`/`upload`/`from-url`, use o `assetKey` **e** o `src` retornados
num nó `image`; o `src` é re-assinado no `GET` do projeto e no export.
- Chamadas que gastam créditos (export, exports, merge, generate, remove-background)
custam créditos reais — **confirme com o usuário** antes de lotes grandes.
agentes
A IA cria a própria skill
Prefere que o seu agente monte a skill no formato dele? Cole o prompt abaixo em qualquer IA — ela lê a referência e devolve uma skill pronta (system prompt, tools/functions, config de MCP, o que o framework usar).
Crie uma skill/ferramenta reutilizável para operar a plataforma de design Lutrix pela API, NO FORMATO DO SEU framework de agente (system prompt, tools/functions, MCP, arquivo de skill — o que você usar).
1. Baixe e leia a especificação canônica (é um SKILL.md universal): https://lutrix.app/skills/lutrix
Referência de apoio: https://lutrix.app/docs
2. A base da API é https://lutrix-api-739d.onrender.com. TODA chamada leva o header "X-Api-Key: lutrix_sk_..." — peça a chave ao usuário (ela é criada em https://lutrix.app/app).
3. Sua skill deve cobrir: listar/criar workspace e projeto; definir o documento de design (JSON com nós text/rect/ellipse/triangle/image/path); exportar (PNG/JPG/SVG/PDF); data-merge ({{campo}} → 1 imagem por linha); gerar imagem por IA; e remover fundo.
4. Nunca exponha a API key no frontend ou em logs. Confirme com o usuário antes de operações que gastam créditos (export, merge, generate, remove-background).
Responda apenas com a skill final, pronta para usar.claude
MCP — usar direto do Claude
O Lutrix expõe um servidor MCP (stdio): o Claude ganha as capacidades do Lutrix como tools nativas. Configure no claude_desktop_config.json:
{
"mcpServers": {
"lutrix": {
"command": "node",
"args": ["/caminho/lutrix-mcp-server/dist/index.js"],
"env": {
"LUTRIX_API_URL": "https://lutrix-api-739d.onrender.com",
"LUTRIX_API_KEY": "lutrix_sk_xxx"
}
}
}
}As 15 tools expostas:
- lutrix_list_workspaces
- lutrix_create_workspace
- lutrix_list_projects
- lutrix_create_project
- lutrix_update_project
- lutrix_get_project
- lutrix_get_brand_kit
- lutrix_set_brand_kit
- lutrix_set_project_doc
- lutrix_render_preview
- lutrix_preflight
- lutrix_export_png
- lutrix_list_template_fields
- lutrix_merge
- lutrix_upload_asset_from_url
uso
Créditos
Ações que consomem processamento gastam créditos. Toda org nova começa com 200. Consulte em GET /credits.