Seu dashboard Instantly abre com 200 leads na fila, templates preparados, e aquele mesmo sentimento vazio — outro lote de "Oi {firstName}, notei sua empresa..." prestes a ser disparado. Toda agência odeia cold email. Nós também. Não porque outreach não funciona, mas porque toda plataforma que pagávamos ainda precisava de horas de pesquisa manual, ainda enviava copy que parecia escrito por um bot, e ainda custava $300/mês para fazer o que sabíamos que Claude podia fazer melhor em segundos. Então paramos de alugar. Conectamos Claude, Hunter, Instantly e Supabase em um sistema que escreve openers contextuais a partir de web scrapes ao vivo, pontua respostas por intenção, e registra cada interação sem a taxa SaaS. A arquitetura não é ciência de foguete — mas a taxa de resposta subiu, o trabalho chato desapareceu, e possuímos toda a stack.

Isso não é um post de arquitetura teórica. Estamos executando este sistema em produção há meses, enviando milhares de emails personalizados que realmente recebem respostas. Vou te levar exatamente pelo motivo pelo qual construímos, como as peças se encaixam, e o que aprendemos da forma difícil.

Sumário

Por Que Construímos Nosso Próprio Sistema de Cold Email com Claude, Instantly e Supabase

O Problema com Outreach Pronto para Usar

Testamos os suspeitos usuais. Lemlist. Apollo. Woodpecker. São ferramentas boas para muitos casos de uso. Mas como uma agência de desenvolvimento web headless, nossas necessidades de outreach eram específicas de formas que essas plataformas não conseguiam lidar.

Aqui está o que ficava quebrado:

Campos de personalização genéricos não são personalização. Inserir o nome da empresa e o título do cargo de alguém em um template não engana ninguém em 2026. Precisávamos de emails que referenciassem a stack de tecnologia atual do prospect, seus problemas de performance do site, ou decisões arquiteturais específicas visíveis no seu website público.

O passo de pesquisa era o gargalo. Nosso outreach com melhor desempenho sempre envolvia alguém do time realmente olhando para o site de um prospect, passando por PageSpeed Insights, verificando o framework, e escrevendo algo específico. Isso levava 10-15 minutos por lead. Em escala, isso é um trabalho em tempo integral.

Os dados viviam em muitos lugares. Leads em uma planilha, sequências de email em outra plataforma, resultados em um terceiro dashboard. Não conseguíamos construir loops de feedback porque nada conversava com nada.

As integrações de IA eram superficiais. Algumas plataformas adicionavam recursos de "escrita com IA", mas eram basicamente wrappers de GPT que geravam o mesmo copy insosso que todos os outros estavam enviando. Nenhuma capacidade de alimentar contexto customizado, nenhum controle sobre prompts, nenhuma forma de construir cadeias de raciocínio multi-etapas.

Precisávamos de um sistema onde IA fizesse a pesquisa, não apenas a escrita.

Nossa Tech Stack e Por Que Escolhemos

Aqui está o que terminamos depois de algumas iterações:

Componente Ferramenta Função Custo Mensal
Busca de leads e verificação de email Hunter.io Encontrar e verificar endereços de email $49 (Starter)
Pesquisa e copywriting com IA Claude (Anthropic API) Analisar prospects, gerar emails personalizados ~$30-60
Banco de dados e orquestração Supabase Armazenar leads, gerenciar estado, acionar workflows $25 (Pro)
Envio de email e warmup Instantly.ai Entregabilidade, infraestrutura de envio, warmup $30 (Growth)
Cola de automação Custom Edge Functions + Cron Conectar tudo junto $0 (incluído em Supabase)

Avaliamos um monte de alternativas. Aqui está a versão curta do motivo pelo qual escolhemos o que escolhemos:

