ガイド · SendGrid API
プロダクトチームはSendGrid APIをどう安全に実装すべきですか?
SendGrid APIは、サーバー側のメールサービスの背後で、認証済みの送信ドメインと、Mail Sendの権限だけに限定したAPIキーを使って実装します。`POST /v3/mail/send`を呼び出す前にすべてのメッセージを検証し、自社の送信記録を保存し、レスポンスの`X-Message-ID`を取得してください。署名付きのEvent Webhookのペイロードは生のバイト列から処理し、イベントの重複を排除し、バウンス、迷惑メール報告、配信停止を尊重します。`202 Accepted`、受信サーバーへの配信、受信トレイへの到達はそれぞれ別の状態として扱い、上限付きの再試行は一時的な失敗に限って行ってください。
範囲を絞った正当な送信ジョブを定義する
SendGridのv3 Mail Send APIは送信メール用のプロバイダーのエンドポイントであり、汎用のユーザーメールボックスではありません。信頼できるアプリケーションサービスやキューのワーカーの背後に置き、アカウントの確認、領収書、セキュリティ通知、要求された通知など、どのプロダクトイベントがメッセージを作成できるかを定義してください。プロバイダーのキーをブラウザ、モバイルクライアント、テンプレート、プロンプト、ログに公開してはいけません。受信者の期待、配信設定の扱い、レピュテーションを独立して運用できるよう、トランザクションメッセージと同意に基づくキャンペーンはデータモデルのレベルで分けておきます。実装の前に、送信ドメインの所有者、テンプレートの承認者、外部に送信できる環境、開発環境で許可される受信者を決めておきましょう。この範囲が、APIキーの権限、ドメインの設定、監査記録、アラート、インシデント対応の境界になります。また、プロダクトのコードがアプリケーション全体で任意のSendGridリクエストを組み立てるのではなく、承認されたメール操作を要求する形になるため、プロバイダーの移行も可能になります。
専用の送信ドメインを認証する
自社で管理するドメインまたは用途別のサブドメインについてSendGridのDomain Authenticationを設定し、そのIDのために生成されたDNSレコードをそのとおりに公開して、SendGridで検証します。プロバイダーのドキュメントによると、サブドメインは認証済みの親ドメインのIDを引き継がないため、Fromアドレスで実際に使うドメインを検証してください。DNSを変更する前に既存のSPFとDMARCのレコードを確認しましょう。同じホスト名に2つ目のSPFポリシーを作成したり、組織の既存のDMARCポリシーを所有者の了承なく置き換えたりしてはいけません。対象者やリスクが異なる場合は、トランザクションのトラフィックとプロモーションのトラフィックに、意図的に選んだ別々のIDを使います。受信したテストメッセージで、表示上のFromアドレス、リターンパス、DKIMの署名ドメイン、返信経路、リンクブランディングの挙動を確認してください。認証によって確立されるのは許可されたIDとアライメントのシグナルであり、受信システムが最終的にどのフォルダに振り分けるかを決めるものではありません。DNSの検証が成功した後も、バウンス、苦情、受信者の期待、コンテンツの監視を続けてください。
環境ごとに最小権限のAPIキーを発行する
ワークロードに必要な権限だけを持つCustom AccessのAPIキーを作成します。送信用のワーカーであれば、通常はMail Sendのアクセス権だけです。日常的な送信処理に、テンプレート、サプレッション、チームメイト、統計、IPの設定、アカウント管理へのFull Accessを与えてはいけません。開発、ステージング、本番で別々のキーを使い、所有するサービスとローテーションの目的がわかる名前を付けてください。SendGridは新しいキーを一度しか表示しないため、そのまま環境のシークレットマネージャーに登録し、ソース管理や共有ドキュメントには決してコピーしないでください。実行時は秘密情報に基づく設定から読み込み、HTTPS経由の`Authorization: Bearer`ヘッダーでのみ渡します。キーのローテーションは運用手順としてテストしましょう。同等の狭い権限を持つ代替キーを作成し、デプロイし、管理されたトラフィックが成功することを確認してから、古いキーを失効させます。予期しない401や403のレスポンスは、キーの欠落、認証情報の失効、権限の不一致、安全でない設定変更を示している可能性があるため、アラートを設定してください。
Mail Sendリクエストを組み立てて記録する
SendGridに接続する前に、内部の送信レコードを1つ作成します。このレコードには、安定したアプリケーションのイベントキー、テナント、送信者ID、承認された受信者、メッセージの種類、テンプレートのバージョン、状態を持たせます。プロバイダーのペイロードは、このレコードから`personalizations`、`from`、`subject`、そして対応するコンテンツパートを少なくとも1つ、または承認済みのダイナミックテンプレートを使って組み立ててください。ネットワーク呼び出しの前に、アドレスの構文、受信者数、添付ファイルのサイズ、テンプレートのデータ、カスタムヘッダーを検証します。SendGridの現行のMail Sendの概要では、添付ファイルを含むリクエスト全体のサイズは30 MB未満、To、Cc、Bccを合わせた受信者の合計は1,000人以下に制限されています。用途を絞った小さなリクエストのほうが、監査も復旧も容易です。`202 Accepted`のレスポンスを受け取ったら、`X-Message-ID`ヘッダーを取得して送信レコードに紐付けます。カテゴリやユニーク引数に個人データを入れてはいけません。SendGridは、これらの値がメッセージのコンテンツに期待される保護の外で保持・閲覧される可能性があると警告しています。
Event Webhookを検証して処理する
SendGridのEvent Webhookは、生のリクエストボディを保持できるHTTPSエンドポイントに設定します。暗号署名、OAuth 2.0、またはその両方を有効にしてください。署名付きの配信では、JSONをパースする前に、正確な生のバイト列に対してタイムスタンプと`X-Twilio-Email-Event-Webhook-Signature`を検証します。Twilioは、ペイロードを再シリアライズするとバイト列が変わり、検証が無効になる可能性があると警告しています。認証されていない入力は拒否し、妥当なリクエストサイズの上限を適用し、チームが選んだタイムスタンプのポリシーに従ってリプレイを防いでください。検証後、成功を返す前にイベントのバッチをキューに入れるか永続的に保存します。`sg_event_id`で重複を排除し、`sg_message_id`、保存済みの`X-Message-ID`、機密性のない内部の相関値を関連付けます。遅れて届いたprocessedイベントが、後のdeliveredやバウンスの結果を上書きしないよう、状態遷移は単調にしてください。トラブルシューティングのため、プロバイダーの元のイベントはアクセスを制限したストレージに保存しますが、アドレス、応答テキスト、エンゲージメントのデータの保持は、プロダクトとポリシーが実際に必要とする範囲に最小化しましょう。
受け付け、配信、振り分けを正確にモデル化する
SendGridのHTTP `202 Accepted`は、リクエストが受け付けられ、処理のためにキューに入ったことを意味します。宛先がメッセージを受け付けたことを示すものではありません。`processed`のWebhookイベントは、SendGridがメッセージを受け付け、配信を試行できる状態であることを意味します。`delivered`イベントは、受信側のメールサーバーがメッセージを受け付けたことをSendGridが報告したもので、多くの場合SMTPの応答を伴います。それでも受信トレイへの到達は確定しません。受信システムは受け付けたメールを、受信トレイのタブ、隔離、迷惑メールフォルダ、その他の場所に振り分けることがあるからです。ストレージとユーザーインターフェースでは、要求済み、プロバイダーが受け付け、処理済み、保留、受信サーバーが受け付け、バウンス、破棄、苦情、サプレッションといった状態を分けておきましょう。エラーでないHTTPレスポンスをすべて「配信済み」と読み替えるのは避けてください。開封などのエンゲージメントのシグナルも配信の証拠ではなく、プライバシー機能の影響を受けることがあります。状態の名前が正確であれば、サポートの調査、再試行、到達率に関する判断をより安全に行えます。
再試行する前に失敗を分類する
202以外のレスポンスをすべて再試行するのではなく、プロバイダーのエラーは種類ごとに処理します。400は通常、ペイロード、送信者、テンプレートのデータ、予約済みヘッダーの修正が必要です。401は認証の問題を、403は権限の不足やアカウントのポリシーを示している可能性があり、413はメッセージサイズを小さくする必要があります。SendGridはエンドポイントごとのレート制限のヘッダーをドキュメント化しており、リフレッシュ期間の許容量を使い切ると429を返します。同期した再試行を生まないよう、リセット時刻まで待ってジッターを加えてください。5xxや転送の失敗は、指数バックオフ、有限の試行回数、運用アラートを設けて再試行します。あいまいなタイムアウトには特に注意が必要です。クライアントがレスポンスを受け取れなくても、プロバイダーはリクエストを受け付けている可能性があります。送信レコードを不明の状態で保留し、関連するイベントを探し、再送する前に意図的な突き合わせのルールを必須にしてください。プロバイダーのAPIがあっても、プロダクトレベルでの重複防止は不要になりません。既知の恒久的なバウンス、無効な受信者、配信停止、迷惑メール報告のあった宛先を、一時的なインフラのエラーとして再試行してはいけません。
サプレッションと受信者の選択を尊重する
bounce、dropped、spam report、unsubscribe、group unsubscribeの各イベントを、受信者の安全を守るためのモデルに取り込みます。SendGridは、メッセージの種類ごとにグローバルサプレッションと配信停止グループをサポートしています。プロモーションや任意のメッセージはそれぞれ正しいグループに関連付け、わかりやすい配信設定の経路を用意し、該当するサプレッションが適用される場合は送信を停止してください。サプレッションを迂回するオプションを、配信のための日常的な手法として使ってはいけません。プロダクトにとって重要なメッセージには、別途文書化された法的・運用上のポリシーが必要な場合もありますが、そのポリシーが本人のプロモーションに関する選択やプロバイダーのレピュテーション保護を黙って上書きしてはいけません。サプレッションを解除するサポートツールは、強力な認可、明示された理由、監査証跡で保護します。恒久的な配信失敗と一時的な配信失敗は分けて追跡し、手動での再有効化は次の送信の前にレビューしてください。これらの制御は受信者を守り、すでにトラフィックを拒否または辞退した宛先への繰り返しの試行を減らします。また、トランザクションメールの送信が、キャンペーンの安全でない挙動を引き継がないようにします。
本番のトラフィックの前にライフサイクル全体をテストする
まず、本番以外のSendGridキーと、管理された認証済みのサブドメインから始めます。DNSを検証してから、チームが所有する受信トレイにプレーンテキスト版とHTML版を送信します。`202`のレスポンスと`X-Message-ID`を確認し、署名付きのWebhookイベントがローカルの送信レコードと関連付けられることを検証してください。実際の顧客のアドレスを使わずに、不正なペイロード、失効したキー、権限の欠落、サイズ超過の添付ファイル、レート制限、保留、バウンス、破棄、重複イベントの経路を試します。Webhookの検証が改変されたボディを拒否すること、ハンドラーが永続的に取り込んだ後にのみ受信確認を返すことを確認しましょう。キーのローテーション、テンプレートのロールバック、サプレッションの適用、クライアントのあいまいなタイムアウトもテストします。リクエストの失敗、イベントの遅延、保留、バウンス、迷惑メール報告、Webhookの署名検証の失敗について、テナントとメッセージの識別子は含めつつ、認証情報や完全なコンテンツは含めないダッシュボードを追加してください。最後に、プランの利用権、リージョンごとの機能、クォータ、プロバイダーのポリシーはアプリケーションのコードとは無関係に変わりうるため、リリース時にSendGridの現行のドキュメントとアカウントの制限を確認しましょう。
プロバイダー固有の依存関係を比較する
チームがSendGrid固有のリクエストフィールド、テンプレート、アカウント制御、Webhook形式、サプレッション、運用責任に意図的に依存する場合は、直接のSendGrid連携が適しています。SendHQの公開ドキュメントでは、検証済みドメイン送信、メール受信、ホスト型テンプレート、配信イベント、サプレッション、Webダッシュボードを備えたワークスペース単位のメールAPIについて説明しています。移行前に、両プロバイダーのペイロード、イベント、送信者IDの管理、サプレッション、リージョン要件、保存されているプロバイダーIDを確認してください。
よくある質問
SendGridの202 Acceptedは、メールが配信されたことを意味しますか?
いいえ。SendGridがAPIリクエストを処理のために受け付けたことを意味します。受信サーバーがメッセージを受け付けたかどうかはEvent Webhookの配信イベントで確認し、受信トレイへの到達は、APIのレスポンスでは確定しない別の結果として扱ってください。
SendGridの送信用キーにはどの権限を持たせるべきですか?
ワーカーが必要とするMail Sendの機能に限定したCustom Accessのキーを使います。日常的な送信にFull Accessは避け、開発、ステージング、本番、管理、その他権限が大きく異なるワークロードごとに、シークレット管理された別々のキーを使ってください。
SendGridのEvent Webhookの署名はどう検証すべきですか?
HTTPの生のボディをそのまま保持し、Twilioの署名とタイムスタンプのヘッダーを読み取って、JSONのパースや再シリアライズの前に検証します。リプレイ対策を適用し、検証に失敗したものは拒否し、イベントのバッチを永続的に保存するかキューに入れてから受信確認を返してください。
失敗したMail Sendリクエストはすべて再試行すべきですか?
いいえ。ペイロード、認証、認可、サイズ、恒久的な受信者のエラーは、再試行するのではなく修正してください。429のレスポンスはドキュメントに記載されたリセット時刻まで待ち、一時的なネットワークの失敗や5xxは上限付きのバックオフで再試行し、あいまいなタイムアウトは再送の前に突き合わせを行います。
トランザクションメールでは、SendGridのサプレッションを迂回してもよいですか?
SendGridは迂回のための制御を提供していますが、プロダクトで日常的に使うべきではありません。メッセージの種類を分け、該当する配信停止やサプレッションを尊重し、例外的な再有効化やポリシー固有の送信判断には、文書化された認可と監査履歴を必須にしてください。
チームはSendGridとSendHQを比較する前に何を評価すべきですか?
移行を計画する前に、プロバイダーのペイロード、イベント、送信者IDの管理、サプレッション、リージョン要件、保存されているプロバイダーIDを比較してください。
出典
- Mail Send APIの概要 — Twilio SendGrid
- Mail Sendエンドポイント — Twilio SendGrid
- SendGridのAPIキー — Twilio SendGrid
- ドメイン認証を設定する — Twilio SendGrid
- Twilio SendGrid Event Webhookの概要 — Twilio SendGrid
- Event Webhookリファレンス — Twilio SendGrid
- Event Webhookのセキュリティ機能 — Twilio SendGrid
- SendGrid APIのレート制限 — Twilio SendGrid
- SendGridのサプレッション — Twilio SendGrid
- SendGrid APIが202 Acceptedを返すのにメールが送信されない場合 — Twilio Help Center
- X-Message-ID — Twilio SendGrid
- SendHQ OpenAPI仕様 — SendHQ