ガイド · ResendメールAPI
プロダクトチームはResendメールAPIをどう安全に実装すべきか
ResendメールAPIは、ブラウザやモバイルのコードではなく、信頼できるサーバーのワーカーの背後に実装してください。正確な送信ドメインを検証し、可能であればそのドメインに限定した送信専用のAPIキーを作成し、承認された送信ジョブを永続化し、`POST /emails`に安定した`Idempotency-Key`を渡します。返されたメールIDを保存し、解析する前にWebhookの署名を検証し、イベントを冪等に処理し、送信すべきでない受信者をサプレッションリストに追加します。APIによる受け付け、プロバイダーによる送信、受信サーバーへの配信、受信トレイへの到達は別々の状態として扱ってください。
プロバイダーへのリクエストの前にプロダクトの操作を定義する
アカウントの確認、領収書、セキュリティ通知、受信者が希望した通知など、範囲の狭いアプリケーションの操作から始めてください。公開されるプロダクトのエンドポイントは、Resendのペイロードを作る前に、呼び出し元、テナント、メッセージの種類、送信者ID、受信者、テンプレートを認可すべきです。再利用可能な認証情報を持ったブラウザに、任意の`from`、`to`、HTML、プロバイダーのオプションを送信させてはいけません。アプリケーションのイベントキー、テナント、テンプレートのリビジョン、承認された送信者、受信者の集合、現在の状態を含む、永続的な内部の送信記録を作成します。ワーカーはその記録をプロバイダーへのリクエストに変換できます。この境界によって、APIキーと信頼できないメッセージ内容をクライアントから遠ざけ、重複防止をテスト可能にし、すべてのビジネスワークフローを書き直すことなくプロバイダーを変更できるようになります。配信設定、サプレッション、インシデント時の判断が明示的に保たれるよう、内部モデルではトランザクションメッセージと同意が前提のメッセージを分けてください。
Fromアドレスで使う正確なドメインを検証する
自社が管理するドメインをResendに追加し、そのドメイン用に表示されるDNSレコードを公開します。無関係な親のIDでカバーされると考えるのではなく、表示上のFromアドレスで実際に使う組織のドメインまたはサブドメインを検証してください。DNSを変更する前に既存のSPFとDMARCのポリシーを確認し、同じホスト名に2つ目のSPFレコードを決して作らないでください。分離、所有権、移行の要件から正当化される場合は、用途別の送信用サブドメインを使います。ダッシュボードで検証済みと表示された後、受信したテストメッセージを調べ、表示上のFromアドレス、DKIMの署名ID、Return-Path、認証結果、返信の挙動を確認してください。プロバイダーによる検証が証明するのは、設定されたIDがプロバイダーのセットアップチェックを満たしたことです。受信者の同意、受信サーバーによる受け付け、受信トレイへの到達、良好なレピュテーションを証明するものではありません。ローテーションやロールバックができるよう、DNSの所有権と変更履歴はプロバイダーのダッシュボードの外でも保存しておきましょう。
ワークロードごとに最小権限のAPIキーを作成する
Resendのドキュメントでは、APIキーにアクセスレベルと、任意のドメイン制限を設定できるとされています。送信ワーカーは、送信アクセスに限定し、アーキテクチャが許す場合はそのワークロードが所有する1つのドメインに限定したキーを使うべきです。管理、ドメイン、Webhook、アカウントの管理は別の権限のもとに置いてください。開発、ステージング、本番で別々のキーを作成し、下位の環境が本番のIDで送信したり、その上限を消費したりできないようにします。各シークレットは管理されたシークレットストアに直接保管し、それを必要とするサーバープロセスにだけ公開し、HTTPS上でBearer認証として渡します。キーをソース管理、ビルド成果物、ログ、テンプレート、分析、チケット、プロンプトにコピーしてはいけません。ローテーションは予行演習しておきましょう。同等のスコープを持つ代替キーを作成し、ワーカーを更新し、管理下のトラフィックとイベントの関連付けを確認してから、古いキーを取り消します。予期しない認証・認可の失敗は、有効期限切れ、取り消し、スコープのずれ、シークレットの漏えいの兆候である可能性があるため、アラートを出してください。
永続的なジョブを1つ、冪等な送信試行を1つにする
Resendを呼び出す前に、内部の送信ジョブを確保します。冪等性の値は、ランダムな再試行ではなく、テナント、操作の種類、不変のアプリケーションイベントIDといった安定したプロダクト上の事実から導き出してください。その値を`Idempotency-Key`ヘッダーで送信します。Resendの現在のドキュメントによると、これらのキーはメールリクエストの重複を防ぎ、24時間で期限切れになり、最大256文字まで含められます。このプロバイダー側の期間は役立ちますが、プロダクトレベルでの重複防止を完全に保証するものではありません。より長いビジネスワークフローに備えて内部のイベントキーに一意制約を設け、同じジョブを取得しうるワーカーを直列化し、成功したリクエストが返すプロバイダーのメールIDを保存してください。ネットワークのタイムアウトで受け付けられたかどうかが曖昧になった場合は、ジョブを不明な状態で保留し、再送する前にプロバイダーのログやイベントと突き合わせます。転送の再試行のたびに新しいキーを生成するよりも、同じ論理操作に1つの安定したキーを再利用するほうが安全です。
メールのリクエストを意図をもって構築し検証する
Resendのメール送信エンドポイントは、Fromアドレス、受信者、件名、メッセージ内容を受け付け、テキスト、HTML、Reactでレンダリングしたコンテンツ、テンプレート、Cc、Bcc、reply-to、ヘッダー、添付ファイル、タグ、予約配信などの文書化されたオプションがあります。プロダクトに必要なものだけを公開してください。アドレスの構文とテナントの所有権を検証し、受信者数と添付ファイル数をプロバイダーの上限より低く抑え、ヘッダーへの改行インジェクションを拒否し、MIME関連のコンテンツはメンテナンスされているライブラリか信頼できるプロバイダーのフィールドを通じて構築します。認証情報、機密性の高い個人データ、制限のない顧客の入力をタグやヘッダーに入れてはいけません。内容全体をログに残すのではなく、テンプレートのリビジョンとサニタイズした変数を保存します。内部のアダプターは、受け付けられたプロバイダーIDや分類された失敗など範囲の狭い結果を返すべきであり、プロバイダーのレスポンスの詳細をビジネスコードに漏らすべきではありません。これにより、プロダクトのイベントの仕様を変えずに、プロバイダー固有のフィールド名、SDKのバージョン、リクエストの上限を更新できるようになります。
再試行する前にAPIのレスポンスと使用量の上限を分類する
HTTPのレスポンスは、ワークフローにおけるひとつの観測として扱ってください。送信が成功したレスポンスはメールの識別子を返すので、内部のジョブと一緒に保存すべきですが、宛先による受け付けや受信トレイへの到達を立証するものではありません。バリデーション、認証、ドメイン、権限、ペイロードのエラーは、やみくもに再試行するのではなく修正してください。ResendはAPIのリクエスト上限を文書化しており、残りの容量、リセットのタイミング、再試行までの遅延を示すフィールドを含む、レート制限とクォータのヘッダーを返します。429のレスポンスでは、文書化された間隔にジッターを加えて待機すべきです。転送の失敗と再試行対象のサーバーエラーは、指数バックオフ、有限の試行回数、そして文書化された期間内であれば同じ論理的な冪等キーを使って再試行します。クライアントがレスポンスを受け取っていなくてもプロバイダーがメールを受け付けている可能性があるため、曖昧な失敗には突き合わせが必要です。繰り返される失敗がドメイン、テンプレート、キー、テナントごとに集中した場合はアラートを出しますが、認証情報、内容全体、不要な受信者データは運用ログに含めないでください。
イベントを処理する前にWebhookのリクエストを認証する
専用のHTTPSのWebhookエンドポイントを設定し、リクエストのrawボディをそのまま保持してください。Resendのドキュメントでは、Svix互換のヘッダーと署名シークレットによるWebhookの署名が説明されています。JSONの解析や再シリアライズの前に、変更されていないペイロードに対してWebhookのID、タイムスタンプ、署名を検証し、公式の検証フローかメンテナンスされている互換ライブラリを使ってください。無効なリクエストや古いリクエストは拒否し、リクエストのサイズに上限を設け、署名シークレットは送信用のキーとは分けて管理します。認証後、プロセスがクラッシュしても配信の証拠が黙って失われないよう、確認応答を返す前にイベントを永続的に保存するかキューに入れます。配信システムはWebhookを再試行・重複させることがあるため、イベント識別子を重複排除のキーとして使い、状態遷移が逆戻りしないようにしてください。後から届いたイベントや重複したイベントが、最後に届いたというだけで、より情報量の多い最終結果を上書きしてはいけません。検証の失敗とイベントの遅延は運用上のシグナルとして記録しますが、rawのメッセージ内容は必要な保持期間を超えて保存しないでください。
配信を誇張せずにプロバイダーのイベントをモデル化する
Resendは、sent、delivered、delivery delayed、bounced、complained、failed、opened、clickedなど、名前付きのメールイベントの種類を公開しています。これらのプロバイダーの名前を、元のイベントの種類、プロバイダーのメールID、イベントID、タイムスタンプ、受信者の範囲、利用可能な診断データとともに、内部の状態モデルに対応付けてください。sentイベントはプロバイダー側の進捗を表します。deliveredイベントはResendが文書化しているイベントの意味に従って配信を報告しますが、受信システムでのSMTPの成功からは、受信者の最終的なフォルダはわかりません。開封とクリックはエンゲージメントの観測であって配信の証明ではなく、プライバシー保護の技術の影響を受けることがあります。バウンス、苦情、恒久的な失敗は、次の送信を判断する前に受信者の安全性の状態を更新すべきです。プロバイダーのイベント履歴は追記専用とし、ユーザーに見せるステータスは明示的なルールから導き出してください。これにより、サポートのための証拠が保たれ、責任が移った後や受信者が否定的なシグナルを示した後の安全でない再試行を防げます。
管理下の受信者で失敗と回復の経路をテストする
本番以外のキー、管理下の検証済みサブドメイン、チームが所有するメールボックスを使ってください。テキストとHTMLのコンテンツ、reply-toの挙動、添付ファイルの上限、安定した冪等キー、保存されたプロバイダーの識別子をテストします。同じ論理ジョブを2回送信し、アプリケーションとプロバイダーの制御によって意図しない重複が生じないことを確認してください。不正なペイロード、誤ったドメイン、取り消されたキー、権限不足、レート制限、転送のタイムアウト、バウンス、苦情、配信の遅延、重複したWebhook、署名対象のボディの改変、古いWebhookのタイムスタンプ、署名シークレットのローテーションを試します。確認応答の前にイベントの取り込みが永続化されていること、受信者の安全性の状態によって以降のジョブがブロックされることを確認してください。無関係なレコードを削除することなく、DNSのローテーションとプロバイダーの削除をテストします。ダッシュボードでは、送信の失敗、レイテンシー、Webhookの検証失敗、イベントの遅延、バウンス、苦情、突き合わせのキューを扱うべきです。クォータ、上限、イベントのフィールド、利用可能な権限は、デプロイしたアプリケーションのコードとは無関係に変わることがあるため、ローンチ時にはResendの最新のドキュメントとアカウントの設定を見直してください。
移行前に公開API機能を比較する
SendHQは、検証済みドメイン送信、メール受信、ホスト型テンプレート、配信イベント、サプレッションを含む、ワークスペース単位のメールAPI向けOpenAPI 3.1契約を公開しています。連携を移行する前に、リクエスト本文、認証、冪等性、返されるID、エラー形式、Webhook、ドメインルール、サプレッションの動作を比較し、フィールド単位のテストで検証してください。類似したエンドポイント名から互換性を想定しないでください。
よくある質問
Resendでメールを送信するエンドポイントはどれですか?
Resendは、Bearer認証を使う`POST https://api.resend.com/emails`を文書化しています。プロダクトの操作、送信ドメイン、受信者、内容を認可した後で、信頼できるサーバーのコードからのみ呼び出してください。
ResendのAPIキーのスコープはどう設定すべきですか?
送信アクセスのキーを使い、文書化された制御がアーキテクチャに合う場合は、ワークロードのドメインに限定してください。本番、本番以外、管理用の権限は、シークレット管理された別々の認証情報に分けておきます。
ResendのAPIが成功レスポンスを返せば、配信されたことになりますか?
いいえ。プロバイダーによる受け付けを記録し、メールの識別子を返すだけです。その後の認証されたイベントでプロバイダーの進捗や受信システムへの配信が報告されることはありますが、受信トレイへの到達は、受信側による別の分類のままです。
Resendの冪等性はどのようにメールの重複を防ぎますか?
同じ論理リクエストには、安定した`Idempotency-Key`を1つ送信してください。Resendは現在、キーを24時間保持し、最大256文字としているため、より長期間有効な内部の一意制約も併せて維持してください。
ResendのWebhookの署名はどのように検証すべきですか?
リクエストのrawボディをそのまま保持し、解析する前に、文書化されたSvix互換のWebhook ID、タイムスタンプ、署名のヘッダーを検証してください。無効な入力や古い入力は拒否し、認証されたイベントは確認応答を返す前に永続的にキューに入れます。
SendHQはResendを置き換えられますか?
SendHQとResendを互換と見なす前に、公開API契約を比較し、フィールド単位の統合テストを実行してください。
出典
- Resendのメール送信API — Resend
- ResendのAPIキー — Resend
- Resendのドメイン — Resend
- Resendの冪等キー — Resend
- Resendの使用量の上限 — Resend
- ResendのWebhook — Resend
- ResendのWebhookリクエストを検証する — Resend
- ResendのWebhookイベントの種類 — Resend
- RFC 5321:簡易メール転送プロトコル(SMTP) — RFC Editor
- SendHQ OpenAPI仕様 — SendHQ