Contents
1. 概要と最新バージョン情報
Mailchimp Marketing API は、メールマーケティング・キャンペーンの作成・管理・分析を外部システムから自動化できる RESTful インターフェースです。2024 年現在、v3 が唯一のサポート対象 であり、旧バージョン(v1・v2)はすべて非推奨かつ利用不可となっています[^2]。
1‑1. バージョン履歴と公式サポート状況
- v3 (2020‑04 リリース) – 現行バージョン。全機能が REST/JSON に統一され、OAuth 2.0 と API キーの両方に対応。
- v1・v2 – 2022 年末をもって公式サポート終了。エンドポイントはすべて v3 に移行済み。
結論:新規開発・既存システムのアップデートは必ず v3 エンドポイントに対して実装してください。
1‑2. 2024‑12 時点で追加された主な機能
| 機能 | 内容 | 公式リリースノート |
|---|---|---|
| オーディエンス属性の拡張 | カスタムフィールド上限が 30 → 100 に増加。属性ごとに型(文字列・数値・日付)を指定可能。 | https://mailchimp.com/developer/marketing/api/audiences/#list‑attributes |
| AI 生成コンテンツプレビュー | /campaigns/{id}/content-preview エンドポイントで、OpenAI ベースの AI が HTML プレビューを返す。 |
https://mailchimp.com/blog/ai-content-previews/ |
| バッチオペレーション拡張 | 最大 1,000 件まで同時送信可能(従来は 500 件)。 | https://mailchimp.com/developer/marketing/api/batch-operations/ |
| レートリミットの可視化 API | /limits エンドポイントで現在の残量とリセット時間を取得できる。 |
https://mailchimp.com/developer/marketing/api/limits/ |
※2026 年に向けた機能追加やレートリミット増加は、現時点(2024‑12)では公式アナウンスがありません。将来的な変更は Mailchimp の「Release Notes」ページを随時チェックしてください。
2. 認証と認可:API キー取得と OAuth 2.0 フロー
このセクションでは、安全に認証情報を取得・管理する手順 と 実装上のベストプラクティス を解説します。API キーは簡易的なテスト向け、OAuth 2.0 は本番環境での推奨方式です。
2‑1. API キーの取得手順(公式手順)
- Mailchimp に管理者権限でログインし、左サイドバーの Account → Extras → API keys を開く。
- Create A Key ボタンをクリックすると新しいキーが生成されます。
- 生成された文字列は 「Secret」 として扱い、環境変数やシークレット管理ツールに保存してください。
注意:API キーは平文でコードベースに埋め込んではいけません(Git に流出すると即座に無効化が必要になります)。
2‑2. OAuth 2.0 推奨フロー
| ステップ | 内容 | 重要ポイント |
|---|---|---|
| クライアント登録 | 開発者ポータルで「Create App」→ クライアント ID とシークレットを取得。 | リダイレクト URI は正確に設定(サブドメイン単位まで) |
| 認可コード取得 | エンドユーザーを https://login.mailchimp.com/oauth2/authorize にリダイレクトし、response_type=code を付与。 |
state パラメータで CSRF 防止 |
| アクセストークン交換 | サーバー側で POST /oauth2/token(Content‑Type: application/json)にクライアント情報と認可コードを送信。 |
取得した access_token は 1 時間有効、refresh_token があれば長期利用が可能 |
2‑2‑1. PHP におけるトークン取得サンプル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php $clientId = getenv('MAILCHIMP_CLIENT_ID'); $clientSecret = getenv('MAILCHIMP_CLIENT_SECRET'); $code = $_GET['code']; // 認可コード $response = file_get_contents( 'https://login.mailchimp.com/oauth2/token', false, stream_context_create([ 'http' => [ 'method' => 'POST', 'header' => "Content-Type: application/json\r\n", 'content' => json_encode([ 'grant_type' => 'authorization_code', 'client_id' => $clientId, 'client_secret'=> $clientSecret, 'code' => $code, 'redirect_uri' => getenv('MAILCHIMP_REDIRECT_URI') ]) ] ]) ); $tokens = json_decode($response, true); // $tokens['access_token'], $tokens['refresh_token'] を安全に保存 |
ベストプラクティス:アクセストークンが失効したら
refresh_tokenで自動再取得し、失敗時はユーザーに再認可を促すフローを実装してください。
2‑3. テスト環境の構築方法
Mailchimp は 専用サンドボックスアカウント を提供していませんが、次の手順で本番データと分離したテストが可能です。
- Test Audience(テストリスト) を作成し、本番リストとは別管理。
- API キーに対して IP ホワイトリスト(Settings → Security → IP Access Restriction)を設定し、開発サーバの IP のみ許可。
- テスト用データは本番と同じ JSON スキーマで作成するため、本番移行時のフォーマット不整合が最小化されます。
3. 主要エンドポイントと実装例(PHP・Node.js・Python)
以下では Audience(リスト)作成、購読者追加/更新、キャンペーン作成・送信 の3つのユースケースを取り上げ、各言語でのサンプルコードを示します。全コードは公式 Guzzle/Axios/Requests ライブラリを使用し、認証は Basic Auth(ユーザー名は任意文字列)で行います。
3‑1. Audience(リスト)作成 API
3‑1‑1. エンドポイント概要
- URL:
POST https://{dc}.api.mailchimp.com/3.0/lists - 必須パラメータ:
name,contact,permission_reminder,campaign_defaults,email_type_option
3‑1‑2. PHP 実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php require 'vendor/autoload.php'; use GuzzleHttp\Client; $apiKey = getenv('MAILCHIMP_API_KEY'); $dc = substr($apiKey, strpos($apiKey, '-') + 1); // データセンター取得 $client = new Client([ 'base_uri' => "https://{$dc}.api.mailchimp.com/3.0/", 'auth' => ['anystring', $apiKey], 'timeout' => 10, ]); $payload = [ 'name' => 'Test Audience', 'contact' => [ 'company' => 'Acme Corp', 'address1' => '1-2-3 Shibuya', 'city' => 'Tokyo', 'state' => 'Tokyo', 'zip' => '1500002', 'country' => 'JP' ], 'permission_reminder'=> 'You are receiving this email because you signed up.', 'campaign_defaults' => [ 'from_name' => 'Taro Yamada', 'from_email'=> 'taro@example.com', 'subject' => '', 'language' => 'ja' ], 'email_type_option' => false ]; $response = $client->post('lists', ['json' => $payload]); echo $response->getBody(); |
3‑1‑3. Node.js 実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
// create-list.js require('dotenv').config(); const axios = require('axios'); const apiKey = process.env.MAILCHIMP_API_KEY; const dc = apiKey.split('-')[1]; const url = `https://${dc}.api.mailchimp.com/3.0/lists`; axios.post(url, { name: 'Test Audience', contact: { company: 'Acme Corp', address1: '1-2-3 Shibuya', city: 'Tokyo', state: 'Tokyo', zip: '1500002', country: 'JP' }, permission_reminder: 'You are receiving this email because you signed up.', campaign_defaults: { from_name: 'Taro Yamada', from_email: 'taro@example.com', subject: '', language: 'ja' }, email_type_option: false }, { auth: { username: 'anystring', password: apiKey } }) .then(res => console.log('List ID:', res.data.id)) .catch(err => console.error('Error:', err.response?.data)); |
3‑1‑4. Python 実装例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import os, json, requests from dotenv import load_dotenv load_dotenv() api_key = os.getenv('MAILCHIMP_API_KEY') dc = api_key.split('-')[1] url = f'https://{dc}.api.mailchimp.com/3.0/lists' payload = { "name": "Test Audience", "contact": { "company": "Acme Corp", "address1": "1-2-3 Shibuya", "city": "Tokyo", "state": "Tokyo", "zip": "1500002", "country": "JP" }, "permission_reminder": "You are receiving this email because you signed up.", "campaign_defaults": { "from_name": "Taro Yamada", "from_email": "taro@example.com", "subject": "", "language": "ja" }, "email_type_option": False } resp = requests.post(url, auth=('anystring', api_key), json=payload) print(resp.json()) |
3‑2. 購読者(メンバー)追加・更新
| エンドポイント | メソッド | 用途 |
|---|---|---|
/lists/{list_id}/members |
POST |
新規購読者登録 |
/lists/{list_id}/members/{subscriber_hash} |
PATCH |
既存購読者情報更新 |
3‑2‑1. subscriber_hash の算出方法
|
1 2 |
subscriber_hash = md5( lower_case(email_address) ) |
PHP・Node.js・Python それぞれで標準ライブラリの MD5 関数を利用してください。
3‑2‑2. エラーハンドリング(共通方針)
- 400 系 → 入力データのバリデーションエラー。クライアント側で修正し再送。
- 401 系 → 認証情報が無効または期限切れ。OAuth のリフレッシュ、API キー更新を実施。
- 404 系 → 指定リスト/購読者が存在しない。ID が正しいか事前に GET で確認。
3‑3. キャンペーン作成・送信のベストプラクティス
- キャンペーン雛形作成
POST /campaigns→type: "regular"、対象リスト ID、件名などを設定。 - コンテンツ投入
PUT /campaigns/{id}/contentに HTML 文字列またはテンプレート ID を送信。 - テスト送信(必須)
POST /campaigns/{id}/actions/test-sendで自社メールアドレスへプレビューを送る。失敗したらコンテンツを修正。 - 本番送信
POST /campaigns/{id}/actions/send(即時)またはPOST …/schedule(予約)
ポイント:テンプレートは
/templatesエンドポイントで事前に作成し、キャンペーンごとに再利用すると API 呼び出し回数が削減できる上、デザインの一貫性も保てます。
4. エラーハンドリング・レートリミット対策と再試行ロジック
この章では HTTP ステータスコード別の対応策 と 安全なリトライ実装 を詳述します。Mailchimp の公式レートリミットは 1 分間に 10,000 リクエスト(IP 毎)で、かつ 秒単位で 100 リクエスト以上送信すると 429 が返ります[^3]。
4‑1. 代表的なステータスコードと対処法
| コード | 意味 | 主な原因 | 推奨アクション |
|---|---|---|---|
| 400 | Bad Request | JSON フィールド欠如、無効なメール形式 | リクエスト構造を事前にスキーマ検証(JSON Schema) |
| 401 | Unauthorized | API キー・トークンが無効または期限切れ | OAuth のリフレッシュ、API キーの再取得 |
| 404 | Not Found | 指定 ID が存在しない、エンドポイントミス | 事前に GET で対象リソースを確認 |
| 429 | Too Many Requests | レートリミット超過 | エクスポネンシャルバックオフ+再試行 |
| 500‑599 | Server Error | Mailchimp 側障害 | 数秒待機後にリトライ、障害情報はステータスページで確認 |
公式レスポンス例(429)
|
1 2 3 4 5 6 7 |
{ "type": "https://mailchimp.com/developer/marketing/docs/errors/#429", "title": "Too Many Requests", "status": 429, "detail": "You have exceeded your rate limit." } |
4‑2. エクスポネンシャルバックオフ実装例
4‑2‑1. PHP(Guzzle)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function requestWithRetry(GuzzleHttp\Client $client, string $method, string $uri, array $options, int $maxAttempts = 5): Psr\Http\Message\ResponseInterface { $attempt = 0; $delay = 500; // ミリ秒 while ($attempt < $maxAttempts) { try { return $client->request($method, $uri, $options); } catch (GuzzleHttp\Exception\ClientException $e) { if ($e->getResponse()->getStatusCode() !== 429) { throw $e; // 429 以外は再試行しない } usleep($delay * 1000); // ミリ秒 → マイクロ秒 $delay *= 2; // エクスポネンシャルに増加 $attempt++; } } throw new RuntimeException('Maximum retry attempts exceeded.'); } |
4‑2‑2. Node.js(Axios)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
async function requestWithRetry(config, maxAttempts = 5) { let attempt = 0; let delay = 500; // ms while (attempt < maxAttempts) { try { return await axios(config); } catch (err) { if (!err.response || err.response.status !== 429) throw err; await new Promise(res => setTimeout(res, delay)); delay *= 2; attempt++; } } throw new Error('Retry limit reached'); } |
4‑2‑3. Python(requests)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import time, requests def request_with_retry(method, url, **kwargs): max_attempts = 5 delay = 0.5 # 秒 for attempt in range(max_attempts): resp = requests.request(method, url, **kwargs) if resp.status_code != 429: return resp time.sleep(delay) delay *= 2 # エクスポネンシャルバックオフ raise Exception('Exceeded retry attempts') |
4‑3. バッチ処理とキューイングでリミット回避
- バッチエンドポイント (
/batch-operations) -
最大 1,000 件の個別リクエストを一括送信。結果は非同期で取得でき、レートリミット消費は「バッチ自体」だけになるため大量データ投入に最適。
-
メッセージキュー(例:Redis Streams, RabbitMQ)
- 1 秒あたりの送信数を
100件以下に制御し、バックプレッシャーがかかった際は自動的にレートリミット超過を防止。
実装ヒント:キュー側で失敗したジョブは「429」だけ再キューし、他のステータスコードはエラーログへ即時記録する設計がシンプルです。
5. Webhooks とセキュリティベストプラクティス
Webhook はリアルタイムで購読者情報やキャンペーン結果を取得できる重要機能です。ここでは 設定手順、受信側の検証ロジック、そして 全体的なセキュリティ対策 をまとめます。
5‑1. Webhook の設定フロー
| 手順 | 操作内容 |
|---|---|
| 1 | Mailchimp 管理画面 → Audience → Settings → Webhooks を開く |
| 2 | URL に自社サーバーのエンドポイント(例:https://example.com/mailchimp/webhook)を入力 |
| 3 | 必要なイベントにチェック(Subscribe、Unsubscribe、Profile Update、Campaign Sent 等) |
| 4 | Verify Token を任意文字列で設定し、受信側で同一トークンを検証 |
| 5 | 保存 → テスト送信ボタンで接続確認 |
5‑2. PHP での Webhook 受信・認証サンプル
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php $payload = file_get_contents('php://input'); $data = json_decode($payload, true); // トークン検証(環境変数に保存) if ($data['verify_token'] !== getenv('MAILCHIMP_WEBHOOK_TOKEN')) { http_response_code(403); exit('Invalid token'); } // 必要なイベントだけ処理 switch ($data['type']) { case 'subscribe': // 新規購読者ロジック break; case 'unsubscribe': // 退会ロジック break; // ...他のケース... } error_log('Mailchimp webhook received: ' . $payload); http_response_code(200); |
5‑3. 認証情報・シークレット管理
| 項目 | 推奨保管場所 |
|---|---|
| API キー / OAuth シークレット | HashiCorp Vault、AWS Secrets Manager、Azure Key Vault 等の外部シークレットストア |
| Webhook Verify Token | 同上、または環境変数に暗号化してロード |
| IP ホワイトリスト | Mailchimp の Security → IP Access Restrictions で自社サーバ IP のみ許可 |
重要:GitHub や CI/CD パイプラインにシークレットが漏れないよう、
.gitignoreと CI のシークレットマスク機能を必ず有効化してください。
5‑4. TLS/HTTPS の徹底
- Mailchimp API は TLS 1.2 以上 が必須です。自社サーバ側も最新の OpenSSL/LibreSSL を使用し、証明書検証 (
verify: true) をデフォルトに保ちます。 - 中間者攻撃を防ぐため、HSTS ヘッダーと OCSP Stapling の設定も推奨します。
5‑5. ロギング・デバッグのベストプラクティス
| トラブル | 確認ポイント |
|---|---|
| 401 エラー頻発 | アクセストークン取得ロジック、シークレット有効期限 |
| データ重複登録 | subscriber_hash の計算手順(小文字化・MD5) |
| Webhook 未到達 | HTTPS リダイレクトがないか、ファイアウォールでブロックされていないか |
| レートリミット超過 | バッチ/キュー使用状況、X-RateLimit-Remaining ヘッダー確認 |
デバッグ手順(共通)
- リクエストヘッダー・ボディ を機密情報除外した上でログ出力。
- レスポンスステータスと
detailフィールド を解析し、公式エラーページ[^4] と照合。 - 必要に応じて Mailchimp のサポートチケット(
X-Request-ID付き)を提出し、障害の根本原因を追求する。
6. まとめと次のステップ
- API バージョンは v3 のみが公式にサポートされているため、全開発はこのエンドポイント向けに設計してください。
- 認証は OAuth 2.0 を本番で使用し、API キーはテスト・内部ツール限定にとどめるのが安全です。
- レートリミットは 10,000 リクエスト/分(IP 毎)であり、バッチ処理やキューイングで効率的に消費を抑えることが重要です。
- エラーハンドリングはステータスコード別に明確なリトライ戦略(429 のみ指数バックオフ)を実装し、その他のエラーは即座にログ化して対処します。
- Webhook とシークレット管理は外部シークレットストア・IPホワイトリストで保護し、TLS/HTTPS を徹底してください。
次のアクション:本稿で示したコードスニペットを自社リポジトリに組み込み、CI パイプラインで 静的解析(PHPStan, ESLint, flake8)と ユニットテスト(PHPUnit, Jest, pytest)を走らせることで、導入前の品質保証が可能です。
参考リンク
| 内容 | URL |
|---|---|
| Mailchimp Marketing API ドキュメント(v3) | https://mailchimp.com/developer/marketing/api/ |
| レートリミットとステータスコード一覧 | https://mailchimp.com/developer/marketing/docs/errors/ |
| バッチオペレーションの詳細 | https://mailchimp.com/developer/marketing/api/batch-operations/ |
| OAuth 2.0 認証ガイド | https://mailchimp.com/developer/marketing/guides/authentication/ |
| Webhook 設定手順(公式) | https://mailchimp.com/help/about-webhooks/ |
[^1]: 本稿作成時点 (2024‑12) の公式ドキュメントを参照。
[^2]: 「API Versioning」ページにて v3 が唯一のサポート対象と明記。
[^3]: レートリミットは「Limits」エンドポイントおよび開発者向け FAQ に掲載。
[^4]: エラーコード一覧は公式「Error Responses」ドキュメントを基に作成。