Slik importerer du CSV- eller Excel-kontakter til Brevo med et skript (Python, Node.js, cURL)

Bulk-importer kontakter fra en CSV- eller Excel-fil inn i Brevo med import-contacts API-et. Inkluderer ferdige Python- og Node.js-skript, en cURL-one-liner, feilhåndtering og tips for filer større enn 10 MB.

import csv contacts to brevo

Hva er Brevos API-endepunkt for bulk-import av kontakter?

Bruk POST /v3/contacts/import. Send CSV som fileBody (≤10 MB), JSON som jsonBody, eller en URL via fileUrl for store filer. Endepunktet er async og returnerer en processId. Python-, Node.js- og cURL-eksempler nedenfor.

Les mer
På denne siden

Illustrasjon · eksempeldata

Eksempel på synkronisering

Se gjennom én oppføring

Kilde

CSV

Koblingsstatus: Eget verktøy

Mål

Brevo

Koblingsstatus: Aktiv

KildefeltMålfeltEksempelverdi
EMAIL EMAIL [email protected]
FIRSTNAME FIRSTNAME Alex
LASTNAME LASTNAME Example
  1. Utkast
  2. Se gjennom én oppføring
  3. Godkjenn denne versjonen

Status gjelder hver enkelt kobling og garanterer ikke at denne synkroniseringen er klar. Feltene er illustrative. Kontroller faktisk skjema og tillatelser før synkroniseringen kjører.

Hvis du noen gang har trengt å sende noen tusen kontakter fra et regneark inn i Brevo, blir den manuelle UI-veien fort slitsom: velg filen, mapp kolonner, velg en liste, vent, gjenta. Et skript gjør samme jobb på sekunder, og (viktigere) du kan kjøre det på nytt etter en tidsplan, etter en database-eksport, eller når CRM-en din spytter ut en fersk CSV.

Denne guiden dekker API-endepunktet Brevo gir deg for nøyaktig dette, med fullt fungerende skript i Python, Node.js, og en cURL-one-liner. Alt i denne guiden treffer POST /v3/contacts/import.

Endepunktet i et øyekast

POST https://api.brevo.com/v3/contacts/import
Content-Type: application/json
api-key: YOUR_API_KEY
{
"fileBody": "EMAIL;FIRSTNAME;LASTNAME\n[email protected];Jane;Doe",
"listIds": [42],
"updateExistingContacts": true,
"emailBlacklist": false,
"smsBlacklist": false
}

Responsen kommer raskt:

{ "processId": 78 }

Det er en 202 Accepted, Brevo har akseptert importen og prosesserer den i bakgrunnen. processId er ditt sporingshåndtak hvis du vil polle for ferdigstillelse eller sette opp en notifyUrl-webhook.

Noen ting verdt å merke seg før du skriver kode:

  • Body kan være CSV (fileBody), JSON (jsonBody), eller en ekstern URL (fileUrl). Velg én. CSV-formen bruker semikolon (;) for å skille kolonner, ikke komma, det er en vanlig felle.
  • fileBody og jsonBody er begrenset til 10 MB. Brevo anbefaler å holde seg rundt 8 MB for å være på den sikre siden. For noe større, last opp filen til S3, GCS, eller hvilken som helst HTTPS-host og send fileUrl i stedet.
  • Egendefinerte attributter som ikke finnes i kontoen din blir stille ignorert. Opprett dem i Brevos UI (eller via Attributes API) før du importerer rader som bruker dem, ellers forsvinner dataen bare.
  • updateExistingContacts er som standard true. Hvis du setter den til false, hopper Brevo over kontakter hvis e-post allerede finnes, nyttig for “legg bare til nye”-jobber.
  • emptyContactsAttributes styrer om tomme celler i CSV-en din sletter eksisterende verdier. Standard false (tomme celler ignoreres). Sett til true hvis CSV-en er sannhetskilden og du vil at blanke skal fjerne utdatert data.

Hent en API-nøkkel

