---
title: "Como importar contatos CSV ou Excel para a Brevo com um script (Python, Node.js, cURL)"
description: "Importe contatos em massa de um arquivo CSV ou Excel para a Brevo usando a API import-contacts. Inclui scripts Python e Node.js prontos para rodar, um one-liner cURL, tratamento de erros e dicas para arquivos maiores que 10 MB."
url: https://tajo.io/pt/blog/import-csv-contacts-to-brevo-with-a-script/
markdown: https://tajo.io/pt/blog/import-csv-contacts-to-brevo-with-a-script.md
lang: pt-BR
author: "Set Noa"
author_url: https://tajo.io/pt/set-noa/
published: 2026-04-30
updated: 2026-05-18
alternates: {en-US: /blog/import-csv-contacts-to-brevo-with-a-script.md, bg-BG: /bg/blog/import-csv-contacts-to-brevo-with-a-script.md, cs-CZ: /cz/blog/import-csv-contacts-to-brevo-with-a-script.md, de-DE: /de/blog/import-csv-contacts-to-brevo-with-a-script.md, da-DK: /dk/blog/import-csv-contacts-to-brevo-with-a-script.md, es-ES: /es/blog/import-csv-contacts-to-brevo-with-a-script.md, fr-FR: /fr/blog/import-csv-contacts-to-brevo-with-a-script.md, el-GR: /gr/blog/import-csv-contacts-to-brevo-with-a-script.md, hi-IN: /hi/blog/import-csv-contacts-to-brevo-with-a-script.md, id-ID: /in/blog/import-csv-contacts-to-brevo-with-a-script.md, hr-HR: /hr/blog/import-csv-contacts-to-brevo-with-a-script.md, hu-HU: /hu/blog/import-csv-contacts-to-brevo-with-a-script.md, it-IT: /it/blog/import-csv-contacts-to-brevo-with-a-script.md, ja-JP: /jp/blog/import-csv-contacts-to-brevo-with-a-script.md, ko-KR: /kr/blog/import-csv-contacts-to-brevo-with-a-script.md, ar-SA: /ar/blog/import-csv-contacts-to-brevo-with-a-script.md, nl-NL: /nl/blog/import-csv-contacts-to-brevo-with-a-script.md, no-NO: /no/blog/import-csv-contacts-to-brevo-with-a-script.md, pl-PL: /pl/blog/import-csv-contacts-to-brevo-with-a-script.md, ro-RO: /ro/blog/import-csv-contacts-to-brevo-with-a-script.md, ru-RU: /ru/blog/import-csv-contacts-to-brevo-with-a-script.md, sv-SE: /se/blog/import-csv-contacts-to-brevo-with-a-script.md, zh-CN: /zh-cn/blog/import-csv-contacts-to-brevo-with-a-script.md, sl-SI: /sl/blog/import-csv-contacts-to-brevo-with-a-script.md, sr-Latn-RS: /sr/blog/import-csv-contacts-to-brevo-with-a-script.md, th-TH: /th/blog/import-csv-contacts-to-brevo-with-a-script.md, tr-TR: /tr/blog/import-csv-contacts-to-brevo-with-a-script.md, ur-PK: /ur/blog/import-csv-contacts-to-brevo-with-a-script.md, vi-VN: /vi/blog/import-csv-contacts-to-brevo-with-a-script.md, sk-SK: /sk/blog/import-csv-contacts-to-brevo-with-a-script.md}
---

