Brevo のデータエクスポートと移行:データを出し入れする方法
Brevo からコンタクト、統計、ログをエクスポートする方法、何が移行できないのかを正確に把握し、どちらの方向にも使える手順チェックリストを解説します。
「brevo data export migration to another platform」のような検索が伸びる理由は 1 つの不安に集約されます。積み上げてきたデータは、入れるのは簡単でも出すのは難しいのではないか、という不安です。Brevo についての正直な答えは、大半はきれいに取り出せる、一部は組み直しが必要な形でしか出てこない、そして少数ながら重要な部分はまったく動かせない、というものです。
このガイドは両方向を扱います。何がエクスポートでき何ができないのか、画面操作では手に負えない規模のアカウント向けの API 呼び出し、そして配信抑止リストと送信レピュテーションを後回しではなく最重要事項として扱う移行チェックリストを示します。
Brevo から実際にエクスポートできるもの
| データ | 取り出し方 | 形式 |
|---|---|---|
| コンタクトと属性 | Contacts ページのエクスポート、または POST /v3/contacts/export | CSV |
| リストの所属 | リストごとのエクスポート、または _listIds メタデータフィールド | CSV |
| 購読ステータス | エクスポートジョブの exportSubscriptionStatus | CSV |
| キャンペーン統計 | キャンペーンレポートのエクスポート、または GET /v3/emailCampaigns | CSV、PDF、JSON |
| トランザクションのイベントログ | GET /v3/smtp/statistics/events または一括エクスポートジョブ | JSON、CSV |
| テンプレート | GET /v3/smtp/templates が htmlContent を返す | JSON |
| 会社と取引 | 該当する CRM ページからエクスポート | CSV |
コンタクトと属性
画面上の経路は CRM から Contacts です。データベース全体をエクスポートするなら、リストもセグメントも読み込まれておらず、フィルターも適用されていない状態にします。特定のリストやセグメントをエクスポートするなら、先に「Load a list or segment」をクリックして選びます。
続いて、標準属性とカスタム属性のどれを含めるかを選びます。既定では EMAIL、最終更新日、作成日が選択されており、残りは自分で追加します。ここが最も間違えやすい手順です。CSV のフィールド区切り文字としてセミコロンかカンマを選び、必要に応じて「Send export by email」を有効にすると、アカウント所有者のアドレスにダウンロードリンクが届きます。「Start export」をクリックし、アカウント名の横にある通知のベルからファイルをダウンロードしてください。
リストとセグメント
リストは所属としてエクスポートされます。リストごとに 1 回ずつエクスポートを実行するか、全件エクスポートに _listIds メタデータを含めて後からファイルを分割します。GET /v3/contacts/lists はリスト名、ID、フォルダー ID を返すので、移行先で構造を再現できます。
セグメントは事情が違い、ここが最初の本当のギャップです。GET /v3/contacts/segments が返すのは id、segmentName、categoryName、updatedAt だけです。セグメントを定義するフィルター条件は公開されていません。ある時点でのセグメントのメンバーはエクスポートできますが、それを生み出したルールは画面から読み取り、新しいツールで手作業で組み直すしかありません。アカウントを解約する前に、すべてのセグメントをスクリーンショットで残しておきましょう。
キャンペーン統計
キャンペーンレポートからはデータを CSV でエクスポートでき、メールと SMS のレポートには共有や印刷用の PDF 版もあります。過去分をまとめて取得するなら、GET /v3/emailCampaigns が statistics パラメーター(globalStats、linksStats、statsByDomain)と、最大 2 年の範囲を指定できる startDate と endDate の組を受け付けます。
トランザクションのログ
経路は 2 つあり、それぞれ取得できる期間が異なります。
GET /v3/smtp/statistics/events は、種別(delivered、opened、clicks、hardBounces、spam、unsubscribed など)で絞り込んだ個別のイベントを返します。日付範囲は 90 日を超えられず、範囲も days パラメーターも渡さない場合は直近 30 日が既定になります。
一括取得には POST /v3/webhooks/export を使い、直近 7 日ぶんの生イベントに対するエクスポートジョブを作成します。7 日間あたり 20 ジョブが上限です。processId を返し、完了時に通知 URL を呼び出して CSV を届けます。列には date、email、event、message-id、reason、sending_ip、subject、tag、template_id などが含まれます。量が多い場合は、複数の CSV ファイルをまとめた圧縮アーカイブで届きます。
実務上の帰結はこうです。90 日を超えるトランザクションの履歴が欲しいなら、それは最初から定期的にエクスポートしておくべきものでした。離脱を決めた週ではなく、今すぐそのジョブを組んでください。
一緒には持ち出せないもの
多くの移行ガイドが飛ばすのがこの部分です。
- オートメーションのワークフロー構造。 API はイベント経由でオートメーションを起動できますが、ワークフローの分岐、待機、条件を読み戻す文書化されたエンドポイントはありません。すべてのワークフローは移行先で手作業で組み直します。
- セグメントのフィルター定義。 前述のとおり、取得できるのは名称と現在のメンバーだけです。
- コンタクト単位の完全なエンゲージメント履歴。 エクスポートエンドポイントの
customContactFilterを使えば、特定キャンペーンの開封者、クリック者、未開封者、配信停止者、ハードバウンス、ソフトバウンスは抽出できます。取り出せないのは「このコンタクトのこれまでのすべての開封とクリック」を 1 つのきれいなファイルにしたものです。生のイベントエンドポイントが 90 日に区切られているからです。 - テンプレートの再現性。
htmlContentはきれいにエクスポートできますが、ドラッグアンドドロップのブロック、差し込みタグの記法、配信停止リンクのプレースホルダーはプラットフォーム固有です。エクスポートした HTML は出発点であって完成品ではありません。移行先のエディターで全テンプレートを検証し直す時間を見込んでください。 - 到達性のレピュテーション。 送信者レピュテーションは送信 IP と認証済みドメインに宿ります。プラットフォームが変われば IP プールも変わり、ウォームアップもやり直しです。同じドメインと DKIM 設定を保てばドメイン側のレピュテーションは維持でき、実際に効果もありますが、IP 側は引き継げません。
- フォーム、ランディングページ、トラッキングの識別子。 登録フォーム、ランディングページ、トラッキングスクリプトはいずれもプラットフォーム固有の ID を持ちます。サイトに埋め込んだものはすべて差し替えが必要で、それらの ID に紐づいた解析は切り替え時に途切れます。
大規模アカウント向けのスクリプトによるエクスポート
コンタクトが 10 万件を超えるあたりから、画面上のエクスポートは遅く扱いにくくなります。そもそも繰り返し実行できるジョブがほしくなるはずです。コンタクトのエクスポートエンドポイントは非同期で、フィルターを受け取り、プロセス ID を返し、完了時に CSV を渡します。
curl --request POST \ --url https://api.brevo.com/v3/contacts/export \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --header 'api-key: YOUR_API_KEY' \ --data '{ "customContactFilter": { "actionForContacts": "allContacts" }, "exportMandatoryAttributes": true, "exportAttributes": ["FIRSTNAME", "LASTNAME", "SMS", "COUNTRY"], "exportMetadata": ["_listIds", "ADDED_TIME", "MODIFIED_TIME"], "exportSubscriptionStatus": ["email_marketing", "sms_marketing"], "exportDateInUTC": true, "notifyUrl": "https://example.com/hooks/brevo-export" }'呼び出しが成功すると HTTP 202 と、processId を含むボディが返ります。exportMandatoryAttributes は既定で true で、EMAIL、ADDED_TIME、MODIFIED_TIME を含みます。したがって exportAttributes はカスタムフィールドを指定する場所です。exportSubscriptionStatus を設定して初めて、メールと SMS のマーケティングにおけるオプトイン状態がファイルに入ります。これを省くことが、法令に適合した移行に使えないエクスポートを作ってしまう最も多い原因です。
ジョブの完了を待つよりレコードをページングしたい場合は、GET /v3/contacts が limit を最大 1000 まで受け付け、offset に加えて差分取得用の modifiedSince と createdSince にも対応します。各コンタクトには emailBlacklisted、smsBlacklisted、listIds、listUnsubscribed、consentGroups が付いて返るので、同意の状態を再構成するのに必要なものはすべてそろいます。
スクリプトを書くときはレート制限に注意してください。コンタクト系のエンドポイントは標準プランで 1 時間あたり 36,000 リクエスト、毎秒 10 リクエストまで、Professional と Enterprise ではその倍です。一方で他の大半のエンドポイントは 1 時間あたり 100 リクエストです。100 万件を 1 ページ 1000 件で回すと 1000 リクエストで、コンタクトの枠には十分収まりますが、キャンペーンやテンプレートのエンドポイントをループで叩くのは収まりません。
配信抑止リストを最初に移行すべき理由
何よりも先にオプトアウトを移してください。
法的な理屈は単純です。配信停止したコンタクトは、あなたのブランドに対して同意を撤回しました。ベンダーを変えたからといって、その撤回がリセットされることはありません。GDPR のもとでは、同意とその撤回の記録は管理者としてのあなたの義務です。CAN-SPAM のもとでは、オプトアウトは 10 営業日以内に反映し、以後は無期限で維持しなければなりません。移行でリストを失うのは技術的な事故ではなく、あなたを指し示す証跡が残るコンプライアンス違反です。
実務上は、到達性の面のほうがさらに深刻です。配信抑止されたアドレスには、苦情を出した人、ハードバウンスした人、はっきり離脱を望んだ人が偏って含まれます。レピュテーションのまっさらな新しい IP からそこへ送ることは、新設の送信環境を初週でスロットリングやブロックに追い込む最短の方法として知られています。数千件のスパムトラップと苦情経験者が、1 か月かけた慎重なウォームアップを台無しにします。
ですから、暗黙に含まれていることを期待せず、配信抑止された集団を明示的にエクスポートしてください。エクスポートエンドポイントの actionForContacts は、何らかの理由でブロックリスト入りしたコンタクトに unsubscribed、特定のリストからオプトアウトしたコンタクトに unsubscribedPerList を受け付けます。キャンペーンごとの hardBounces も別途取得しましょう。新しいプラットフォームへ取り込むときは、そのファイルを配信可能なリストではなく配信抑止リストへインポートします。
Brevo は逆方向にも対応しています。ブロックリスト済みコンタクトの一覧のインポートに対応し、インポート API は emailBlacklist と smsBlacklist の真偽値を受け取るので、取り込んだファイルは配信抑止として着地します。ここで Brevo が正しく設けている非対称性に注目してください。コンタクトを一括でブロックリストから外すことはできません。放っておいてほしいと言った人を一括で再購読させるのは違法だからです。配信抑止は追加が容易で、意図的に解除が難しく作られています。これは障害ではなく、正しい挙動として受け止めましょう。
移行チェックリスト:Brevo から出る場合
- 棚卸し。 コンタクト、リスト、セグメント、稼働中のオートメーション、テンプレート、連携の数を数えます。どの連携が Brevo に書き込んでいるかを書き出してください。それらが向き先を変えることになる配管です。
- エクスポート。 全属性と購読ステータスを含むコンタクト、リストごとのファイルまたは
_listIdsを持つ 1 つのファイル、配信抑止の集団を別ファイルとして、キャンペーン統計、90 日の枠が許すかぎり遡ったトランザクションイベント、そしてテンプレートの HTML。 - 期限のあるものを保管する。 期間が区切られているもの(生イベント、ログ)は、枠が過ぎれば失われます。今のうちに自社のデータウェアハウスやオブジェクトストレージへ保存してください。
- 整形と対応づけ。 重複を除き、日付と電話番号の書式をそろえ、移行先向けに列とフィールドの明示的な対応表を書きます。ここは、1 年間まったく反応のないアドレスを落とす自然なタイミングでもあります。死んだ重量をウォームアップするために費用を払うより安上がりです。しきい値はメールリストのクリーニングガイドで扱っています。
- 配信抑止を先に投入する。 オプトアウトとハードバウンスを移行先の配信抑止リストへ取り込み、件数がエクスポートと一致することを確認してから、配信可能なコンタクトを読み込みます。
- ウォームアップ。 最も反応の良いセグメントから始め、量を段階的に増やし、バウンス率と苦情率を毎日確認します。手順の詳細はメール到達性ガイドにあります。
- 並行稼働。 重要なトランザクションメールは Brevo から送り続けたまま、マーケティング送信の比率を移行先で徐々に増やします。両方を一度に切り替えてはいけません。
- 検証。 コンタクト数を突き合わせ、20 件ほどをフィールド単位で抜き取り確認し、テスト送信を試みて配信抑止が実際に効いていることを確かめ、1 週間の送信量を旧プラットフォームと比較します。
- 切り替えと切り戻しの用意。 DNS と連携先のエンドポイントは、誰かが見ている時間帯に変更します。切り替え後も少なくとも 1 請求サイクルは Brevo のアカウントを有効かつ支払い済みのまま維持し、エクスポートしたファイルは両方のプラットフォームの外に保管してください。ベンダーの約束ではなく、それが実際の切り戻し計画です。
他のプラットフォームから Brevo へ移行する
同じチェックリストを逆向きに走らせますが、Brevo 固有の注意が 3 つあります。
現行ベンダーから本物のエクスポートを受け取る。 大半のプラットフォームは、コンタクトとカスタムフィールドを CSV で渡してくれます。配信抑止リストとバウンスリストは明示的に依頼してください。別のエクスポートになっていて、依頼を忘れられがちです。コンタクト課金のモデルから移ってくるなら、移行後に実際にいくら払うことになるかをBrevo 料金ガイドと照らして比べましょう。
アップロード前にフィールドを対応づける。 Brevo の属性には型(テキスト、数値、日付、真偽値、カテゴリ)があり、日付がテキスト属性に入ると後で絞り込めません。正しい型で属性を先に作り、それからインポートします。
規模のあるものは API 経由でインポートする。 POST /v3/contacts/import は fileBody にインラインの CSV、jsonBody に JSON 配列(いずれも上限は 10 MB 前後)、fileUrl にリモートファイルを受け取り、listIds または newList オブジェクトを指定できます。updateExistingContacts は既定で true で、メールアドレスで突き合わせます。配信抑止ファイルは emailBlacklist を true にして 1 回目のインポートを実行し、配信可能なコンタクトは 2 回目のインポートで取り込みます。実際に動くスクリプト一式は、スクリプトで CSV のコンタクトを Brevo にインポートする方法のガイドにあります。
そのうえで、移行できなかったものを組み直します。オートメーション、セグメント、フォーム、テンプレートです。実在の相手に送る前に、複数のメールプロバイダーへシードテストを送っておきましょう。
次の移行を崖にしないために
プラットフォームの移行が崖のように感じられるのは、そのプラットフォームが記録の正本になっているからです。注文履歴、購読者の状態、キャンペーンの結果が 1 つのベンダーの内側にあり、動かすことが避難作業になってしまいます。
代わりの姿は、自分の側に正本を持ち、送信プラットフォームを金庫ではなく届け先として扱うことです。ストアのデータ、同意の状態、エンゲージメントのイベントが自社システムへ継続的に同期されていれば、チャネルの切り替えや追加はプロジェクトではなく設定変更になります。それが Tajo が Brevo と事業者のスタックの間で担う仕事です。データを双方向に流し続け、プラットフォームが唯一の写しになる状態を避けます。
いずれにせよ、上で説明したエクスポートのジョブは、離れる予定があるかどうかにかかわらず、今すぐ定期実行する価値があります。最も安く済む移行とは、決断した時点ですでにデータがプラットフォームの外にある移行です。