Ilustrativo — o HTTP Request no centro fala com qualquer serviço; a paginação processa listas em lotes.
🌐 HTTP Request e APIs REST
O HTTP Request node é o canivete suíço: quando não existe node nativo, ele fala com qualquer API REST. Você define método, URL, headers e body, e recebe a resposta como item.
GET https://api.exemplo.com/v1/pedidos
?status=={{ $json.status }}&limit=50
// a resposta vira item; acesse com: ={{ $json.data }}
📊 Os verbos REST que importam
- GET - ler dados (não muda nada no servidor).
- POST - criar um novo registro.
- PUT/PATCH - atualizar um registro existente.
- DELETE - remover. Confira sempre o status code: 2xx ok, 4xx erro seu, 5xx erro deles.
🪪 Autenticação
O erro 401 Unauthorized é o tropeço nº1 em integração. A API precisa provar quem é você: um token no header (Bearer) ou um fluxo de consentimento (OAuth2).
Authorization: Bearer ={{ $env.API_TOKEN }}
Content-Type: application/json
✓ Bearer token
- ✓Simples: 1 chave fixa no header.
- ✓Bom para APIs de servidor (OpenAI, Stripe).
- ✓Guarde a chave em $env/credential.
✓ OAuth2
- ✓Para acessar conta de um usuário (Google, Slack).
- ✓O n8n renova o token automaticamente (refresh).
- ✓Configure uma vez na credential e reuse.
⚠️ Deu 401? Cheque nesta ordem
Chave certa? Header com o nome exato (Authorization)? Prefixo Bearer com espaço? Token expirado (OAuth)? Escopo suficiente? 90% dos 401 caem aqui.
🗄️ Supabase / banco: ler e gravar
O banco é a memória da automação. Sem ele, cada execução esquece tudo. Com Supabase/Postgres você lê com SELECT e grava com INSERT/UPDATE — ou melhor, UPSERT, que grava ou atualiza por chave única.
POST https://abcd.supabase.co/rest/v1/leads
Headers:
apikey: ={{ $env.SUPABASE_SERVICE_KEY }}
Prefer: resolution=merge-duplicates
Body:
{ "email": "={{ $json.email }}", "intencao": "={{ $json.intencao }}" }
🔑 Chave única = sua âncora
Defina uma coluna única (ex.: email). O UPSERT usa ela para decidir entre criar e atualizar — é o que evita duplicata (assunto do módulo 4.4).
- •SELECT com filtro ?email=eq.ana@x.com para ler.
- •Prefer: resolution=merge-duplicates faz o UPSERT no Supabase.
📊 Planilhas (Google Sheets)
O Google Sheets é o "banco" favorito de quem não é dev. Cliente entende planilha. Entregar resultado numa aba é a forma mais rápida de mostrar valor sem treinar ninguém — leitura por linha, escrita por append ou update.
Nome: ={{ $json.nome }}
Email: ={{ $json.email }}
Prioridade: ={{ $json.prioridade }}
Data: ={{ $now.format('dd/MM/yyyy') }}
Adiciona linha nova
Por chave/coluna
Planilha como entrada
Aba e intervalo
💡 Dica prática
Planilha é ótima para entrega visível, mas péssima como banco transacional. Para dedupe e volume, use Supabase; para o cliente ver o resultado, espelhe numa aba.
🔄 Paginação e processar listas
APIs limitam quantos itens devolvem por chamada e impõem rate limit. Processar tudo de uma vez quebra. SplitInBatches (Loop Over Items) fatia a lista em lotes; cursor/offset busca página por página.
GET https://api.exemplo.com/v1/itens?cursor=={{ $json.next_cursor }}
// repita o HTTP node em loop enquanto next_cursor não for null
// SplitInBatches: tamanho 50 + Wait 1s entre lotes p/ respeitar rate limit
⚠️ O erro N+1 e o rate limit
Disparar uma chamada por item, sem lote nem espera, leva ao 429 Too Many Requests e a custo absurdo. Sempre agrupe em batches e adicione um Wait entre eles.
Fatie a lista
SplitInBatches com tamanho de lote (ex.: 50) divide 500 itens em 10 voltas.
Processe o lote e espere
Faça o trabalho do lote, adicione um node Wait, e volte ao SplitInBatches.
Pare quando acabar
O loop encerra quando não há mais lotes (ou next_cursor é null).
🧮 Tratar nulos e mapear campos
Um campo nulo inesperado quebra o fluxo no meio. Expressões n8n ={{ }} com valor padrão e optional chaining tornam a automação resiliente a dados sujos.
// valor padrão quando vem nulo/undefined ={{ $json.email ?? 'sem-email@placeholder.com' }} // optional chaining evita "cannot read property of undefined" ={{ $json.cliente?.endereco?.cidade ?? 'N/D' }} // renomear/formatar ao mapear ={{ $json.valor ? 'R$ ' + $json.valor.toFixed(2) : 'R$ 0,00' }}
✓ Mapeamento resiliente
- ✓Sempre ?? valor_padrao em campo que pode faltar.
- ✓?. em objetos aninhados de fonte externa.
- ✓Formatar tipos (data, número) no mapeamento.
✗ Mapeamento frágil
- ✗Assumir que todo item tem todos os campos.
- ✗Acessar $json.a.b.c sem proteção.
- ✗Gravar undefined no banco/planilha.
📌 Resumo do Módulo
Próximo Módulo:
4.4 - Confiabilidade (erros, retries, idempotência, observabilidade, checklist de produção)