Claude em vez de GPT-4: Testamos ambos extensivamente. Claude 3.5 Sonnet (e agora Claude 4 Sonnet em 2025) consistentemente produziu emails que soavam mais naturais e menos "escritos por IA". Também era melhor em seguir system prompts complexos sem derivar. O preço era comparável, mas a janela de contexto mais longa do Claude significava que conseguíamos alimentar mais dados de pesquisa por prospect.

Supabase em vez de Airtable ou um setup Postgres customizado: Precisávamos de um banco de dados real com row-level security, mas não queríamos gerenciar infraestrutura. Supabase nos deu Postgres, Edge Functions, Cron jobs, e um dashboard decente — tudo em um lugar. Usamos Supabase pesadamente em projetos de clientes também, então o time já conhecia bem.

Instantly em vez de Lemlist ou Smartlead: A rede de warmup do Instantly é genuinamente boa, sua API é limpa, e o preço fez sentido para nosso volume. Não precisamos do construtor de sequências integrado do Instantly porque lidamos com a lógica de sequenciamento nós mesmos.

Hunter em vez de Apollo ou Snov.io: A verificação de email do Hunter é consistentemente a mais precisa que já testamos. Sua API de busca de domínio é rápida e a qualidade dos dados é alta. Apollo tem mais pontos de dados, mas descobrimos que sua precisão de email é menor, o que mata a entregabilidade.

Visão Geral da Arquitetura

O sistema funciona em cinco estágios, cada um rodando independentemente:

[Fontes de Lead] → [Enriquecimento Hunter] → [DB Supabase] → [Pesquisa Claude + Copy] → [Envio Instantly]
     ↑                                       ↑                                           |
     |                                       |                                           |
     +----------- Loop de Feedback ----------+-------------------------------------------+
  1. Ingestão: Alimentamos domínios de prospect de várias fontes (listas manuais, scrapers, dados de referência)
  2. Enriquecimento: Hunter encontra contatos e verifica emails
  3. Armazenamento: Tudo vai para Supabase com rastreamento de status
  4. Pesquisa + Escrita: Claude analisa cada prospect e gera copy personalizado
  5. Envio: Emails aprovados vão para campanhas Instantly
  6. Aprendizado: Dados de resposta fluem de volta para Supabase, informando personalização futura

Cada estágio é desacoplado. Se a API do Hunter cair, a fila de enriquecimento apenas acumula — não quebra o envio. Se quisermos trocar Claude por um modelo diferente, mudamos uma função.

Por Que Construímos Nosso Próprio Sistema de Cold Email com Claude, Instantly e Supabase - arquitetura

Encontrando e Enriquecendo Leads com Hunter

Hunter.io cuida de dois trabalhos críticos: encontrar a pessoa certa em uma empresa e verificar que seu email realmente funciona.

Aqui está uma versão simplificada de nossa função de enriquecimento:

import { createClient } from '@supabase/supabase-js';

const HUNTER_API_KEY = Deno.env.get('HUNTER_API_KEY');

async function enrichLead(domain: string) {
  // Busca de domínio para encontrar tomadores de decisão
  const searchRes = await fetch(
    `https://api.hunter.io/v2/domain-search?domain=${domain}&department=executive,it&api_key=${HUNTER_API_KEY}`
  );
  const searchData = await searchRes.json();
  
  const contacts = searchData.data.emails
    .filter((e: any) => e.confidence > 70)
    .slice(0, 3); // Top 3 contatos por domínio
  
  // Verificar cada email
  for (const contact of contacts) {
    const verifyRes = await fetch(
      `https://api.hunter.io/v2/email-verifier?email=${contact.value}&api_key=${HUNTER_API_KEY}`
    );
    const verifyData = await verifyRes.json();
    
    if (verifyData.data.status === 'valid') {
      await supabase.from('leads').insert({
        domain,
        email: contact.value,
        first_name: contact.first_name,
        last_name: contact.last_name,
        position: contact.position,
        confidence: contact.confidence,
        status: 'enriched',
        enriched_at: new Date().toISOString()
      });
    }
  }
}

