Integração · ESP / Email Marketing
Brevo (antigo Sendinblue) é um dos ESPs mais usados em PT-BR. O caminho que funciona é higienização periódica: exportar a lista pela API do Brevo, mandar tudo num lote pro EmailChecker, aguardar a conclusão e reimportar o resultado num atributo custom — mais a blocklist automática pros inválidos.
Como integrar
Em Contacts > Settings > Contact attributes, crie EMAIL_QUALITY (texto, nome em MAIÚSCULAS). É por ele que você vai segmentar depois.
GET https://api.brevo.com/v3/contacts?listIds=42&limit=500&offset=... paginando até esvaziar, juntando os emails num array. Validação dentro do formulário do Brevo não é possível: a API do EmailChecker é assíncrona.
POST https://app.emailchecker.email/api/v1/batch com {"emails": [...], "name": "brevo-lista-42"} e Authorization: Bearer ec_live_... Guarde o data.id da resposta 201.
GET https://app.emailchecker.email/api/v1/batch/{id} a cada 30 segundos até status = "completed". Não há webhook de retorno — o array data.emails só aparece preenchido nesse momento.
PUT https://api.brevo.com/v3/contacts/{email} gravando attributes.EMAIL_QUALITY com o result, e emailBlacklisted: true para os undeliverable. Depois filtre "EMAIL_QUALITY = deliverable" nas campanhas.
Exemplo · JAVASCRIPT
// Higienização em lote: Brevo -> EmailChecker -> Brevo
const EC = 'https://app.emailchecker.email/api/v1';
const ecH = {
Authorization: `Bearer ${process.env.EC_API_KEY}`,
'Content-Type': 'application/json',
};
const brevoH = {
'api-key': process.env.BREVO_API_KEY,
'Content-Type': 'application/json',
};
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// 1) exporta a lista paginando de 500 em 500
const emails = [];
for (let offset = 0; ; offset += 500) {
const url = `https://api.brevo.com/v3/contacts?listIds=42&limit=500&offset=${offset}`;
const pagina = await fetch(url, { headers: brevoH }).then((r) => r.json());
if (!pagina.contacts || pagina.contacts.length === 0) break;
emails.push(...pagina.contacts.map((c) => c.email));
}
// 2) envia o lote
const criado = await fetch(`${EC}/batch`, {
method: 'POST',
headers: ecH,
body: JSON.stringify({ emails, name: 'brevo-lista-42' }),
}).then((r) => r.json());
// 3) polling até completed (a plataforma não chama de volta)
let lote;
do {
await sleep(30_000);
lote = await fetch(`${EC}/batch/${criado.data.id}`, { headers: ecH }).then((r) => r.json());
} while (lote.data.status === 'pending' || lote.data.status === 'processing');
if (lote.data.status !== 'completed') throw new Error(`lote ${lote.data.status}`);
// 4) atributo pra segmentar + blocklist pros inválidos
for (const e of lote.data.emails) {
await fetch(`https://api.brevo.com/v3/contacts/${encodeURIComponent(e.email)}`, {
method: 'PUT',
headers: brevoH,
body: JSON.stringify({
attributes: { EMAIL_QUALITY: e.result },
emailBlacklisted: e.result === 'undeliverable',
}),
});
}A API do EmailChecker é REST com Bearer auth (`Authorization: Bearer ec_live_...`) na base `https://app.emailchecker.email` e é assíncrona: você envia o lote em `POST /api/v1/batch` e busca o resultado em `GET /api/v1/batch/{id}` até o `status` virar `completed`. Não existe endpoint de validação unitária nem webhook de retorno — quem descobre que o lote terminou é o polling. Limites: 1 a 100.000 emails por lote, 300 requisições/minuto e 10.000/hora. A API é exclusiva do plano Gold.
Casos de uso
Rode o lote na véspera do disparo e segmente por EMAIL_QUALITY = deliverable. A reputação do domínio agradece.
Importou uma lista nova? Antes de qualquer envio, passe a lista inteira por um lote — os undeliverable já entram direto na blocklist do Brevo.
Antes da campanha de win-back, revalide a lista de inativos: boa parte dos endereços parados há dois anos já virou undeliverable.
Troubleshooting
Os erros que mais aparecem ao conectar o Brevo (ex-Sendinblue) — e como resolver cada um.
O step Webhook do Workflow dispara e segue em frente — ele não aguarda resultado, e o EmailChecker não devolve nada de volta pro Brevo. Use o Workflow no máximo pra empilhar o email numa fila e faça a validação em lote num script agendado, consultando GET /api/v1/batch/{id} até completed.
Atributos custom precisam existir antes em Contacts > Settings com o nome em MAIÚSCULAS (ex: EMAIL_QUALITY) e o corpo deve ser { "attributes": { "EMAIL_QUALITY": "deliverable" } }. Chave em minúsculo ou fora do objeto attributes dá 400. URL-encode o email no path quando tiver "+".
O gargalo é o Brevo, não o EmailChecker: a API transacional aceita cerca de 10 requisições por segundo. Espace os PUTs ou use POST /v3/contacts/import com o CSV do resultado inteiro. Do lado do EmailChecker o limite é bem folgado pra esse uso — 300 requisições/minuto e 10.000/hora, e o lote todo custa uma chamada de envio mais as de polling.
Comece grátis com 500 créditos. Sem cartão, sem compromisso.