This workflow follows the Gmail → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "My workflow",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"daysInterval": 3,
"triggerAtHour": 9
}
]
}
},
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [
0,
0
],
"id": "e925c8fb-4834-4a79-a659-822289d526f8",
"name": "Schedule Trigger"
},
{
"parameters": {
"url": "https://pncp.gov.br/api/search",
"sendQuery": true,
"queryParameters": {
"parameters": [
{
"name": "q",
"value": "advocaticio"
},
{
"name": "status",
"value": "recebendo_proposta"
},
{
"name": "tipos_documento",
"value": "edital"
},
{
"name": "ordenacao",
"value": "-data"
},
{
"name": "pagina",
"value": "1"
},
{
"name": "tam_pagina",
"value": "20"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [
208,
0
],
"id": "dc2647ff-c4a4-4d1b-ab6f-89e43a974609",
"name": "HTTP Request"
},
{
"parameters": {
"jsCode": "// Code node n8n - Formata licita\u00e7\u00f5es PNCP em HTML para envio via Gmail\nconst inputData = $input.all();\nconst dados = inputData[0].json;\nconst PALAVRAS_CHAVE = ['advocat', 'jur\u00eddic', 'juridic', 'assessoria jur\u00eddica', 'assessoria juridica', 'servi\u00e7os jur\u00eddicos', 'servi\u00e7os juridicos'];\n\nconst todoItems = dados.items || [];\nconst items = todoItems.filter(item => {\n if (item.situacao_nome === 'Revogada' || item.tem_resultado) return false;\n const texto = ((item.title || '') + ' ' + (item.description || '')).toLowerCase();\n return PALAVRAS_CHAVE.some(p => texto.includes(p));\n});\nconst total = items.length;\n\nfunction formatarData(isoStr) {\n if (!isoStr) return '\u2014';\n const d = new Date(isoStr);\n return d.toLocaleDateString('pt-BR', {\n day: '2-digit', month: '2-digit', year: 'numeric',\n hour: '2-digit', minute: '2-digit'\n });\n}\n\nfunction formatarCNPJ(cnpj) {\n if (!cnpj || cnpj.length !== 14) return cnpj || '\u2014';\n return cnpj.replace(/^(\\d{2})(\\d{3})(\\d{3})(\\d{4})(\\d{2})$/, '$1.$2.$3/$4-$5');\n}\n\nfunction corSituacao(situacao) {\n const cores = {\n 'Divulgada no PNCP': '#2e7d32',\n 'Revogada': '#c62828',\n 'Suspensa': '#ef6c00',\n 'Anulada': '#c62828',\n };\n return cores[situacao] || '#555555';\n}\n\nconst agora = new Date().toLocaleDateString('pt-BR', {\n day: '2-digit', month: '2-digit', year: 'numeric',\n hour: '2-digit', minute: '2-digit'\n});\n\nlet cardsHtml = '';\n\nitems.forEach((item, i) => {\n const situacaoCor = corSituacao(item.situacao_nome);\n const local = [item.municipio_nome, item.uf].filter(Boolean).join(', ');\n const url = item.item_url ? `https://pncp.gov.br${item.item_url.replace('/compras/', '/app/editais/')}` : '#';\n const descricao = (item.description || '').trim();\n\n cardsHtml += `\n <div style=\"background:#ffffff; border:1px solid #e0e0e0; border-radius:8px; padding:20px; margin-bottom:16px; border-left:4px solid ${situacaoCor};\">\n <h3 style=\"margin:0 0 8px 0; color:#1a237e; font-size:16px;\">\n ${i + 1}. ${item.title || 'Sem titulo'}\n </h3>\n\n <span style=\"display:inline-block; background:${situacaoCor}; color:#fff; padding:3px 10px; border-radius:12px; font-size:12px; font-weight:bold; margin-bottom:12px;\">\n ${item.situacao_nome || '\u2014'}\n </span>\n ${item.tem_resultado ? '<span style=\"display:inline-block; background:#1565c0; color:#fff; padding:3px 10px; border-radius:12px; font-size:12px; font-weight:bold; margin-left:6px;\">Com Resultado</span>' : ''}\n\n <p style=\"margin:12px 0 16px 0; color:#333; font-size:14px; line-height:1.5;\">\n ${descricao.length > 400 ? descricao.substring(0, 400) + '...' : descricao}\n </p>\n\n <table style=\"width:100%; border-collapse:collapse; font-size:13px; color:#444;\">\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; width:140px; color:#666;\">Orgao</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.orgao_nome || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">CNPJ</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${formatarCNPJ(item.orgao_cnpj)}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Unidade</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.unidade_nome || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Local</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${local || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Poder / Esfera</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.poder_nome || '\u2014'} / ${item.esfera_nome || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Modalidade</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.modalidade_licitacao_nome || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Tipo</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.tipo_nome || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">N Controle</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${item.numero_controle_pncp || '\u2014'}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Publicacao</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${formatarData(item.data_publicacao_pncp)}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Inicio Vigencia</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${formatarData(item.data_inicio_vigencia)}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; border-bottom:1px solid #f0f0f0; font-weight:bold; color:#666;\">Fim Vigencia</td>\n <td style=\"padding:6px 0; border-bottom:1px solid #f0f0f0;\">${formatarData(item.data_fim_vigencia)}</td>\n </tr>\n <tr>\n <td style=\"padding:6px 12px 6px 0; font-weight:bold; color:#666;\">Ultima Atualizacao</td>\n <td style=\"padding:6px 0;\">${formatarData(item.data_atualizacao_pncp)}</td>\n </tr>\n </table>\n\n <div style=\"margin-top:14px;\">\n <a href=\"${url}\" style=\"display:inline-block; background:#1a237e; color:#ffffff; padding:8px 20px; border-radius:6px; text-decoration:none; font-size:13px; font-weight:bold;\">\n Ver no PNCP\n </a>\n </div>\n </div>`;\n});\n\nconst htmlCompleto = `\n<div style=\"font-family:'Segoe UI',Roboto,Arial,sans-serif; max-width:700px; margin:0 auto; background:#f5f5f5; padding:24px;\">\n\n <div style=\"background:#1a237e; color:#ffffff; padding:20px 24px; border-radius:8px 8px 0 0; text-align:center;\">\n <h1 style=\"margin:0; font-size:22px;\">Monitoramento PNCP</h1>\n <p style=\"margin:6px 0 0 0; font-size:14px; opacity:0.85;\">Licitacoes advocaticias e juridicas</p>\n </div>\n\n <div style=\"background:#ffffff; padding:16px 24px; border-bottom:1px solid #e0e0e0;\">\n <table style=\"width:100%; font-size:14px; color:#333;\">\n <tr>\n <td><strong>Total encontrado:</strong> <span style=\"color:#1a237e; font-size:18px; font-weight:bold;\">${total}</span> licitacao(oes)</td>\n <td style=\"text-align:right; color:#888;\">Consultado em: ${agora}</td>\n </tr>\n </table>\n </div>\n\n <div style=\"padding:20px 0;\">\n ${cardsHtml}\n </div>\n\n <div style=\"text-align:center; padding:16px; color:#999; font-size:12px; border-top:1px solid #e0e0e0;\">\n Relatorio gerado automaticamente via n8n | Fonte: PNCP (pncp.gov.br)\n </div>\n\n</div>`;\n\nreturn [{ json: { html: htmlCompleto, total: total, assunto: `PNCP: ${total} licitacao(oes) advocaticias/juridicas encontradas - ${agora}` } }];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
416,
0
],
"id": "f2d71b01-5067-454e-9a89-575e17d9bd8f",
"name": "Code in JavaScript"
},
{
"parameters": {
"sendTo": "joaovtesteves2002@gmail.com, rozangelasousa.adv@gmail.com",
"subject": "={{ $json.assunto }}",
"message": "={{ $json.html }}",
"options": {
"appendAttribution": false,
"senderName": "Automa\u00e7\u00e3o Licita\u00e7\u00e3o PNCP"
}
},
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.2,
"position": [
624,
0
],
"id": "66c945a6-064b-423c-9bd8-49dfbeb15d0d",
"name": "Send a message",
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false,
"timeSavedMode": "fixed",
"timezone": "America/Sao_Paulo",
"callerPolicy": "workflowsFromSameOwner"
},
"staticData": {
"node:Schedule Trigger": {
"recurrenceRules": [
87
]
}
},
"triggerCount": 1,
"meta": {
"templateCredsSetupCompleted": true
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Wf-Jv. Uses httpRequest, gmail. Scheduled trigger; 4 nodes.
Source: https://github.com/jvtavarese/pncp-licitacoes/blob/efe5de9343d6364c9307a8dcf2661bda3079d13e/legacy/n8n-workflow/wf-jv.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
YOUR_ID 4. Uses gmail, googleDrive, googleSheets, httpRequest. Scheduled trigger; 53 nodes.
14310 Send Overdue Invoice Payment Reminders With Ifirma Gmail Postgrid And Slack. Uses httpRequest, stopAndError, slack, gmail. Scheduled trigger; 53 nodes.
Addendo — Blog Automatico Don Jacinto Nahual. Uses httpRequest, redis, github, gmail. Scheduled trigger; 51 nodes.
Addendo — Blog Automatico Don Jacinto Nahual. Uses httpRequest, redis, github, gmail. Scheduled trigger; 51 nodes.
Instead of providing a routine check, it focuses on significant movements by: Sending a Slack alert only if a query crosses a defined movement threshold. Emailing a structured report with the Top 25 i