notei.
API · v1

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.

REST · JSON Auth por chave Multi-moeda Idempotente Webhooks
# 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" }] }'
Antes de tudo

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.

Proposta · 1 pra 1

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
Oferta · 1 pra muitos

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.

01

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.
02

Quickstart

  1. 1. Crie a conta em notei.online e gere a chave em Configurações.
  2. 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.

Tutorial

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.

03

Casos de uso

Agente de IA / CRM

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.

Multi-moeda

A mesma proposta, qualquer mercado

currency + total_value_cents aceitam BRL ou qualquer outra moeda, sem config extra.

Monitoramento

Alerta quando esquentou

Faça polling de /activity e dispare um alerta no Slack quando vier um cta.clicked ou price.lingered.

PDF → proposta

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.

Referência

Propostas

GET/api/v1/meIdentidade + cota
POST/api/v1/proposalsCria (JSON); send
POST/api/v1/proposals/from-pdfCria de PDF
GET/api/v1/proposalsLista
GET/api/v1/proposals/{id}Detalhe
PATCH/api/v1/proposals/{id}Atualiza
POST/api/v1/proposals/{id}/sendEnvia → link
DEL/api/v1/proposals/{id}Apaga

Tipos 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).
Experimente

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.

Personalização

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_presetdefault · 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:

Notei · default
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
"branding": {}
Dark techy · space
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
{
  "primary_color": "#22d3ee",
  "background_color": "#0b0f14",
  "text_color": "#e5e7eb",
  "cta_bg_color": "#22d3ee",
  "cta_text_color": "#0b0f14",
  "font_preset": "space"
}
Editorial · playfair
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
{
  "primary_color": "#7c3aed",
  "background_color": "#faf7f2",
  "font_preset": "playfair",
  "hide_powered_by": true
}
Clean SaaS · inter
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
{
  "primary_color": "#2563eb",
  "background_color": "#ffffff",
  "text_color": "#0f172a",
  "cta_bg_color": "#2563eb",
  "font_preset": "inter"
}
Neon bold · geist
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
{
  "primary_color": "#a3e635",
  "background_color": "#0a0a0a",
  "text_color": "#fafafa",
  "cta_bg_color": "#a3e635",
  "cta_text_color": "#0a0a0a",
  "font_preset": "geist"
}
Luxo · dm
Proposta
Identidade visual
pra Acme
Investimento
R$ 12.000
{
  "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": "![imagem](...)" }
# 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.

GET/api/v1/offersLista
POST/api/v1/offersCria (preset OU contact_fields)
PATCH/api/v1/offers/{id}Atualiza / ativa-desativa
GET/api/v1/offers/{id}/leadsLeads captados
GET/api/v1/offers/{id}/statsConversão + pipeline
GET/api/v1/contact-presetsPresets de campos
POST /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.

GET…/{id}/insightsResumo + heatmap por seção
GET…/{id}/viewsSessões cruas (device, geo, scroll)
GET…/{id}/events~22 sinais crus, filtra por tipo
GET…/{id}/recipientsEngajamento por pessoa
GET…/{id}/decisionsAceites/recusas + assinatura
GET/api/v1/activityFeed do workspace (polling)

Erros

Sempre { "detail": { "error": "<code>", "message": "…" } }.

HTTPerrorquando
401missing/invalid_api_keysem chave ou inválida/revogada
402no_active_plan_or_creditsenviou sem plano/crédito
404not_foundproposta não é sua
413too_largePDF acima de 10MB
429rate_limited / quota_exceeded120/min, ou cota mensal
Spec pra gerar tools automático

Um agente lê o OpenAPI e monta as ferramentas sozinho.

GET /api/v1/openapi