Filtramos pelos departamentos executive e it porque esses são nossos compradores — CTOs, VPs de Engenharia, founders técnicos. A filtragem de departamento do Hunter não é perfeita, mas elimina muito barulho.

Uma coisa que aprendemos: nunca pule a verificação de email. Mesmo com scores de confiança do Hunter, ainda verificamos cada endereço. Uma taxa de bounce acima de 3% vai destruir a reputação do seu domínio de envio. Vimos domínios indo de 95% inbox placement para 40% pasta de spam de um lote ruim.

Rodamos cerca de 500 créditos de buscas Hunter por semana, que cabe confortavelmente no plano Starter deles.

Personalização com IA com Claude

Aqui é onde as coisas ficam interessantes. A integração Claude não é apenas "escreva um cold email para mim". É um pipeline multi-etapas de pesquisa e escrita.

Passo 1: Análise do Website

Antes do Claude escrever qualquer coisa, alimentamos com dados sobre o website do prospect. Raspamos informações básicas usando uma função leve:

async function analyzeProspectSite(domain: string) {
  // Buscar homepage e páginas chave
  const homepage = await fetch(`https://${domain}`);
  const html = await homepage.text();
  
  // Extrair sinais de tech do HTML
  const signals = {
    hasNextJs: html.includes('__next') || html.includes('_next/static'),
    hasReact: html.includes('react') || html.includes('__REACT'),
    hasWordPress: html.includes('wp-content') || html.includes('wp-includes'),
    hasShopify: html.includes('shopify') || html.includes('cdn.shopify'),
    hasGatsby: html.includes('gatsby'),
    usesJQuery: html.includes('jquery'),
    metaGenerator: extractMeta(html, 'generator'),
    pageSize: html.length,
    // ... mais sinais
  };
  
  // Rodar verificação PageSpeed via API
  const psiData = await fetchPageSpeedInsights(domain);
  
  return {
    ...signals,
    performanceScore: psiData.lighthouseResult.categories.performance.score * 100,
    lcp: psiData.lighthouseResult.audits['largest-contentful-paint'].numericValue,
    cls: psiData.lighthouseResult.audits['cumulative-layout-shift'].numericValue,
    fid: psiData.lighthouseResult.audits['max-potential-fid'].numericValue
  };
}

Isso dá a Claude dados reais para trabalhar. Não "Oi, notei que sua empresa faz X" — mais como "Sua homepage LCP é 4.2 segundos e você ainda está rodando jQuery junto com React, o que está adicionando 90KB ao seu bundle inicial."

Passo 2: Prompt de Pesquisa Claude

Usamos a API do Claude com um system prompt cuidadosamente elaborado. Aqui está uma versão simplificada:

const researchPrompt = `Você é um senior web developer analisando o website de um prospect para uma agência de desenvolvimento headless. Dados os seguintes dados técnicos sobre seu site, identifique:

1. Sua stack de tecnologia atual (seja específico)
2. 2-3 problemas concretos de performance ou arquitetura
3. O que uma migração para uma arquitetura headless moderna poderia melhorar
4. Uma observação específica e não óbvia que mostre análise genuína

NÃO seja genérico. Se não conseguir encontrar algo específico, diga isso.
NÃO mencione "na paisagem digital de hoje" ou filler similar.
Seja direto e técnico.

Dados do site:
${JSON.stringify(siteAnalysis, null, 2)}

Prospect: ${lead.first_name} ${lead.last_name}, ${lead.position} em ${lead.domain}`;

const research = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1000,
  messages: [{ role: 'user', content: researchPrompt }]
});

Passo 3: Geração de Email

A saída de pesquisa alimenta uma segunda chamada Claude que escreve o email real. Dividir pesquisa da escrita foi um insight chave — quando tentávamos fazer ambos em um prompt, os emails eram piores. Claude pularia a pesquisa para chegar à escrita mais rápido.

