---
title: "Så importerar du CSV- eller Excel-kontakter till Brevo med ett skript (Python, Node.js, cURL)"
description: "Massimportera kontakter från en CSV- eller Excel-fil till Brevo med API:t import-contacts. Innehåller färdiga skript i Python och Node.js, en cURL-rad, felhantering och tips för filer större än 10 MB."
url: https://tajo.io/se/blog/import-csv-contacts-to-brevo-with-a-script/
markdown: https://tajo.io/se/blog/import-csv-contacts-to-brevo-with-a-script.md
lang: sv-SE
author: "Set Noa"
author_url: https://tajo.io/se/set-noa/
published: 2026-04-30
updated: 2026-05-05
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, 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, 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/se/blog/?category=data-sync)

# Så importerar du CSV- eller Excel-kontakter till Brevo med ett skript (Python, Node.js, cURL)

Massimportera kontakter från en CSV- eller Excel-fil till Brevo med API:t import-contacts. Innehåller färdiga skript i Python och Node.js, en cURL-rad, felhantering och tips för filer större än 10 MB.

import csv contacts to brevo

Vilken är Brevos API-endpoint för massimport av kontakter?

Använd POST /v3/contacts/import. Skicka CSV som fileBody (≤10 MB), JSON som jsonBody eller en URL via fileUrl för stora filer. Endpointen är asynkron och returnerar ett processId. Exempel i Python, Node.js och cURL nedan.