Logg inn på Brevo -> Settings -> SMTP & API -> API Keys -> opprett en ny nøkkel. Den ser ut som xkeysib-.... Du sender den som api-key HTTP-header på hver forespørsel. Behandle den som et passord, den har full lese/skrive-tilgang på kontoen din.

Et rent mønster: legg den i en miljøvariabel slik at den aldri havner i kildetreet ditt.

Terminal window
export BREVO_API_KEY="xkeysib-..."

Python: les en CSV, send den til Brevo

Dette er det enklest mulige skriptet: les en lokal CSV med standardbiblioteket, send body-en rett til Brevo. Ingen tredjeparts-SDK nødvendig utover requests.

import_csv_to_brevo.py
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}")

Kjør det:

Terminal window
python import_csv_to_brevo.py contacts.csv

CSV-ens første rad er headeren. Kolonnenavn mappes til Brevo-attributter med store bokstaver, eksakt match: EMAIL, FIRSTNAME, LASTNAME, pluss eventuelle egendefinerte attributter du har definert. EMAIL er obligatorisk.

EMAIL,FIRSTNAME,LASTNAME,COMPANY,CITY
[email protected],Jane,Doe,Acme,Berlin
[email protected],John,Smith,Globex,Paris

Det er hele flyten. Skriptet returnerer innen et sekund; selve importen kjører serverside og tar fra noen sekunder til noen minutter avhengig av volum.

Excel-filer: tre brukbare veier

Brevos import-endepunkt leser ikke .xlsx direkte, så du har tre reelle alternativer avhengig av hvor jobben må leve:

  1. Kjør en VBA-makro inne i arbeidsboken, ett-klikks synkronisering fra Excel selv, ingen ekstern skript. Dette er riktig svar når filen lever på en stasjonær PC og teamet ditt vil ha en knapp på arket. Full kode i Excel-til-Brevo VBA-makroguiden.
  2. Office Scripts + Power Automate, hvis arbeidsboken ligger i OneDrive/SharePoint og du vil ha uovervåket planlagt synkronisering. Også dekket i Excel-guiden.
  3. Konverter .xlsx til CSV fra et skript, det resten av denne seksjonen dekker. Best hvis du allerede kjører Python eller Node på en server og bare trenger å hente en arbeidsbok inn én gang om dagen.

For alternativ 3, gjør pandas det til en one-liner:

# 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")

Hvis du ikke vil ha pandas som avhengighet, fungerer openpyxl alene:

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: samme jobb, offisiell SDK

Brevo publiserer @getbrevo/brevo for Node. Den håndterer auth, retries og typet forespørselsform:

import-csv-to-brevo.mjs
// 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}`);

Eller, hvis du ikke vil ha SDK-en, fungerer vanlig fetch på samme måte:

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: en one-liner for ad-hoc-importer

Når du bare vil teste endepunktet eller dytte en liten fil inn for hånd:

Terminal window
# 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 . sluker hele filen og JSON-escaper den, sparer deg fra å måtte escape newlines og quotes manuelt.

Filer større enn 10 MB: bruk fileUrl

fileBody er begrenset til 10 MB. Hvis kontakteksporten din er større, host filen på en URL Brevo kan hente og send den:

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

Alt som kan nås via en offentlig HTTPS-URL fungerer, pre-signerte S3-URL-er, GCS, din egen statiske host, til og med en GitHub raw-URL for engangsimporter. Brevo henter filen fra URL-en din, så kjører importen. Aksepterte formater: .csv, .txt, .json.

Send JSON i stedet for CSV

Hvis du allerede henter kontakter fra en database, trenger du ikke gå via CSV, send dem som JSON direkte:

body = {
"jsonBody": [
{
"email": "[email protected]",
"attributes": {
"FIRSTNAME": "Jane",
"LASTNAME": "Doe",
"COMPANY": "Acme",
},
},
{
"email": "[email protected]",
"attributes": {
"FIRSTNAME": "John",
"LASTNAME": "Smith",
"COMPANY": "Globex",
},
},
],
"listIds": [42],
}