const emailPrompt = `Escreva um cold email de um senior developer em uma agência de desenvolvimento headless.

Notas de pesquisa:
${research.content[0].text}

Regras:
- 4-6 sentações máximo. Cada sentença deve ganhar seu lugar.
- Comece com a observação técnica mais específica.
- Sem bajulação. Sem "Amo o que você está fazendo".
- Um CTA claro: pergunte se gostariam de ver uma auditoria de performance.
- Soe como um developer, não um vendedor.
- Use primeiro nome. Sem sobrenome na saudação.
- Linha de assunto: curta, específica ao problema de tech deles, minúscula.`;

O resultado? Emails que começam com coisas como "Sua loja Shopify Plus está server-renderizando páginas de produto que poderiam ser geradas estaticamente — isso está adicionando 2+ segundos a cada visualização de produto" em vez de "Notei sua impressionante empresa e queria entrar em contato".

Supabase como Camada de Orquestração

Supabase é o cérebro da operação. Aqui está nosso schema principal:

create table leads (
  id uuid primary key default gen_random_uuid(),
  domain text not null,
  email text,
  first_name text,
  last_name text,
  position text,
  confidence int,
  status text default 'new', -- new, enriched, researched, drafted, approved, sent, replied, bounced
  site_analysis jsonb,
  research_notes text,
  email_subject text,
  email_body text,
  instantly_campaign_id text,
  sent_at timestamptz,
  opened_at timestamptz,
  replied_at timestamptz,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

create index idx_leads_status on leads(status);
create index idx_leads_domain on leads(domain);

O campo status dirige tudo. Cron jobs do Supabase rodamcada 15 minutos, pegando leads em cada estágio e empurrando para o próximo:

-- Cron: Processar leads enriquecidos através de pesquisa Claude
select cron.schedule(
  'process-research',
  '*/15 * * * *',
  $$select net.http_post(
    'https://your-project.supabase.co/functions/v1/process-research',
    '{}',
    '{"Authorization": "Bearer your-service-key"}'::jsonb
  )$$
);

Processamos em lote 20 leads por execução para ficar dentro dos limites de taxa do Claude e manter custos previsíveis.

A coluna site_analysis JSONB é incrivelmente útil. Conseguimos consultar todos os nossos leads para encontrar padrões — como "mostre-me todos os leads rodando WordPress com score de performance abaixo de 50" — e construir campanhas direcionadas a partir desses segmentos.

Enviando em Escala com Instantly

Instantly cuida do envio real de email. Empurramos emails aprovados via sua API:

async function pushToInstantly(lead: Lead) {
  const response = await fetch('https://api.instantly.ai/api/v1/lead/add', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      api_key: INSTANTLY_API_KEY,
      campaign_id: lead.instantly_campaign_id,
      skip_if_in_workspace: true,
      leads: [{
        email: lead.email,
        first_name: lead.first_name,
        last_name: lead.last_name,
        company_name: lead.domain,
        personalization_1: lead.email_subject,
        personalization_2: lead.email_body
      }]
    })
  });
  
  if (response.ok) {
    await supabase
      .from('leads')
      .update({ status: 'sent', sent_at: new Date().toISOString() })
      .eq('id', lead.id);
  }
}

Templates de campanha do Instantly usam variáveis {{personalization_1}} e {{personalization_2}}, que mapeiam para nosso subject e body gerados por Claude. A campanha em si é apenas um shell — toda a inteligência vive no nosso sistema.

Rodamos 3 contas de envio através do warmup do Instantly por pelo menos 2 semanas antes de enviar qualquer outreach. Domain warmup não é opcional. Aprendemos isso da forma difícil com nosso primeiro domínio sendo sinalizado dentro de uma semana.

Setup de Entregabilidade

Nossa infraestrutura de envio:

  • 3 domínios (variações da nossa marca, não nosso domínio principal)
  • SPF, DKIM, e DMARC configurados em todos eles
  • Contas Google Workspace (não Outlook — Google lida melhor com cold email em nosso teste)
  • Warmup do Instantly rodando continuamente, mesmo em dias de envio ativo
  • Máximo 35 emails por conta por dia
  • Intervalos de envio aleatórios entre 3-7 minutos