[Läs mer](https://tajo.io/se/blog/import-csv-contacts-to-brevo-with-a-script/#endpointen-i-korthet)

| Källfält | Målfält | Exempelvärde |
| --- | --- | --- |
| `EMAIL` | `EMAIL` | `alex@example.com` |
| `FIRSTNAME` | `FIRSTNAME` | `Alex` |
| `LASTNAME` | `LASTNAME` | `Example` |

Om du någon gång har behövt skicka in några tusen kontakter från ett kalkylblad till Brevo så vet du att den manuella vägen i gränssnittet snabbt blir jobbig: välj fil, mappa kolumner, välj lista, vänta, upprepa. Ett skript gör samma jobb på några sekunder och, viktigare, du kan köra det igen enligt schema, efter en databasexport eller varje gång ditt CRM spottar ut en ny CSV.

Den här guiden går igenom API-endpointen Brevo erbjuder för exakt det här, med kompletta skript i Python, Node.js och en cURL-rad. Allt i guiden går mot **`POST /v3/contacts/import`**.

## Endpointen i korthet

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

Svaret kommer snabbt:

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

Det är ett 202 Accepted. Brevo har tagit emot importen och bearbetar den i bakgrunden. `processId` är ditt spårnings-id om du vill polla efter färdigställning eller sätta upp en `notifyUrl`-webhook.

Några saker värda att veta innan du börjar koda:

- **Body kan vara CSV (`fileBody`), JSON (`jsonBody`) eller en extern URL (`fileUrl`).** Välj en. CSV-formen använder semikolon (`;`) som kolumnavskiljare, inte komma. Det är en vanlig fallgrop.
- **`fileBody` och `jsonBody` är begränsade till 10 MB.** Brevo rekommenderar att du håller dig runt 8 MB för säkerhets skull. För något större laddar du upp filen till S3, GCS eller valfri HTTPS-host och skickar `fileUrl` i stället.
- **Anpassade attribut som inte finns på ditt konto ignoreras tyst.** Skapa dem i Brevos gränssnitt (eller via Attributes API) innan du importerar rader som använder dem, annars försvinner data bara.
- **`updateExistingContacts` har true som standard.** Om du sätter det till `false` hoppar Brevo över kontakter vars e-post redan finns, användbart för jobb som “lägg bara till nya”.
- **`emptyContactsAttributes`** styr om tomma celler i din CSV ska radera befintliga värden. Standard `false` (tomma celler ignoreras). Sätt till `true` om din CSV är källan till sanning och du vill att tomma värden ska rensa bort gammal data.

## Skaffa en API-nyckel

Logga in på Brevo, gå till **Settings → SMTP & API → API Keys** och skapa en ny nyckel. Den ser ut som `xkeysib-...`. Du skickar den som HTTP-headern `api-key` i varje anrop. Behandla den som ett lösenord, den har full läs- och skrivåtkomst på ditt konto.

Ett rent mönster: lägg den i en miljövariabel så att den aldrig hamnar i ditt källträd.

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

## Python: läs en CSV och skicka den till Brevo

Det här är det enklaste tänkbara skriptet: läs en lokal CSV med standardbiblioteket och skicka body direkt till Brevo. Inget tredjeparts-SDK behövs utöver `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}")
```

Kör det:

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

Första raden i din CSV är rubriken. Kolumnnamn mappas till Brevo-attribut via **versaler, exakt matchning**: `EMAIL`, `FIRSTNAME`, `LASTNAME`, plus eventuella anpassade attribut du har definierat. `EMAIL` är obligatoriskt.

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

Det är hela flödet. Skriptet returnerar inom en sekund. Själva importen körs på serversidan och tar allt från några sekunder till några minuter beroende på volym.

## Excel-filer: tre rimliga vägar

Brevos import-endpoint läser inte `.xlsx` direkt, så du har tre verkliga alternativ beroende på var arbetet behöver bo:

1. **Kör ett VBA-makro inuti arbetsboken.** Ett-klicks-synk från Excel självt, inget externt skript. Det är rätt svar när filen ligger på en dator och ditt team vill ha en knapp på arket. Komplett kod i [guiden för Excel-till-Brevo VBA-makro](https://tajo.io/se/blog/import-excel-contacts-to-brevo-with-vba-macro).
2. **Office Scripts + Power Automate.** Om arbetsboken ligger i OneDrive/SharePoint och du vill ha schemalagd synk utan tillsyn. Tas också upp i [Excel-guiden](https://tajo.io/se/blog/import-excel-contacts-to-brevo-with-vba-macro).
3. **Konvertera `.xlsx` till CSV från ett skript.** Det här är vad resten av avsnittet handlar om. Bäst om du redan kör Python eller Node på en server och bara behöver dra in en arbetsbok en gång om dagen.

För alternativ 3 räcker pandas en rad:

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

Om du inte vill ha pandas som beroende fungerar `openpyxl` ensamt:

```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: samma jobb, officiellt SDK

Brevo publicerar `@getbrevo/brevo` för Node. Det hanterar autentisering, retries och den typade request-formen:

```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, om du inte vill ha SDK:t, vanlig `fetch` fungerar likadant:

```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 rad för ad hoc-importer

När du bara vill testa endpointen eller skicka in en liten fil för hand:

```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 .` slurpar hela filen och JSON-escapar den, så slipper du escapa radbrytningar och citattecken manuellt.

## Filer större än 10 MB: använd `fileUrl`

`fileBody` är begränsad till 10 MB. Om din kontaktdump är större hostar du filen på en URL Brevo kan hämta och skickar den:

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

Allt som är åtkomligt via en publik HTTPS-URL fungerar: pre-signerade S3-URL:er, GCS, din egen statiska host, även en GitHub raw-URL för enstaka importer. Brevo hämtar filen från din URL och kör sedan importen. Accepterade format: `.csv`, `.txt`, `.json`.

## Skicka JSON i stället för CSV

Om du redan hämtar kontakter från en databas behöver du inte gå vägen via CSV. Skicka dem som JSON direkt:

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

Samma 10 MB-tak. Samma asynkrona beteende.

## Polla efter färdigställning

Importen är asynkron. `processId` är ditt grepp för att följa den. Det finns en separat endpoint för att kontrollera processtatus:

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

För långkörande jobb är det renare mönstret `notifyUrl`: skicka en HTTPS-endpoint som Brevo postar till när importen är klar, och hoppa över pollningen.

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

## Vanliga fel och hur du löser dem

**`400 Bad Request` utan tydlig orsak.** Nästan alltid semikolon kontra komma i CSV:n. Brevos import förväntar sig `;`, inte `,`. Dubbelkolla `fileBody` efter ditt konverteringssteg.

**Värden för anpassade attribut försvinner.** Attributet finns inte på ditt konto. Skapa det under **Contacts → Settings → Contact attributes** innan import, eller använd [Attributes API](https://developers.brevo.com/reference/create-attribute) för att skapa det som en del av ditt skript.

**`401 Unauthorized`.** Fel headernamn. Det är `api-key` (gemener, bindestreck), inte `Authorization` eller `X-API-Key`.

**Importen “lyckades” men kontakterna dök inte upp i listan.** Kontrollera att `listIds` innehåller rätt lista. Och: om `updateExistingContacts` är `false` och kontakterna redan finns hoppar Brevo tyst över dem i stället för att lägga till dem i listan.

**Vissa rader importerades, andra inte.** Brevo mejlar dig en felrapport per rad efter att importen är klar (om du inte satt `disableNotification: true`). Rapporten talar om vilka rader som hade ogiltiga e-postadresser, saknade obligatoriska fält eller formateringsfel.

## När det är värt att skripta och när gränssnittet räcker

Gränssnittet duger för enstaka importer under tusen rader. Ett skript vinner så snart:

- Du importerar mer än en gång (t.ex. veckovis export från ditt CRM)
- Källdatan behöver städning innan den hamnar i Brevo (avduplicering, formatering av telefonnummer, uppdelning av fullständigt namn i för- och efternamn)
- Du vill att det ska köras enligt schema utan att någon klickar
- Filen är större än vad gränssnittet trivs med

Slå in skriptet ovan i ett cron-jobb eller en GitHub Action så har du automatiserad kontaktsynk. Nästa inlägg i serien visar hur du gör samma sak direkt från ett Google Sheet med Apps Script, ingen server krävs.

## Vidare läsning

- [Brevo API: Import contacts reference](https://developers.brevo.com/reference/import-contacts)
- [Brevo API: Contact attributes](https://developers.brevo.com/reference/create-attribute)
- [Build contact lists for your email campaigns](https://help.brevo.com/hc/en-us/articles/209499265)

## Vanliga Frågor

**Vilken är Brevos API-endpoint för massimport av kontakter?**

POST https://api.brevo.com/v3/contacts/import. Den tar emot CSV-innehåll (fileBody), en URL till en extern fil (fileUrl) eller en JSON-array (jsonBody). Endpointen är asynkron: den returnerar ett processId direkt och slutför importen i bakgrunden.

**Vad är den maximala filstorleken?**

10 MB för CSV inline (fileBody) eller JSON (jsonBody). För större filer hostar du filen någonstans där den är åtkomlig och skickar dess URL via fileUrl i stället. Den vägen har ingen dokumenterad storleksgräns.

**Hur importerar jag en .xlsx-fil?**

Brevos import-API tar bara emot .csv, .txt eller .json. Konvertera först .xlsx till .csv. Pandas, openpyxl eller LibreOffice headless klarar det på en rad. Skriptet i den här guiden innehåller en konvertering från xlsx till csv.

**Skrivs befintliga kontakter över?**

Som standard, ja. updateExistingContacts har true som standardvärde och matchar på e-postadress. Sätt det till false om du vill hoppa över kontakter som redan finns. Sätt emptyContactsAttributes till true om du vill att tomma CSV-celler ska radera befintliga värden (annars ignoreras tomma celler).

## Relaterade artiklar

### [Importera kontakter från Google Sheets till Brevo med Apps Script](https://tajo.io/se/blog/import-google-sheet-contacts-to-brevo-apps-script/)

30 apr. 2026 · 3 min lästid

Google Sheets → Brevo

### [Så skickar du Excel-kontakter till Brevo med ett VBA-makro (och alternativet med Office Scripts)](https://tajo.io/se/blog/import-excel-contacts-to-brevo-with-vba-macro/)

30 apr. 2026 · 6 min lästid

Microsoft Excel → Brevo

### [Dataexport och migrering i Brevo: så flyttar du dina data in eller ut](https://tajo.io/se/blog/brevo-data-export-migration/)

19 aug. 2026 · 9 min lästid

8 avsnitt
