---
title: "Slik importerer du CSV- eller Excel-kontakter til Brevo med et skript (Python, Node.js, cURL)"
description: "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."
url: https://tajo.io/no/blog/import-csv-contacts-to-brevo-with-a-script/
markdown: https://tajo.io/no/blog/import-csv-contacts-to-brevo-with-a-script.md
lang: no-NO
author: "Set Noa"
author_url: https://tajo.io/no/set-noa/
published: 2026-04-30
updated: 2026-05-03
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, pl-PL: /pl/blog/import-csv-contacts-to-brevo-with-a-script.md, pt-BR: /pt/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}
---

[Datasynkronisering](https://tajo.io/no/blog/?category=data-sync)

# 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](https://tajo.io/no/blog/import-csv-contacts-to-brevo-with-a-script/#endepunktet-i-et-%C3%B8yekast)

| Kildefelt | Målfelt | Eksempelverdi |
| --- | --- | --- |
| `EMAIL` | `EMAIL` | `alex@example.com` |
| `FIRSTNAME` | `FIRSTNAME` | `Alex` |
| `LASTNAME` | `LASTNAME` | `Example` |

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

```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
}
```

Responsen kommer raskt:

```json
{ "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.

```bash
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`.

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

Kjør det:

```bash
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.

```csv
EMAIL,FIRSTNAME,LASTNAME,COMPANY,CITY
jane@example.com,Jane,Doe,Acme,Berlin
john@example.com,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](https://tajo.io/no/blog/import-excel-contacts-to-brevo-with-vba-macro).
2. **Office Scripts + Power Automate**, hvis arbeidsboken ligger i OneDrive/SharePoint og du vil ha uovervåket planlagt synkronisering. Også dekket i [Excel-guiden](https://tajo.io/no/blog/import-excel-contacts-to-brevo-with-vba-macro).
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:

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

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

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

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

```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}`);
```

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

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

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

```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 .` 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:

```python
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:

```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],
}
```

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:

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

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.

```python
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](https://developers.brevo.com/reference/create-attribute) 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

- [Brevo API: Import contacts-referanse](https://developers.brevo.com/reference/import-contacts)
- [Brevo API: Contact attributes](https://developers.brevo.com/reference/create-attribute)
- [Bygg kontaktlister for e-postkampanjene dine](https://help.brevo.com/hc/en-us/articles/209499265)

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

## Relaterte artikler

### [Importer kontakter fra Google Sheets til Brevo med Apps Script](https://tajo.io/no/blog/import-google-sheet-contacts-to-brevo-apps-script/)

30\. apr. 2026 · 3 min lesetid

Google Sheets → Brevo

### [Slik dytter du Excel-kontakter til Brevo med en VBA-makro (og Office Scripts-alternativet)](https://tajo.io/no/blog/import-excel-contacts-to-brevo-with-vba-macro/)

30\. apr. 2026 · 6 min lesetid

Microsoft Excel → Brevo

### [Dataeksport og migrering i Brevo: slik flytter du data inn eller ut](https://tajo.io/no/blog/brevo-data-export-migration/)

19\. aug. 2026 · 10 min lesetid

8 seksjoner
