Propostas rastreadas,
direto do seu código.
A API do Notei deixa seu sistema — ou um agente de IA — criar uma proposta, enviá-la por um link único e ler de volta tudo o que o cliente fez: quanto tempo leu, se voltou no preço, se clicou em aceitar. Sem painel, sem trabalho manual.
# Sua primeira proposta enviada — em um comando
curl -X POST https://notei.online/api/v1/proposals \
-H "Authorization: Bearer $NOTEI_KEY" \
-H "Content-Type: application/json" \
-d '{ "title": "Proposta — Acme", "send": true,
"sections": [{ "type": "cover", "title": "Capa", "content": "# Olá, Acme" }] }'
Proposta ou Oferta?
São dois objetos diferentes — e a API cria os dois. O motor de rastreamento (views, eventos, insights) é o mesmo nos dois; muda como o cliente chega.
Você manda pra um cliente
Um documento em /p/{slug} com link único e não-adivinhável que você envia. Tem send, aceite digital e consome 1 cota/crédito ao enviar.
- Fluxo: rascunho → enviada → vista → aceita/recusada
- Tem destinatários nomeados (links ?r=)
- POST /api/v1/proposals
O cliente chega até você
Uma página pública e estável em /o/{slug} de um serviço fixo, sempre no ar. Quem se interessa preenche o form e vira lead + proposta no funil. Sem send, sem cota.
- Mede conversão: views → leads
- Campos de contato por preset_key
- POST /api/v1/offers
Regra de bolso: sabe pra quem vai → proposta. Quer um link pra divulgar e captar interessados → oferta.
Autenticação
Toda chamada usa uma chave de API. Gere uma no painel em Configurações → Chaves de API. Ela aparece uma única vez — guarde num cofre de segredos. Mande em um dos dois headers:
Authorization: Bearer ntk_live_xxxxxxxxxxxxxxxxxxxx
# ou
X-API-Key: ntk_live_xxxxxxxxxxxxxxxxxxxx
- Guardamos só o SHA256 da chave — nem nós a recuperamos.
- 120 req/min por chave. Tentativas inválidas são limitadas por IP.
- Uma chave só enxerga os dados do próprio workspace.
- Revogar uma chave tem efeito imediato.
Quickstart
- 1. Crie a conta em notei.online e gere a chave em Configurações.
- 2. Confirme que a chave funciona:
curl https://notei.online/api/v1/me -H "Authorization: Bearer $NOTEI_KEY"
3. Crie e envie. Pronto — o public_url da resposta é o link pra mandar pro cliente.
O fluxo completo, passo a passo
Respostas reais da API (encurtadas). É exatamente o que você recebe.
① Cria a proposta e já envia
POST /api/v1/proposals
{
"title": "Proposta — Landing page institucional",
"client_name": "Acme Ltda", "client_email": "compras@acme.com",
"total_value_cents": 1200000, "currency": "BRL",
"external_id": "crm-deal-8841", "send": true,
"sections": [
{ "type": "cover", "title": "Capa", "content": "# Proposta pra **Acme**" },
{ "type": "solution", "title": "Solução", "content": "Landing + CMS + analytics." },
{ "type": "pricing", "title": "Investimento", "content": "R$ 12.000 à vista" },
{ "type": "cta", "title": "Próximo passo","content": "Aceite por aqui." }
],
"recipients": [{ "name": "Maria", "role": "CFO", "email": "maria@acme.com" }]
}
201 Created
{
"id": 94, "status": "sent",
"slug": "acme-ltda-proposta-landin-t2zgam",
"public_url": "https://notei.online/p/acme-ltda-proposta-landin-t2zgam",
"currency": "BRL", "total_value_cents": 1200000,
"sections": [ ... ]
}
Mandou o public_url pro cliente por WhatsApp/email. A partir daqui o Notei captura tudo.
② Lê o que o cliente fez
GET /api/v1/proposals/94/insights
{
"status": "viewed", "total_views": 1, "unique_visitors": 1,
"best_engagement_score": 61,
"event_counts": { "view.started": 1, "cta.clicked": 1, "section.exited": 1 },
"sections": [
{ "type": "pricing", "title": "Investimento", "total_seconds": 21, "entered_count": 1 }
],
"sessions": [
{ "temperature": "warm", "score": 61,
"headline": "Interesse morno — vale um empurrãozinho",
"bullets": ["Leu por 1min 14s", "Parou 21s no preço", "Clicou em aceitar"] }
]
}
③ Ou puxa os sinais crus (pro seu dashboard)
GET /api/v1/proposals/94/events?type=cta.clicked
[ { "type": "cta.clicked", "section_id": null, "metadata": {},
"occurred_at": "2026-06-24T22:39:02Z" } ]
E pra monitorar tudo de uma vez, GET /api/v1/activity?since=… devolve o feed de eventos de todas as propostas — ideal pra um agente fazer polling.
Casos de uso
Fechou no CRM, proposta sai sozinha
Seu agente monta as seções em markdown e dá send:true. Use external_id = id do negócio: retry não duplica.
A mesma proposta, qualquer mercado
currency + total_value_cents aceitam BRL ou qualquer outra moeda, sem config extra.
Alerta quando esquentou
Faça polling de /activity e dispare um alerta no Slack quando vier um cta.clicked ou price.lingered.
Já tem a proposta em PDF?
POST /proposals/from-pdf sobe o arquivo, a IA quebra em seções tipadas e vira um link rastreado.
Propostas
/api/v1/meIdentidade + cota/api/v1/proposalsCria (JSON); send/api/v1/proposals/from-pdfCria de PDF/api/v1/proposalsLista/api/v1/proposals/{id}Detalhe/api/v1/proposals/{id}Atualiza/api/v1/proposals/{id}/sendEnvia → link/api/v1/proposals/{id}ApagaTipos de seção: cover, about, problem, solution, deliverables, stack, timeline, pricing, cta, faq, custom. Pra reaproveitar um modelo, passe template_id (veja GET /api/v1/templates).
Exemplo — criar e enviar
POST /api/v1/proposals
{
"title": "Proposta — Landing institucional",
"client_name": "Acme Ltda",
"client_email": "compras@acme.com",
"total_value_cents": 1200000,
"currency": "BRL",
"external_id": "crm-deal-8841",
"send": true,
"sections": [
{ "type": "cover", "title": "Capa",
"content": "# Proposta pra **Acme**" },
{ "type": "pricing", "title": "Investimento",
"content": "R$ 12.000 à vista" },
{ "type": "cta", "title": "Próximo passo",
"content": "Aceite por aqui." }
],
"recipients": [
{ "name": "Maria", "role": "CFO", "email": "maria@acme.com" }
]
}
201 Created
{
"id": 94,
"status": "sent",
"slug": "acme-ltda-proposta-landin-qrvko5",
"public_url":
"https://notei.online/p/acme-ltda-proposta-landin-qrvko5",
"currency": "BRL",
"total_value_cents": 1200000,
"sections": [ ... ]
}
# o public_url é o link rastreado pra você
# mandar pro cliente (WhatsApp/email/etc).
Playground
Edite o corpo e rode de verdade — a resposta é real. Roda no seu navegador (same-origin); a chave não sai daqui e não é salva.
A resposta aparece aqui…
Pra valer, use sua chave de Configurações → Chaves de API. A sandbox é compartilhada e os dados são descartáveis.
Branding & campos de aceite
Cores, logo e imagens
Mande um objeto branding no create/patch da proposta — cores, fonte, logo e imagens. Valores inválidos caem no padrão automaticamente, então não tem como quebrar o layout.
- primary_color, background_color, surface_color, text_color, cta_bg_color… — hex (#rrggbb)
- logo_url, hero_image, background_image — URL https ou relativa
- font_preset — default · inter · geist · playfair · space · dm
- cta_text, hide_powered_by, hide_price_until_click
Seis caras pra mesma proposta — o preview é o que o cliente vê. Escolha um font_preset e as cores:
pra Acme
"branding": {}
pra Acme
{
"primary_color": "#22d3ee",
"background_color": "#0b0f14",
"text_color": "#e5e7eb",
"cta_bg_color": "#22d3ee",
"cta_text_color": "#0b0f14",
"font_preset": "space"
}
pra Acme
{
"primary_color": "#7c3aed",
"background_color": "#faf7f2",
"font_preset": "playfair",
"hide_powered_by": true
}
pra Acme
{
"primary_color": "#2563eb",
"background_color": "#ffffff",
"text_color": "#0f172a",
"cta_bg_color": "#2563eb",
"font_preset": "inter"
}
pra Acme
{
"primary_color": "#a3e635",
"background_color": "#0a0a0a",
"text_color": "#fafafa",
"cta_bg_color": "#a3e635",
"cta_text_color": "#0a0a0a",
"font_preset": "geist"
}
pra Acme
{
"primary_color": "#c9a84a",
"background_color": "#14241f",
"text_color": "#f1e9d6",
"cta_bg_color": "#c9a84a",
"cta_text_color": "#14241f",
"font_preset": "dm"
}
Hospedar a imagem no Notei
Não tem onde hospedar o logo? Suba aqui e use a URL no branding:
curl -X POST https://notei.online/api/v1/assets \
-H "Authorization: Bearer $NOTEI_KEY" \
-F "file=@logo.png"
# -> { "url": "https://notei.online/uploads/api/12/ab3x.png", "markdown": "" }
# use a url em branding.logo_url (PNG/JPEG/WebP/GIF até 5MB; SVG não, por segurança)
Campos pra aceitar a proposta
Defina o que o cliente precisa preencher pra aceitar. name e email entram sempre; você adiciona o resto. Obrigatórios são validados no aceite.
POST /api/v1/proposals (ou PATCH)
{
"title": "...", "sections": [ ... ],
"contact_fields": [
{ "key": "phone", "label": "WhatsApp", "type": "tel", "required": true },
{ "key": "cnpj", "label": "CNPJ", "type": "cnpj", "required": true },
{ "key": "cargo", "label": "Cargo", "type": "text", "required": false }
]
}
// atalho: "preset_key": "b2b" (veja GET /api/v1/contact-presets)
// tipos: text · email · tel · cnpj · cpf · textarea · select
Os valores preenchidos voltam em GET /api/v1/proposals/{id}/decisions (campo extra_fields). CNPJ/CPF pedem consentimento LGPD automático.
Ofertas
Páginas públicas /o/{slug} que captam leads. Não têm send — ficam sempre no ar.
/api/v1/offersLista/api/v1/offersCria (preset OU contact_fields)/api/v1/offers/{id}Atualiza / ativa-desativa/api/v1/offers/{id}/leadsLeads captados/api/v1/offers/{id}/statsConversão + pipeline/api/v1/contact-presetsPresets de camposPOST /api/v1/offers
{
"title": "Consultoria internacional",
"price_cents": 250000, "currency": "USD", "price_label": "a partir de",
"preset_key": "b2b", // ou "contact_fields": [...] custom
"content": "## O que entra\n- Discovery\n- Implementação",
"max_leads": 50
}
// -> 201 { "id": 7, "public_url": ".../o/epo8p5kmpu44p9", "currency": "USD", ... }
Monitoramento & insights
Os mesmos sinais que o painel do Notei usa — agora no seu código.
…/{id}/insightsResumo + heatmap por seção…/{id}/viewsSessões cruas (device, geo, scroll)…/{id}/events~22 sinais crus, filtra por tipo…/{id}/recipientsEngajamento por pessoa…/{id}/decisionsAceites/recusas + assinatura/api/v1/activityFeed do workspace (polling)Erros
Sempre { "detail": { "error": "<code>", "message": "…" } }.
| HTTP | error | quando |
|---|---|---|
| 401 | missing/invalid_api_key | sem chave ou inválida/revogada |
| 402 | no_active_plan_or_credits | enviou sem plano/crédito |
| 404 | not_found | proposta não é sua |
| 413 | too_large | PDF acima de 10MB |
| 429 | rate_limited / quota_exceeded | 120/min, ou cota mensal |
Um agente lê o OpenAPI e monta as ferramentas sozinho.