A Cola de Automação

Supabase Edge Functions conectam tudo. Aqui está o fluxo em pseudocódigo:

A cada 15 minutos:
  1. Pegue leads com status='new', rode enriquecimento Hunter → status='enriched'
  2. Pegue leads com status='enriched', rode análise de site → status='analyzed'
  3. Pegue leads com status='analyzed', rode pesquisa Claude + geração de email → status='drafted'
  4. (Humano revisa emails rascunhados no dashboard Supabase)
  5. Pegue leads com status='approved', empurre para Instantly → status='sent'
  6. Puxe dados de engajamento da API Instantly → atualize opened_at, replied_at

Passo 4 é importante. Não automatizamos totalmente o envio. Todo email recebe revisão humana antes de sair. Isso pega a alucinação ocasional do Claude (Claude uma vez afirmou que um site foi construído com Remix quando era claramente Next.js) e nos deixa adicionar toques pessoais.

O passo de revisão leva cerca de 2-3 segundos por email já que Claude acerta 95% do tempo. Aprovamos em lotes usando uma visualização simples do dashboard Supabase.

Resultados e O Que Aprendemos

Estamos rodando este sistema desde Q1 2025. Aqui estão números reais:

| Métrica | Nosso Sistema | Média da Indústria (2026) | |--------|-----------|------------------------|| | Taxa de Abertura | 62% | 24% | | Taxa de Resposta | 8.4% | 1-3% | | Taxa de Resposta Positiva | 4.1% | 0.5-1% | | Taxa de Bounce | 0.8% | 3-5% | | Custo Por Lead Contatado | $0.18 | $0.50-2.00 | | Tempo Por Lead (humano) | ~5 segundos (revisão) | 10-15 minutos |

A taxa de abertura é alta porque as linhas de assunto são específicas. "seu lcp shopify é 4.2s" é aberto. "Pergunta rápida" não é.

A taxa de resposta é alta porque os emails demonstram conhecimento técnico genuíno. Quando um CTO lê um email que identifica corretamente sua stack de tech e um problema de performance real, é mais provável que se engaje — mesmo que saiba que é outreach.

O Que Não Funcionou

Envio totalmente automatizado (sem revisão humana): Tentamos isso por duas semanas. Claude alucinava detalhes de stack de tech cerca de 5% das vezes. Essa é uma taxa de erro baixa para um LLM, mas enviar um email que diz "seu app React" para alguém rodando Vue é pior que enviar um email genérico. O dano de confiança é real.

Emails longos: Nossos primeiros prompts Claude geravam emails de 8-10 sentações. As taxas de resposta eram metade do que vemos agora com 4-6 sentações. Menor sempre é melhor.

Enviando mais de 40 emails por dia por conta: A entregabilidade cai um penhasco. 30-35 é o sweet spot em 2026.

Usar Claude para follow-ups baseados em aberturas: Tentamos gerar emails de follow-up acionados por aberturas. Os follow-ups se sentiam insistentes e a conversão não valia o custo. Agora enviamos um simples follow-up sem IA três dias depois.

Breakdown de Custos

Aqui está o que isso nos custa mensalmente, processando aproximadamente 2.000 leads:

Serviço Custo Mensal Notas
Hunter.io (Starter) $49 500 buscas + verificações
Anthropic API (Claude) $45 ~2.000 pesquisas + gerações de email
Supabase (Pro) $25 Banco de dados, Edge Functions, Cron
Instantly (Growth) $30 Envio, warmup, analytics
Google Workspace (3 contas) $21 Infraestrutura de envio
Domínios (3) $10 Custo anual amortizado
Total ~$180 $0.09 por lead processado

Compare isso com o plano de $79/mês do Apollo (enriquecimento limitado, sequências básicas) ou o $69/mês por assento do Lemlist. Estamos gastando menos e obtendo resultados dramaticamente melhores porque a personalização é real, não baseada em templates.