[Sincronização de dados](https://tajo.io/pt/blog/?category=data-sync)

# Como importar contatos CSV ou Excel para a Brevo com um script (Python, Node.js, cURL)

Importe contatos em massa de um arquivo CSV ou Excel para a Brevo usando a API import-contacts. Inclui scripts Python e Node.js prontos para rodar, um one-liner cURL, tratamento de erros e dicas para arquivos maiores que 10 MB.

import csv contacts to brevo

Qual endpoint do Brevo importa contatos em massa?

Use POST /v3/contacts/import. Envie CSV como fileBody (≤10 MB), JSON como jsonBody, ou uma URL via fileUrl para arquivos grandes. O endpoint é assíncrono e devolve um processId. Exemplos em Python, Node.js e cURL mais abaixo.

[Saiba mais](https://tajo.io/pt/blog/import-csv-contacts-to-brevo-with-a-script/#o-endpoint-num-relance)

| Campo de origem | Campo de destino | Valor de exemplo |
| --- | --- | --- |
| `EMAIL` | `EMAIL` | `alex@example.com` |
| `FIRSTNAME` | `FIRSTNAME` | `Alex` |
| `LASTNAME` | `LASTNAME` | `Example` |

Se você já precisou empurrar uns milhares de contatos de uma planilha para a Brevo, sabe que o caminho manual da interface fica chato rápido: escolher o arquivo, mapear colunas, escolher uma lista, esperar, repetir. Um script faz o mesmo trabalho em segundos e, mais importante ainda, você pode rodar de novo de forma agendada, depois de um export do banco de dados ou sempre que o seu CRM cuspir um CSV novo.

Esta guia cobre o endpoint da API que a Brevo te dá exatamente para isso, com scripts completos e funcionando em Python, Node.js e um one-liner cURL. Tudo nesta guia bate em **`POST /v3/contacts/import`**.

## O endpoint num relance

```http
POST https://api.brevo.com/v3/contacts/import
Content-Type: application/json
api-key: YOUR_API_KEY

{
  "fileBody": "EMAIL;FIRSTNAME;LASTNAME\njane@example.com;Jane;Doe",
  "listIds": [42],
  "updateExistingContacts": true,
  "emailBlacklist": false,
  "smsBlacklist": false
}
```

A resposta volta rápido:

```json
{ "processId": 78 }
```

Isso é um 202 Accepted, a Brevo aceitou a importação e está processando em segundo plano. O `processId` é o seu identificador de rastreamento se quiser fazer polling até terminar ou configurar um webhook `notifyUrl`.

Algumas coisas que vale a pena saber antes de escrever código:

- **O corpo pode ser CSV (`fileBody`), JSON (`jsonBody`) ou uma URL remota (`fileUrl`).** Escolha um. A forma CSV usa ponto e vírgula (`;`) para separar colunas, não vírgula, é uma pegadinha clássica.
- **`fileBody` e `jsonBody` têm teto de 10 MB.** A Brevo recomenda ficar em torno de 8 MB para ir tranquilo. Para qualquer coisa maior, suba o arquivo para S3, GCS ou qualquer host HTTPS e passe `fileUrl` no lugar.
- **Atributos personalizados que não existem na sua conta são ignorados em silêncio.** Crie eles na interface da Brevo (ou via API de Atributos) antes de importar linhas que os usem, do contrário os dados simplesmente somem.
- **`updateExistingContacts` é `true` por padrão.** Se você colocar como `false`, a Brevo pula contatos cujo email já existe, útil para tarefas de “adicionar só os novos”.
- **`emptyContactsAttributes`** controla se células vazias do seu CSV apagam valores existentes. Padrão `false` (células vazias são ignoradas). Coloque como `true` se o seu CSV é a fonte da verdade e os vazios devem limpar dados desatualizados.

## Conseguir uma API key

Faça login na Brevo → **Configurações → SMTP & API → API Keys** → crie uma nova chave. Tem o formato `xkeysib-...`. Você vai passar como header HTTP `api-key` em cada requisição. Trate como uma senha, ela tem acesso completo de leitura e escrita na sua conta.

Padrão limpo: coloque numa variável de ambiente para nunca cair na sua árvore de fontes.

```bash
export BREVO_API_KEY="xkeysib-..."
```

## Python: ler um CSV, enviar para a Brevo

Este é o script mais simples possível: ler um CSV local com a biblioteca padrão, enviar o corpo direto para a Brevo. Não precisa de nenhum SDK de terceiros além do `requests`.

```python
import csv
import io
import os
import sys
import requests

API_KEY = os.environ["BREVO_API_KEY"]
LIST_ID = 42  # the Brevo list to add contacts to
INPUT_FILE = sys.argv[1] if len(sys.argv) > 1 else "contacts.csv"

# Brevo wants semicolon-separated CSV. If your file uses commas (most do),
# convert it on the fly so you don't have to edit the source spreadsheet.
def to_brevo_csv(path: str) -> str:
    with open(path, newline="", encoding="utf-8") as f:
        reader = csv.reader(f)  # default: comma-separated
        out = io.StringIO()
        writer = csv.writer(out, delimiter=";")
        for row in reader:
            writer.writerow(row)
        return out.getvalue()

body = {
    "fileBody": to_brevo_csv(INPUT_FILE),
    "listIds": [LIST_ID],
    "updateExistingContacts": True,
    "emptyContactsAttributes": False,
    "emailBlacklist": False,
    "smsBlacklist": False,
}

resp = requests.post(
    "https://api.brevo.com/v3/contacts/import",
    json=body,
    headers={"api-key": API_KEY, "Content-Type": "application/json"},
    timeout=60,
)

if resp.status_code != 202:
    print(f"Import failed: {resp.status_code} {resp.text}")
    sys.exit(1)

process_id = resp.json()["processId"]
print(f"Import accepted. Process ID: {process_id}")
```

Rode:

```bash
python import_csv_to_brevo.py contacts.csv
```

A primeira linha do seu CSV é o cabeçalho. Os nomes das colunas são mapeados para atributos da Brevo por **maiúsculas, correspondência exata**: `EMAIL`, `FIRSTNAME`, `LASTNAME`, mais qualquer atributo personalizado que você tenha definido. `EMAIL` é obrigatório.

```csv
EMAIL,FIRSTNAME,LASTNAME,COMPANY,CITY
jane@example.com,Jane,Doe,Acme,Berlin
john@example.com,John,Smith,Globex,Paris
```

Esse é o fluxo todo. O script volta em menos de um segundo, a importação real roda no servidor e leva entre poucos segundos e alguns minutos dependendo do volume.

## Arquivos Excel: três caminhos viáveis

O endpoint de importação da Brevo não lê `.xlsx` diretamente, então você tem três opções reais dependendo de onde o trabalho precisa viver:

1. **Rodar uma macro VBA dentro da pasta de trabalho**, sincronização em um clique do próprio Excel, sem script externo. É a resposta certa quando o arquivo vive num desktop e seu time quer um botão na planilha. Código completo no [guia da macro VBA do Excel para a Brevo](https://tajo.io/pt/blog/import-excel-contacts-to-brevo-with-vba-macro).
2. **Office Scripts + Power Automate**, se a pasta de trabalho está no OneDrive/SharePoint e você quer sincronização agendada e desassistida. Também coberto no [guia do Excel](https://tajo.io/pt/blog/import-excel-contacts-to-brevo-with-vba-macro).
3. **Converter `.xlsx` para CSV via script**, o que cobre o resto desta seção. Melhor se você já está rodando Python ou Node num servidor e só precisa puxar uma pasta de trabalho uma vez por dia.

Para a opção 3, pandas faz isso em uma linha:

```python
# pip install pandas openpyxl
import pandas as pd

def xlsx_to_brevo_csv(path: str, sheet_name: str | int = 0) -> str:
    df = pd.read_excel(path, sheet_name=sheet_name)
    return df.to_csv(sep=";", index=False)

body["fileBody"] = xlsx_to_brevo_csv("contacts.xlsx")
```

Se você não quer pandas como dependência, `openpyxl` sozinho também funciona:

```python
from openpyxl import load_workbook
import csv, io

def xlsx_to_brevo_csv(path: str) -> str:
    wb = load_workbook(path, read_only=True)
    ws = wb.active
    out = io.StringIO()
    writer = csv.writer(out, delimiter=";")
    for row in ws.iter_rows(values_only=True):
        writer.writerow(["" if v is None else v for v in row])
    return out.getvalue()
```

## Node.js: mesmo trabalho, SDK oficial

A Brevo publica `@getbrevo/brevo` para Node. Ele cuida da autenticação, retries e a forma tipada da requisição:

```javascript
// npm install @getbrevo/brevo
import fs from 'node:fs/promises';
import { BrevoClient } from '@getbrevo/brevo';

const API_KEY = process.env.BREVO_API_KEY;
const LIST_ID = 42;
const INPUT_FILE = process.argv[2] ?? 'contacts.csv';

const client = new BrevoClient({ apiKey: API_KEY });

// Read the CSV and convert commas to semicolons if needed
const raw = await fs.readFile(INPUT_FILE, 'utf-8');
const csv = raw.includes(';') ? raw : raw.replace(/,/g, ';');

const result = await client.contacts.importContacts({
  fileBody: csv,
  listIds: [LIST_ID],
  updateExistingContacts: true,
  emptyContactsAttributes: false,
});

console.log(`Import accepted. Process ID: ${result.processId}`);
```

Ou, se você não quer o SDK, um `fetch` puro funciona da mesma forma:

```javascript
const resp = await fetch('https://api.brevo.com/v3/contacts/import', {
  method: 'POST',
  headers: {
    'api-key': process.env.BREVO_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    fileBody: csv,
    listIds: [42],
    updateExistingContacts: true,
  }),
});

if (resp.status !== 202) {
  throw new Error(`Import failed: ${resp.status} ${await resp.text()}`);
}

const { processId } = await resp.json();
console.log(`Process ID: ${processId}`);
```

## cURL: um one-liner para importações pontuais

Quando você só quer testar o endpoint ou enfiar um arquivo pequeno na mão:

```bash
# Convert commas to semicolons, then send the file inline
csv=$(sed 's/,/;/g' contacts.csv | jq -Rs .)

curl -X POST https://api.brevo.com/v3/contacts/import \
  -H "api-key: $BREVO_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"fileBody\": $csv, \"listIds\": [42], \"updateExistingContacts\": true}"
```

`jq -Rs .` engole o arquivo inteiro e faz escape como JSON, evita ter que escapar manualmente quebras de linha e aspas.

## Arquivos maiores que 10 MB: use `fileUrl`

`fileBody` tem teto de 10 MB. Se o seu dump de contatos é maior, hospede o arquivo numa URL que a Brevo possa baixar e passe ela:

```python
body = {
    "fileUrl": "https://files.example.com/contacts/2026-04-30.csv",
    "listIds": [42],
    "updateExistingContacts": True,
}
```

Qualquer coisa acessível por uma URL HTTPS pública funciona, URLs pré-assinadas do S3, GCS, seu próprio host estático, até uma URL raw do GitHub para importações pontuais. A Brevo busca o arquivo na sua URL e depois roda a importação. Formatos aceitos: `.csv`, `.txt`, `.json`.

## Enviar JSON em vez de CSV

Se você já está puxando contatos de um banco de dados, não precisa fazer o desvio pelo CSV, mande direto como JSON:

```python
body = {
    "jsonBody": [
        {
            "email": "jane@example.com",
            "attributes": {
                "FIRSTNAME": "Jane",
                "LASTNAME": "Doe",
                "COMPANY": "Acme",
            },
        },
        {
            "email": "john@example.com",
            "attributes": {
                "FIRSTNAME": "John",
                "LASTNAME": "Smith",
                "COMPANY": "Globex",
            },
        },
    ],
    "listIds": [42],
}
```

Mesmo teto de 10 MB. Mesmo comportamento assíncrono.

## Polling até terminar

A importação é assíncrona, `processId` é o seu identificador para rastrear. Existe um endpoint separado para checar o status do processo:

```python
def wait_for_import(process_id: int, timeout_s: int = 600) -> dict:
    import time
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(
            f"https://api.brevo.com/v3/processes/{process_id}",
            headers={"api-key": API_KEY},
            timeout=30,
        )
        r.raise_for_status()
        status = r.json()
        if status["status"] in ("completed", "failed"):
            return status
        time.sleep(5)
    raise TimeoutError(f"Import {process_id} did not finish in {timeout_s}s")

result = wait_for_import(process_id)
print(f"Import {result['status']}: {result}")
```

Para tarefas longas, o padrão mais limpo é `notifyUrl`: passe um endpoint HTTPS para o qual a Brevo vai fazer POST quando a importação terminar, e dispense o polling.

```python
body["notifyUrl"] = "https://your-app.example.com/webhooks/brevo-import"
```

## Erros comuns e como resolver

**`400 Bad Request` sem causa óbvia.** Quase sempre é ponto e vírgula contra vírgula no CSV. A importação da Brevo espera `;`, não `,`. Confira de novo o `fileBody` depois do seu passo de conversão.

**Valores de atributos personalizados somem.** O atributo não existe na sua conta. Crie ele em **Contatos → Configurações → Atributos do contato** antes de importar, ou use a [API de Atributos](https://developers.brevo.com/reference/create-attribute) para criar como parte do seu script.

**`401 Unauthorized`.** Nome de header errado. É `api-key` (minúsculo, com hífen), não `Authorization` nem `X-API-Key`.

**Importação “succeeded” mas os contatos não apareceram na lista.** Confira se `listIds` contém a lista certa. Além disso: se `updateExistingContacts` está `false` e os contatos já existem, a Brevo os pula em silêncio em vez de adicionar de novo na lista.

**Algumas linhas importadas, outras não.** A Brevo te manda um relatório de erros linha por linha por email depois que a importação termina (a não ser que você coloque `disableNotification: true`). O relatório te diz quais linhas tinham email inválido, campos obrigatórios faltando ou problemas de formatação.

## Quando script e quando interface

A interface está bem para importações pontuais com menos de mil linhas. Um script ganha assim que:

- Você importa mais de uma vez (por exemplo, export semanal do seu CRM)
- Os dados de origem precisam ser limpos antes de cair na Brevo (deduplicação, formatar números de telefone, separar nomes completos em primeiro e último)
- Você quer que rode de forma agendada sem ninguém clicando
- O arquivo é maior do que a zona de conforto da interface

Embrulhe o script acima num cron job ou numa GitHub Action e você tem sincronização automática de contatos. O próximo post desta série mostra como fazer a mesma coisa direto de um Google Sheet usando Apps Script, sem servidor.

## Leitura adicional

- [API da Brevo: referência de importar contatos](https://developers.brevo.com/reference/import-contacts)
- [API da Brevo: atributos do contato](https://developers.brevo.com/reference/create-attribute)
- [Construir listas de contatos para suas campanhas de email](https://help.brevo.com/hc/en-us/articles/209499265)

## Perguntas frequentes

**Qual é o endpoint da API da Brevo para importação de contatos em massa?**

POST https://api.brevo.com/v3/contacts/import. Aceita conteúdo CSV (fileBody), uma URL de arquivo remoto (fileUrl) ou um array JSON (jsonBody). O endpoint é assíncrono, devolve um processId na hora e termina a importação em segundo plano.

**Qual é o tamanho máximo de arquivo?**

10 MB para CSV inline (fileBody) ou JSON (jsonBody). Para arquivos maiores, hospede o arquivo em um lugar acessível e passe a URL via fileUrl, esse caminho não tem limite de tamanho documentado.

**Como importo um arquivo .xlsx?**

A API de importação da Brevo aceita apenas .csv, .txt ou .json. Converta primeiro o .xlsx para .csv, pandas, openpyxl ou LibreOffice headless fazem isso em uma linha. O script desta guia inclui uma conversão de xlsx para csv.

**Vai sobrescrever os contatos existentes?**

Por padrão, sim: updateExistingContacts está como true e faz o match pelo email. Coloque como false para pular contatos que já existem. Coloque emptyContactsAttributes como true se quiser que células vazias do CSV apaguem valores existentes (caso contrário, células vazias são ignoradas).

## Artigos relacionados

### [Importar contatos do Google Sheets para a Brevo com Apps Script](https://tajo.io/pt/blog/import-google-sheet-contacts-to-brevo-apps-script/)

30 de abr. de 2026 · 3 min de leitura

Google Sheets → Brevo

### [Como empurrar contatos do Excel para a Brevo com uma macro VBA (e a alternativa Office Scripts)](https://tajo.io/pt/blog/import-excel-contacts-to-brevo-with-vba-macro/)

30 de abr. de 2026 · 7 min de leitura

Microsoft Excel → Brevo

### [Exportação e migração de dados na Brevo: como levar seus dados para dentro ou para fora](https://tajo.io/pt/blog/brevo-data-export-migration/)

19 de ago. de 2026 · 11 min de leitura

8 seções