Samme 10 MB-tak. Samme async-oppførsel.

Polling for ferdigstillelse

Importen er asynkron, processId er håndtaket ditt for å spore den. Det er et eget endepunkt for å sjekke prosess-status:

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}")

For lange jobber er det renere mønsteret notifyUrl: send en HTTPS-endepunkt Brevo POSTer til når importen er ferdig, og hopp over pollingen.

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

Vanlige feil og hvordan fikse dem

400 Bad Request uten åpenbar årsak. Nesten alltid semikolon vs komma i CSV-en. Brevos import forventer ;, ikke ,. Dobbeltsjekk fileBody etter konverteringssteget ditt.

Verdier for egendefinerte attributter forsvinner. Attributtet finnes ikke i kontoen din. Opprett det under Contacts -> Settings -> Contact attributes før import, eller bruk Attributes API-et for å opprette det som del av skriptet ditt.

401 Unauthorized. Feil header-navn. Det er api-key (små bokstaver, bindestrek), ikke Authorization eller X-API-Key.

Importen “lyktes” men kontaktene dukket ikke opp i listen. Sjekk at listIds inneholder riktig liste. Også: hvis updateExistingContacts er false og kontaktene allerede finnes, hopper Brevo stille over dem i stedet for å legge dem til på listen igjen.

Noen rader importerte, noen ikke. Brevo sender deg en e-post med en feilrapport per rad etter at importen er ferdig (med mindre du setter disableNotification: true). Rapporten forteller deg hvilke rader som hadde dårlige e-poster, manglende påkrevde felt eller formateringsproblemer.

Når skal du skrive skript vs bruke UI

UI-et fungerer fint for engangsimporter under tusen rader. Et skript vinner så snart:

  • Du importerer mer enn én gang (f.eks. ukentlig eksport fra CRM-en din)
  • Kildedataen trenger rensing før den lander i Brevo (deduplisering, formatering av telefonnumre, splitte fulle navn til fornavn/etternavn)
  • Du vil at den skal kjøre etter en tidsplan uten at noen klikker knapper
  • Filen er større enn UI-ets komfortsone

Pakk skriptet over i en cron-jobb eller en GitHub Action og du har automatisert kontaktsynkronisering. Neste innlegg i denne serien viser hvordan du gjør det samme rett fra et Google Sheet med Apps Script, ingen server nødvendig.

Videre lesning

Ofte Stilte Spørsmål

Hva er Brevos API-endepunkt for bulk-import av kontakter?

POST https://api.brevo.com/v3/contacts/import. Det aksepterer CSV-innhold (fileBody), en ekstern fil-URL (fileUrl), eller et JSON-array (jsonBody). Endepunktet er asynkront, det returnerer en processId umiddelbart og fullfører importen i bakgrunnen.

Hva er maksimal filstørrelse?

10 MB for inline CSV (fileBody) eller JSON (jsonBody). For større filer, host filen et sted som er tilgjengelig og send URL-en via fileUrl i stedet, den banen har ingen dokumentert størrelsesbegrensning.

Hvordan importerer jeg en .xlsx-fil?

Brevos import-API tar bare .csv, .txt eller .json. Konverter .xlsx til .csv først, pandas, openpyxl, eller LibreOffice headless kan gjøre det på én linje. Skriptet i denne guiden inkluderer en xlsx til csv-konvertering.

Vil det overskrive eksisterende kontakter?

Som standard, ja, updateExistingContacts er som standard true og matcher på e-post. Sett den til false for å hoppe over kontakter som allerede finnes. Sett emptyContactsAttributes til true hvis du vil at tomme CSV-celler skal slette eksisterende verdier (ellers ignoreres tomme celler).

Be om tidlig tilgang

Skriv inn fornavn og e-postadresse. Vi sender deg en lenke for å bekrefte forespørselen om tilgang til Tajo.

Skaff Brevo

Denne siden som Markdown: import-csv-contacts-to-brevo-with-a-script.md

Laster inn Markdown …
Åpne i Claude Åpne i ChatGPT