Para contexto, este sistema gerou diretamente leads que se transformaram em projetos de desenvolvimento Next.js e desenvolvimento Astro no valor de 50-100x o custo mensal. O ROI é absurdo.

FAQ

Quanto tempo levou para construir este sistema?

A primeira versão funcionando levou cerca de duas semanas de esforço em meio período — talvez 40 horas totais. Iteramos nele continuamente desde então, principalmente ajustando prompts Claude e adicionando tratamento de edge cases. Se você é confortável com Supabase Edge Functions e APIs REST, você poderia ter uma versão básica rodando em um fim de semana.

Isso não é apenas spam com passos extras?

Questão justa. A diferença é que todo email contém uma observação técnica genuína sobre o website do destinatário. Não estamos disparando "vamos fazer uma call" para 10.000 pessoas. Estamos enviando insights específicos e úteis para uma lista alvo de pessoas que realmente têm os problemas que resolvemos. Nossa taxa de unsubscribe é inferior a 0,5%, o que sugere que os destinatários não veem como spam também.

Por que Claude em vez de GPT-4 ou Gemini?

Testamos os três. Claude seguiu nossos system prompts de forma mais confiável — especialmente os constrains como "não seja genérico" e "não use frases de enchimento". GPT-4 derivaria para linguagem de vendas mesmo com instruções explícitas para não fazer. Gemini era rápido mas a qualidade de saída era inconsistente. Isso pode mudar conforme os modelos evoluem, e nosso sistema é projetado para trocar modelos facilmente.

Como você lida com conformidade GDPR e CAN-SPAM?

Todo nosso outreach é direcionado para emails comerciais (não pessoais), inclui nosso endereço físico, e tem um opt-out claro em cada email. Para GDPR, processamos dados sob interesse legítimo para outreach B2B, mantemos registros de atividades de processamento, e honramos pedidos de remoção imediatamente via um webhook automatizado. Também purgamos leads com mais de 90 dias automaticamente do nosso banco de dados. Converse com um advogado para sua situação específica — isso não é aconselhamento legal.

O que acontece quando um lead responde?

Respostas fluem de volta da API do Instantly para Supabase. Recebemos uma notificação Slack para cada resposta, e um humano assume a conversa imediatamente. Nunca usamos IA para tratamento de resposta. Uma vez que alguém se engaja, merece uma pessoa real. Prospects interessados são apontados para nossa página de contato ou diretamente para um link de agendamento de call.

Essa abordagem pode funcionar para serviços não-técnicos?

A peça de análise de site é específica para desenvolvimento web, mas o padrão de arquitetura — enriquecer leads, usar IA para pesquisar e personalizar, enviar através de uma ferramenta dedicada — funciona para qualquer outreach B2B. Você apenas precisaria de inputs de pesquisa diferentes. Uma agência de design poderia analisar design visual e padrões de UX. Uma agência de marketing poderia puxar métricas SEO. A chave é alimentar Claude dados reais, não pedir para inventar coisas.

Qual é a parte mais difícil de manter este sistema?

Manutenção de prompt. Conforme os modelos Claude atualizam, prompts que funcionavam perfeitamente às vezes precisam de ajuste. Também passamos tempo monitorando entregabilidade de email — verificando Google Postmaster Tools, assistindo por picos de taxa de spam, rotacionando contas de envio. São talvez 2-3 horas por semana de manutenção total.

Você venderia isso como um produto?

Pensamos nisso, mas honestamente a vantagem competitiva é muito valiosa. Se toda agência rodasse este exato sistema, a efetividade cairia porque destinatários começariam a ver emails pesquisados por IA em todos os lugares. Por enquanto, estamos mantendo como uma ferramenta interna. Se você quer ajuda construindo algo similar para seu negócio, entre em contato — ajudamos alguns clientes a configurar sistemas similares como parte do nosso trabalho de desenvolvimento headless CMS.