---
title: "スクリプトでCSVまたはExcelの連絡先をBrevoにインポートする方法（Python、Node.js、cURL）"
description: "import-contacts APIを使って、CSVやExcelファイルから連絡先を一括でBrevoにインポートします。すぐに動かせるPythonとNode.jsスクリプト、cURLワンライナー、エラー処理、10MBを超えるファイルへのヒントを含みます。"
url: https://tajo.io/jp/blog/import-csv-contacts-to-brevo-with-a-script/
markdown: https://tajo.io/jp/blog/import-csv-contacts-to-brevo-with-a-script.md
lang: ja-JP
author: "Set Noa"
author_url: https://tajo.io/jp/set-noa/
published: 2026-04-30
updated: 2026-05-14
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, 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, 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}
---

[データ同期](https://tajo.io/jp/blog/?category=data-sync)

# スクリプトでCSVまたはExcelの連絡先をBrevoにインポートする方法（Python、Node.js、cURL）

import-contacts APIを使って、CSVやExcelファイルから連絡先を一括でBrevoにインポートします。すぐに動かせるPythonとNode.jsスクリプト、cURLワンライナー、エラー処理、10MBを超えるファイルへのヒントを含みます。

import csv contacts to brevo

連絡先を一括インポートするためのBrevo APIエンドポイントは何ですか？

POST /v3/contacts/importを使います。CSVはfileBody（10MB以下）、JSONはjsonBody、大きなファイルの場合はfileUrl経由でURLを渡します。エンドポイントは非同期でprocessIdを返します。Python、Node.js、cURLの例は以下のとおりです。

[詳しく見る](https://tajo.io/jp/blog/import-csv-contacts-to-brevo-with-a-script/#%E3%82%A8%E3%83%B3%E3%83%89%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E6%A6%82%E8%A6%81)

| 送信元フィールド | 送信先フィールド | サンプル値 |
| --- | --- | --- |
| `EMAIL` | `EMAIL` | `alex@example.com` |
| `FIRSTNAME` | `FIRSTNAME` | `Alex` |
| `LASTNAME` | `LASTNAME` | `Example` |

スプレッドシートから数千件の連絡先をBrevoに送り込む必要があったことがあるなら、手動UIの経路がすぐに苦痛になることをご存じでしょう。ファイルを選び、列をマッピングし、リストを選び、待ち、繰り返す。スクリプトなら同じ仕事が数秒で済みます。さらに重要なのは、スケジュール実行や、データベースエクスポート後、CRMが新しいCSVを吐き出すたびに再実行できることです。

このガイドでは、まさにこの目的のためにBrevoが用意しているAPIエンドポイントを、Python、Node.js、cURLワンライナーの完全な動作スクリプトとともに取り上げます。このガイドのすべては **`POST /v3/contacts/import`** にアクセスします。

## エンドポイント概要

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

レスポンスは素早く返ります。

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

これは202 Accepted です。Brevo がインポートを受け付け、バックグラウンドで処理しています。`processId` は完了をポーリングしたり `notifyUrl` webhook を設定したりする際の追跡ハンドルです。

コードを書く前に押さえておきたい点がいくつかあります。

- **本文は CSV（`fileBody`）、JSON（`jsonBody`）、リモート URL（`fileUrl`）のいずれかにできます。** 1 つを選んでください。CSV 形式は列の区切りにカンマではなくセミコロン（`;`）を使います。よくある落とし穴です。
- **`fileBody` と `jsonBody` は 10MB が上限です。** Brevo は安全のため 8MB 程度に抑えることを推奨しています。それより大きい場合は、ファイルを S3、GCS、または任意の HTTPS ホストにアップロードして `fileUrl` を渡してください。
- **アカウントに存在しないカスタム属性は黙って無視されます。** Brevo の UI（または Attributes API）で先に作成してから、それらを使う行をインポートしてください。さもないとデータが消えます。
- **`updateExistingContacts` のデフォルトは `true` です。** `false` に設定すると、Brevo はメールアドレスがすでに存在する連絡先をスキップします。「新規追加のみ」のジョブに便利です。
- **`emptyContactsAttributes`** は CSV の空セルが既存の値を消去するかどうかを制御します。デフォルトは `false`（空セルは無視）です。CSV が信頼できる情報源で、空欄が古いデータを消去すべき場合は `true` に設定してください。

## API キーを取得する

Brevo にログインし、**Settings → SMTP & API → API Keys** で新しいキーを作成します。`xkeysib-...` のような形式です。すべてのリクエストで `api-key` HTTP ヘッダーとして渡します。アカウントに対する完全な読み書き権限を持つので、パスワードのように扱ってください。

きれいなパターンとして、ソースツリーに残らないよう環境変数に入れます。

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

## Python: CSV を読んで Brevo にプッシュ

これは可能な限りシンプルなスクリプトです。標準ライブラリでローカル CSV を読み、本文をそのまま Brevo に送ります。`requests` 以外のサードパーティ SDK は不要です。

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

実行します。

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

CSV の最初の行はヘッダーです。列名は **大文字での完全一致** で Brevo 属性にマッピングされます。`EMAIL`、`FIRSTNAME`、`LASTNAME` に加え、定義したカスタム属性が利用できます。`EMAIL` は必須です。

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

これがフロー全体です。スクリプトは 1 秒以内に戻ります。実際のインポートはサーバーサイドで実行され、ボリュームに応じて数秒から数分かかります。

## Excel ファイル: 実用的な 3 つのパス

Brevo のインポートエンドポイントは `.xlsx` を直接読まないため、作業がどこで行われるかに応じて 3 つの実用的な選択肢があります。

1. **ワークブック内で VBA マクロを実行する。** 外部スクリプトなしで、Excel 自体からワンクリック同期できます。ファイルがデスクトップにあり、チームがシート上にボタンを欲しがっている場合の正解です。完全なコードは [Excel-to-Brevo VBA マクロガイド](https://tajo.io/jp/blog/import-excel-contacts-to-brevo-with-vba-macro)にあります。
2. **Office Scripts + Power Automate。** ワークブックが OneDrive/SharePoint にあり、無人スケジュール同期を望む場合に。[Excel ガイド](https://tajo.io/jp/blog/import-excel-contacts-to-brevo-with-vba-macro)でも取り上げています。
3. **スクリプトから `.xlsx` を CSV に変換する。** このセクションの残りでカバーする内容です。すでにサーバーで Python や Node を実行しており、1 日に 1 回ワークブックを取り込むだけで良い場合に最適です。

選択肢 3 の場合、pandas を使えば 1 行で済みます。

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

依存関係に pandas を入れたくない場合は、`openpyxl` だけでも動きます。

```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: 同じ仕事、公式 SDK

Brevo は Node 用に `@getbrevo/brevo` を公開しています。認証、リトライ、型付きのリクエスト形状を扱います。

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

または、SDK を使いたくなければ、素の `fetch` で同じことができます。

```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: アドホックなインポート用ワンライナー

エンドポイントをテストしたり、小さなファイルを手動で送り込みたいだけのときに。

```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 .` はファイル全体を取り込んで JSON エスケープしてくれます。改行やクォートを手動でエスケープする手間が省けます。

## 10MB を超えるファイル: `fileUrl` を使う

`fileBody` は 10MB が上限です。連絡先ダンプがこれより大きい場合は、Brevo が取得できる URL でファイルをホストし、それを渡します。

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

公開 HTTPS URL で到達可能なものなら何でも動きます。署名付き S3 URL、GCS、自前の静的ホスト、ワンショットインポートなら GitHub の raw URL でも構いません。Brevo がその URL からファイルを取得し、インポートを実行します。受け付ける形式は `.csv`、`.txt`、`.json` です。

## CSV の代わりに JSON を送る

すでにデータベースから連絡先を引き出しているなら、CSV を経由する必要はありません。直接 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],
}
```

同じ 10MB の上限。同じ非同期の挙動。

## 完了をポーリングする

インポートは非同期です。`processId` が追跡用のハンドルになります。プロセスステータスをチェックする別のエンドポイントがあります。

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

長時間実行ジョブにはよりきれいなパターンとして `notifyUrl` があります。インポート完了時に Brevo が POST してくる HTTPS エンドポイントを渡せば、ポーリングをスキップできます。

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

## よくあるエラーと修正方法

**`400 Bad Request` で原因が明確でない。** ほとんどの場合、CSV のセミコロン対カンマです。Brevo のインポートは `,` ではなく `;` を期待します。変換ステップ後の `fileBody` を再確認してください。

**カスタム属性の値が消える。** その属性がアカウントに存在しません。**Contacts → Settings → Contact attributes** で先に作成するか、[Attributes API](https://developers.brevo.com/reference/create-attribute) を使ってスクリプトの一部として作成してください。

**`401 Unauthorized`。** ヘッダー名が間違っています。`Authorization` や `X-API-Key` ではなく `api-key`（小文字、ハイフン）です。

**インポートが「成功」したのに、連絡先がリストに表示されない。** `listIds` に正しいリストが含まれているか確認してください。また、`updateExistingContacts` が `false` で連絡先がすでに存在する場合、Brevo はリストに再追加せずに静かにスキップします。

**一部の行はインポートされ、一部はされない。** インポートが完了すると Brevo が行ごとのエラーレポートをメールで送ります（`disableNotification: true` を設定していない限り）。レポートには、悪いメールアドレス、必須フィールドの欠落、フォーマットの問題があった行が記載されます。

## スクリプト化すべきとき、UI を使うべきとき

UI は 1,000 行未満のワンショットインポートには問題ありません。次のいずれかに該当する場合、スクリプトが勝ります。

- 複数回インポートする場合（CRM からの週次エクスポートなど）
- ソースデータを Brevo に入れる前にクリーニングが必要な場合（重複排除、電話番号のフォーマット、フルネームを姓名に分割）
- 誰もボタンをクリックせずにスケジュール実行したい場合
- ファイルが UI の快適ゾーンより大きい場合

上記のスクリプトを cron ジョブや GitHub Action でラップすれば、自動連絡先同期の完成です。このシリーズの次の投稿では、Apps Script を使って Google Sheet から直接同じことを行う方法を示します。サーバー不要です。

## さらに読む

- [Brevo API: Import contacts reference](https://developers.brevo.com/reference/import-contacts)
- [Brevo API: Contact attributes](https://developers.brevo.com/reference/create-attribute)
- [メールキャンペーン用の連絡先リストを構築する](https://help.brevo.com/hc/en-us/articles/209499265)

## よくある質問

**連絡先を一括インポートするためのBrevo APIエンドポイントは何ですか？**

POST https://api.brevo.com/v3/contacts/import です。CSVコンテンツ（fileBody）、リモートファイルURL（fileUrl）、またはJSON配列（jsonBody）を受け付けます。エンドポイントは非同期で、processIdをすぐに返し、インポートはバックグラウンドで完了します。

**ファイルサイズの上限はどれくらいですか？**

インラインCSV（fileBody）またはJSON（jsonBody）で10MBです。それより大きなファイルの場合は、到達可能な場所にファイルをホストし、fileUrlでURLを渡してください。このパスにはドキュメント化されたサイズ上限はありません。

**.xlsxファイルはどうやってインポートしますか？**

BrevoのインポートAPIは.csv、.txt、.jsonのみを受け付けます。まず.xlsxを.csvに変換してください。pandas、openpyxl、またはLibreOffice headlessで1行で変換できます。このガイドのスクリプトにはxlsxからcsvへの変換が含まれています。

**既存の連絡先は上書きされますか？**

デフォルトでは上書きされます。updateExistingContactsはデフォルトでtrueで、メールアドレスでマッチングします。falseに設定すると既存の連絡先をスキップします。空のCSVセルで既存の値を消去したい場合はemptyContactsAttributesをtrueに設定してください（そうでない場合は空のセルは無視されます）。

## 関連記事

### [Apps ScriptでGoogle Sheetsの連絡先をBrevoに取り込む](https://tajo.io/jp/blog/import-google-sheet-contacts-to-brevo-apps-script/)

2026年4月30日 · 3 分読む

Google Sheets → Brevo

### [VBAマクロでExcelの連絡先をBrevoにプッシュする方法（Office Scriptsという代替案も）](https://tajo.io/jp/blog/import-excel-contacts-to-brevo-with-vba-macro/)

2026年4月30日 · 8 分読む

Microsoft Excel → Brevo

### [Brevo のデータエクスポートと移行：データを出し入れする方法](https://tajo.io/jp/blog/brevo-data-export-migration/)

2026年8月19日 · 12 分読む

8 セクション
