# eaipostou > Gerador de imagens de posts para redes sociais. Cria cards no estilo tweet ou nota de celular, divide texto longo em carrossel com IA e renderiza imagens 1080px prontas para o feed do Instagram. Interface web em https://eaipostou.com.br/studio e API REST documentada abaixo. Uso responsavel: por padrao as imagens carregam um aviso de simulacao ("Simulacao criada para fins ilustrativos"). O conteudo gerado e ilustrativo e nao deve ser usado para se passar por publicacoes reais de terceiros. ## Base da API - Base URL: https://eaipostou.com.br/api - Formato: JSON (Content-Type: application/json) - Erros: sempre {"detail": "mensagem em portugues"} - Envie um User-Agent proprio (ex.: "MeuAgente/1.0"). Clientes com User-Agent generico de biblioteca podem ser barrados na borda. - OpenAPI: https://eaipostou.com.br/api/openapi.json - Swagger UI: https://eaipostou.com.br/api/docs ## Autenticacao Duas opcoes, ambas via header `Authorization: Bearer `: 1. Chave de API (recomendada para agentes): formato `sps_live_...`. O usuario gera em Studio > Conta e equipe > Chaves de API. Nao expira; pode ser revogada. 2. Token JWT: `POST /auth/login` com {"email": "...", "password": "..."} devolve {"access_token": "..."} valido por 7 dias. Registro: `POST /auth/register` com {"email", "name", "password"}. `GET /auth/me` devolve o usuario atual: {"id", "email", "name", "plan": "free|pro", "role": "user|admin"}. ## Planos e limites - Free: 15 exportacoes/mes, 5 geracoes de IA/mes, carrossel de ate 5 cards, 3 projetos na nuvem. - Pro: sem limites mensais e carrossel de ate 20 cards. - Ha um teto global mensal de geracoes de IA na instancia (protecao de custo). Quando atingido, `POST /ai/carousel` responde 503. ## Endpoints principais ### POST /ai/carousel — dividir texto em cards com IA Body: {"text": "50 a 30000 caracteres", "max_cards": 2-20 (opcional, padrao 10), "instructions": "ate 500 chars (opcional)"} Resposta 200: {"cards": ["texto do card 1", ...], "usage": {"plan", "month", "used", "limit", "remaining"}} Erros: 403 limite mensal do plano Free atingido; 503 IA indisponivel ou teto global atingido; 422 conteudo recusado. ### POST /render — renderizar imagem de um projeto Body: {"project": , "mode": "carousel"|"single"|"story", "ratio": "4:5"|"3:4"|"1:1"|"livre", "style": "cheio"|"janela", "margin": 0-120, "show_counter": bool, "show_hint": bool, "watermark": bool} - mode carousel: um slide 1080px por card. Resposta: image/png (1 card) ou application/zip (varios). - mode single: uma imagem unica com todos os cards empilhados. Respeita o ratio: 4:5 = 1080x1350, 3:4 = 1080x1440, 1:1 = 1080x1080, "livre" = altura automatica do conteudo. Resposta: image/png. - Para Instagram, ambos os modos com ratio 4:5 dao 1080x1350; para 1 card tanto faz carousel ou single. - ratio 3:4 (1080x1440) e o formato alto: ocupa mais tela no feed e preenche a grade do perfil sem corte. O 4:5 continua sendo o padrao seguro; na grade ele perde as laterais (so aparece a faixa central de 1012x1350). - style cheio (padrao): o conteudo ocupa a imagem toda, melhor leitura no feed. - watermark (padrao false): credito opcional "feito com @eaipostou" no canto da imagem. - mode story: PNG 1080x1920 para Story/WhatsApp Status. Campos extras: "story_bg" (imagem de fundo em data URL, opcional), "story_position" ("topo"|"centro"|"base"), "story_style" ("texto" padrao: escrita nativa de story com marcacao atras de cada linha; "literatura": fonte serifada com caixa por paragrafo e uma cor de "story_palette" por bloco, cada quebra de linha vira um bloco; "card": o post completo flutuando). ==destaques== saem na cor do tema "story_pill" ("branco"|"preto"|"nenhum", cor da marcacao no estilo texto) "story_palette" (lista de 1 a 8 cores #RRGGBB para o estilo literatura; os blocos circulam pelas cores na ordem, entao 1 cor = todos iguais, 2 cores = alternado, e repetir uma cor concentra o destaque: ["#ECECEC","#ECECEC","#C5F045"] poe a cor forte so no 3o bloco) e "story_shadow" ("nenhum"|"suave"|"media"|"forte": veu escuro sobre a imagem de fundo para legibilidade). Conteudo fica na zona segura, fora das areas que o Instagram cobre. Usa o primeiro post. ### POST /render/reel — card + video em MP4 para Reels (plano Pro) Multipart form-data com dois campos: "project" (JSON do Projeto como string; usa o primeiro post) e "video" (arquivo MP4, MOV ou WebM, ate 90s e 80 MB). Resposta: video/mp4 de 1080x1920, com o card em cima e o video numa janela de cantos arredondados, mantendo o audio original. Erros: 403 plano Free; 422 video invalido ou longo demais. ### POST /render/batch — varios posts de uma vez Body: {"csv": "texto csv"} OU {"rows": [{...}]}, mais os mesmos campos de estilo do /render e {"theme": "light"|"gray"|"dark", "notice": "simulacao"|..., "profile": {...} opcional}. Colunas/chaves de cada linha: nome, usuario, conteudo, data, horario, origem, visualizacoes, respostas, compartilhamentos, curtidas, salvamentos. Cada linha vira um card. Resposta: application/zip com as imagens. ### Projetos (nuvem) - GET /projects — lista {"id", "name", "workspace_id", "owner_name", "updated_at"} - POST /projects — body {"name", "data": , "workspace_id": null|id} - GET /projects/{id} | PUT /projects/{id} | DELETE /projects/{id} ### Chaves de API - GET /keys — lista as chaves do usuario (sem o valor completo) - POST /keys — body {"label": "nome"}; resposta inclui "key" (valor completo, exibido so nesta resposta) - DELETE /keys/{id} — revoga ### Uso - GET /usage/export — contador de exportacoes do mes - GET /ai/usage — contador de geracoes de IA do mes ## O objeto Projeto Mesmo JSON usado pelo studio. Campos ausentes ganham valores padrao na renderizacao, entao o projeto MINIMO valido e: {"name": "meu post", "themeId": "dark", "posts": [{"text": "card 1"}, {"text": "card 2"}]} Atencao aos defaults: sem "date"/"time" a linha de data NAO aparece (bom), mas sem "metrics" os cards saem com numeros de exemplo e sem "profile" saem como "Sua Marca". Para controle total, envie o objeto completo: { "id": "string", "name": "string", "updatedAt": "ISO-8601", "cardStyle": "tweet" | "notas" | "caderno", // visual do card (ausente = tweet) "themeId": "light" | "gray" | "dark" | "custom", "customTheme": {"appBg", "cardBg", "accent", "textPrimary", "textSecondary", "border", "radius"}, "notice": "simulacao" | "educativo" | "patrocinado" | "ficticio" | "estudo-de-caso" | "opiniao" | "none", "noticeInCard": true, "canvasPreset": "auto", "posts": [ { "id": "string", "profile": {"name", "username", "role", "avatarDataUrl": null|dataURL, "badge": "none|check|star|shield", "badgeColor": "#hex"}, "text": "conteudo do card; \n para quebras. No estilo notas, ==palavra== vira marca-texto amarelo", "fontSize": 17, "media": [{"id", "dataUrl", "alt"}], "date": "8 de ago. de 2026", "time": "12:00", "client": "", "metrics": {"views", "replies", "reposts", "likes", "bookmarks"} // numero ou null (oculta) } ], "exportSettings": {"format": "png", "scale": 2, "quality": 0.95, "fileName": "post", "transparent": false, "margin": 48} } Notas sobre cardStyle "notas": renderiza como nota de celular (barra "< Notas", texto grande, @username discreto). Ignora metrics, date, badge e avatar. O tema controla o fundo: dark = nota preta, light = nota branca. Notas sobre cardStyle "caderno": renderiza como bloco de anotacoes fotografado sobre uma mesa, com espiral no topo e letra a mao (fonte Caveat). Ignora metrics, date, badge e avatar; o @username sai discreto no canto. O tema controla a mesa: dark = mesa escura com papel creme, light = mesa clara com papel branco. Cada linha ganha uma inclinacao minima, sempre a mesma para o mesmo texto. Como escrever para o caderno: linhas curtas, uma ideia por linha, " " entre linhas e " " separando blocos. Use ==Titulo== para o sublinhado desenhado. Um traco de fechamento e desenhado sozinho no fim, nao precisa pedir. Formato que funciona bem: tres blocos com titulo e dados, e uma frase de fecho no ultimo bloco. Tipografia adaptativa: quando "fontSize" e omitido ou 17 (padrao), a renderizacao aumenta a fonte automaticamente para textos curtos (ate 90 chars -> 26px; ate 160 -> 22px; ate 260 -> 19px), para a frase preencher bem a arte. Para controle manual, envie um fontSize diferente de 17 (ex.: frase de impacto: 24-28; texto medio: 19-21; texto longo: 17). Regras de exibicao importantes: - Ocultar data e horario: envie "date": "" e "time": "" (linha some do card). Nao invente datas se o usuario nao pedir. - Ocultar uma metrica: valor null. Ocultar todas: todas null. - Foto de perfil (avatarDataUrl): e um data URL base64. NAO tem como inventar; ela so existe dentro de um projeto ja salvo pelo usuario. Para usar a foto, SEMPRE parta de um projeto salvo (fluxo abaixo). ## Fluxo recomendado: partir de um projeto salvo do usuario Se o usuario tem um projeto salvo (ex.: "MDN") com foto, nome e @, NAO monte o Projeto do zero. Reaproveite o salvo, trocando apenas os textos: 1. GET /projects e encontre o item com o "name" que o usuario citou. Guarde o "id". 2. GET /projects/{id}. O campo "data" e o Projeto completo, com o perfil e a foto (avatarDataUrl) intactos. 3. Monte os novos posts copiando um post existente de data.posts como base (preserva profile com a foto) e trocando so o "text" de cada card. Para N cards, replique a base N vezes com ids diferentes. 4. Ajuste o que o usuario pedir (ex.: "date": "" e "time": "" para sair sem data, metricas null para sair sem numeros). 5. Renderize com o payload do passo seguinte. ## Receita para Instagram (feed) Para gerar imagens no formato que o Instagram usa, mande exatamente: POST /render {"project": , "mode": "carousel", "ratio": "4:5", "style": "cheio"} - mode "carousel" + ratio "4:5": um slide de 1080x1350 por card (o formato do feed). ratio "3:4" da 1080x1440 (formato alto, preenche a grade do perfil). ratio "1:1" da 1080x1080. - style "cheio": o conteudo ocupa a imagem inteira (recomendado; e o que os perfis grandes usam). style "janela" poe o card como uma moldura flutuando sobre o fundo do tema: evite, a leitura no celular fica pior. - A resposta e image/png com 1 card ou application/zip com varios (publique as imagens na ordem). ## Exemplo completo (agente que cria um carrossel do zero) 1. Divida o texto: POST /ai/carousel {"text": "...", "max_cards": 5} 2. Se o usuario tem projeto salvo, siga o "Fluxo recomendado" acima para montar o Projeto com o perfil real. Senao, monte com o objeto de referencia. 3. Renderize com a "Receita para Instagram": POST /render {"project": ..., "mode": "carousel", "ratio": "4:5", "style": "cheio"} e salve o ZIP. 4. Opcional: salve na nuvem com POST /projects (ou PUT /projects/{id} para atualizar) para o usuario abrir no studio depois. ```python import json, urllib.request BASE = "https://eaipostou.com.br/api" KEY = "sps_live_SUA_CHAVE" def req(path, data=None): r = urllib.request.Request( BASE + path, data=json.dumps(data).encode() if data else None, headers={"Content-Type": "application/json", "Authorization": f"Bearer {KEY}", "User-Agent": "MeuAgente/1.0"}) return urllib.request.urlopen(r, timeout=120) cards = json.load(req("/ai/carousel", {"text": "seu texto longo...", "max_cards": 5}))["cards"] ``` ## Guia rapido: como gerar um BOM story (para agentes) 1. Estilo "literatura" e o mais versatil para frases e listas; "texto" para o visual descontraido de story digitado; "card" so quando o usuario quiser mostrar o post em si. 2. Quebras de linha controlam os blocos no literatura: cada vira uma caixa. Prefira blocos de 1 a 2 linhas renderizadas (frases curtas). 2 a 4 blocos por story. 3. fontSize 18-20 para texto normal, 22-26 para frase unica de impacto. Menor e mais elegante que maior. 4. Cores: use a paleta da marca do usuario se ele tiver; senao ["#ffffff"]. Coloque a cor mais chamativa em UM bloco so (a frase-chave). Texto comum na cor neutra. 5. Fundo: se o usuario tiver imagens de marca, use em story_bg; story_shadow "suave" para fundos escuros, "media"/"forte" para fotos claras ou detalhadas. 6. position "centro" como padrao; "base" quando o story acompanha um sticker/enquete que o usuario vai por em cima; "topo" quando houver CTA de resposta embaixo. 7. Nao invente datas nem metricas; para posts de marca use notice "none". 8. Feche stories de serie com uma pergunta curta (convite a resposta): engajamento em story e resposta na caixinha. ## Links - Studio (interface web): https://eaipostou.com.br/studio - Guia da API para humanos: https://eaipostou.com.br/docs - OpenAPI: https://eaipostou.com.br/api/openapi.json