send-email について
send-emailは、Resendでメールを送る開発者向けスキルです。単体・一括送信の使い分けに加え、リトライ、到達性、テンプレート、テスト方法を説明します。
主な機能
- 01単体送信と一括送信の使い分け
- 02冪等キーとエラー時のリトライ指針
- 03添付、予約送信、テンプレート
- 04配信イベントとタグの説明
- 05到達性とテストの指針
活用シーン
- 01トランザクションメールや添付メールの送信
- 02複数の通知メールをまとめて送信
- 03レート制限やサーバーエラーへのリトライ
- 04配信、バウンス、苦情イベントのテスト
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ resend/ resend-skills --skill send-emailインストール後、Claude Code で/send-emailを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/batch-email-examples.mdbest-practices.mdinstallation.mdsingle-email-examples.mdwebhooks.md詳細
Resend でメールを送信する
概要
Resend には、メール送信用のエンドポイントが 2 つあります。
| 方法 | エンドポイント | 用途 |
|---|---|---|
| 単一送信 | POST /emails | 個別のトランザクションメール、添付ファイル付きメール、予約送信 |
| 一括送信 | POST /emails/batch | 1 回のリクエストで複数の異なるメールを送信(最大 100 件)、一括通知 |
一括送信を選ぶ場合:
- 2 件以上の異なるメールを一度に送信する
- API 呼び出しを減らすことが重要である(デフォルトのレート制限は毎秒 2 リクエストです)
- 添付ファイルや予約送信が不要である
単一送信を選ぶ場合:
- メールを 1 件送信する
- メールに添付ファイルが必要である
- メールを予約送信する必要がある
- 受信者ごとに送信タイミングを変える必要がある
クイックスタート
- 設定ファイル(package.json、requirements.txt、go.mod など)からプロジェクトの言語を検出します
- SDK をインストールするか、cURL を使用します。詳しくはreferences/installation.mdを参照してください
- 上記の判断基準に基づいて、単一送信または一括送信を選択します
- ベストプラクティスを実装します。冪等性キー、エラー処理、再試行を含みます
ベストプラクティス(本番環境では必須)
本番環境でメールを送信する場合は、必ずこれらを実装してください。完全な実装例はreferences/best-practices.mdを参照してください。
冪等性キー
失敗したリクエストを再試行する際のメールの重複を防ぎます。
| 主な情報 | |
|---|---|
| 形式(単一送信) | <event-type>/<entity-id>(例:welcome-email/user-123) |
| 形式(一括送信) | batch-<event-type>/<batch-id>(例:batch-orders/batch-456) |
| 有効期限 | 24 時間 |
| 最大長 | 256 文字 |
| 重複したペイロード | 再送信せずに元のレスポンスを返します |
| 異なるペイロード | 409 エラーを返します |
エラー処理
| コード | 対応 |
|---|---|
| 400、422 | リクエストパラメーターを修正し、再試行しないでください |
| 401、403 | API キーを確認するか、ドメインを検証し、再試行しないでください |
| 409 | 冪等性の競合です。新しいキーを使用するか、ペイロードを修正してください |
| 429 | レート制限に達しました。指数バックオフで再試行してください(デフォルトのレート制限は毎秒 2 リクエストです) |
| 500 | サーバーエラーです。指数バックオフで再試行してください |
再試行戦略
- バックオフ: 指数(1 秒、2 秒、4 秒…)
- 最大再試行回数: 多くの用途では 3~5 回
- 再試行するのは: 429(レート制限)と 500(サーバーエラー)のみ
- 再試行時は必ず使用: 冪等性キー
単一メール
エンドポイント: POST /emails(cURL よりも SDK を推奨)
必須パラメーター
| パラメーター | 型 | 説明 |
|---|---|---|
from | string | 送信者アドレス。形式:"Name <[email protected]>" |
to | string[] | 受信者アドレス(最大 50 件) |
subject | string | メールの件名 |
html または text | string | メール本文 |
任意パラメーター
| パラメーター | 型 | 説明 |
|---|---|---|
cc | string[] | CC の受信者 |
bcc | string[] | BCC の受信者 |
reply_to* | string[] | 返信先アドレス |
scheduled_at* | string | 送信日時を予約します(ISO 8601) |
attachments | array | 添付ファイル(合計最大 40MB) |
tags | array | トラッキング用のキーと値のペア(タグを参照) |
headers | object | カスタムヘッダー |
*パラメーター名は SDK によって異なります(例:Node.js では replyTo、Python では reply_to)。
最小限の例(Node.js)
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send(
{
from: 'Acme <[email protected]>',
to: ['[email protected]'],
subject: 'Hello World',
html: '<p>Email body here</p>',
},
{ idempotencyKey: `welcome-email/${userId}` }
);
if (error) {
console.error('Failed:', error.message);
return;
}
console.log('Sent:', data.id);
エラー処理と再試行ロジックを含む、すべての SDK の実装例はreferences/single-email-examples.mdを参照してください。
一括メール
エンドポイント: POST /emails/batch(ただし、cURL よりも SDK を推奨)
制限事項
- 添付ファイル不可 - 添付ファイル付きメールには単一送信を使用してください
- 予約送信不可 - 予約送信メールには単一送信を使用してください
- アトミック - 1 件でもメールの検証に失敗すると、バッチ全体が失敗します
- 1 回のリクエストにつき最大 100 件のメール
- バッチ内の個々のメールの受信者は最大 50 件
送信前の検証
検証エラーがあるとバッチ全体が失敗するため、送信前にすべてのメールを検証してください。
- 必須フィールド(from、to、subject、html/text)を確認します
- メールアドレスの形式を検証します
- バッチサイズが 100 以下であることを確認します
最小限の例(Node.js)
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.batch.send(
[
{
from: 'Acme <[email protected]>',
to: ['[email protected]'],
subject: 'Order Shipped',
html: '<p>Your order has shipped!</p>',
},
{
from: 'Acme <[email protected]>',
to: ['[email protected]'],
subject: 'Order Confirmed',
html: '<p>Your order is confirmed!</p>',
},
],
{ idempotencyKey: `batch-orders/${batchId}` }
);
if (error) {
console.error('Batch failed:', error.message);
return;
}
console.log('Sent:', data.map(e => e.id));
検証、エラー処理、再試行ロジックを含むすべての SDK 実装については、references/batch-email-examples.md を参照してください。
大規模なバッチ(100 件以上のメール)
100 件を超えるメールを送信する場合は、複数のバッチリクエストに分割してください。
- 100 件ずつに分割します
- チャンクごとに一意の冪等性キーを使用します:
<batch-prefix>/chunk-<index> - スループットを向上させるため、チャンクを並列送信します
- 部分的な失敗に対応できるよう、チャンクごとに結果を追跡します
チャンク分割の完全な実装については、references/batch-email-examples.md を参照してください。
到達率
受信トレイへの到達率を最大限に高めるには、次の方法に従ってください。
到達率について詳しくは、npx skills add resend/email-best-practices で email-best-practices スキルをインストールしてください。
必須
| 実践方法 | 理由 |
|---|---|
| 有効な SPF、DKIM、DMARC レコードを設定する | メールを認証し、なりすましを防止します |
| リンクのドメインを送信元ドメインに一致させる | @acme.com から送信する場合は、https://acme.com へのリンクを使用します。ドメインが一致しないと、迷惑メールフィルターに検知されます |
| プレーンテキスト版を含める | アクセシビリティと到達率を高めるため、html と text の両方のパラメーターを使用します(指定されていない場合、Resend がプレーンテキスト版を生成します) |
| 「no-reply」アドレスを避ける | 実際に利用できるアドレス(例:support@)を使用すると、信頼性を示すシグナルが向上します |
| 本文を 102KB 未満に保つ | これを超えるサイズのメッセージは Gmail で省略表示されます |
推奨
| 実践方法 | 理由 |
|---|---|
| サブドメインを使用する | トランザクションメールには notifications.acme.com、マーケティングメールには mail.acme.com を使用すると、レピュテーションを保護できます |
| トランザクションメールではトラッキングを無効にする | 開封・クリックのトラッキングは、パスワードリセットや領収書などのメールで迷惑メールフィルターに検知されることがあります |
トラッキング(開封とクリック)
トラッキングはメールごとではなく、Resend ダッシュボードのドメインレベルで設定します。
| 設定 | 仕組み | 推奨事項 |
|---|---|---|
| 開封トラッキング | 1x1 ピクセルの透明な画像を挿入します | トランザクションメールでは無効にしてください。到達率が低下する可能性があります |
| クリックトラッキング | リダイレクト経由でリンクを書き換えます | 機密性の高いメール(パスワードリセット、セキュリティアラート)では無効にしてください |
トラッキングを有効にする場合:
- エンゲージメント指標が重要なマーケティングメール
- ニュースレターやお知らせ
トラッキングを無効にする場合:
- トランザクションメール(領収書、確認メール、パスワードリセット)
- セキュリティ上機密性の高いメール
- 到達率の最大化を優先する場合
ダッシュボードで設定します:Domain → Configuration → Click/Open Tracking
Webhook(イベント通知)
Webhook を使用すると、メールの配信状況をリアルタイムで追跡できます。イベント発生時に、Resend はエンドポイントに HTTP POST リクエストを送信します。
| イベント | 用途 |
|---|---|
email.delivered | 配信の成功を確認します |
email.bounced | メーリングリストから削除し、ユーザーに通知します |
email.complained | ユーザーの配信登録を解除します(迷惑メールの苦情) |
email.opened / email.clicked | エンゲージメントを追跡します(マーケティングのみ) |
すべてのリクエストで Webhook 署名を検証してください。 検証しないと、誰でもエンドポイントに偽のイベントを送信できます。
セットアップ、署名検証コード、すべてのイベントタイプについては、references/webhooks.md を参照してください。
タグ
タグは、メールの追跡とフィルタリングに役立つキーと値のペアです。
tags: [
{ name: 'user_id', value: 'usr_123' },
{ name: 'email_type', value: 'welcome' },
{ name: 'plan', value: 'enterprise' }
]
用途:
- システム内の顧客とメールを関連付ける
- メールの種類(welcome、receipt、password-reset)で分類する
- Resend ダッシュボードでメールをフィルタリングする
- Webhook イベントをアプリケーションに関連付ける
制約: タグ名と値には、ASCII の英字、数字、アンダースコア、ハイフンのみを使用できます。それぞれ最大 256 文字です。
テンプレート
リクエストごとに HTML を送信する代わりに、事前に作成したテンプレートを使用してください。
const { data, error } = await resend.emails.send({
from: 'Acme <[email protected]>',
to: ['[email protected]'],
subject: 'Welcome!',
template: {
id: 'tmpl_abc123', // or alias: 'welcome-email'
variables: {
USER_NAME: 'John', // Case-sensitive! Must match template exactly.
ORDER_TOTAL: '$99.00'
}
}
});
注: 変数名は大文字と小文字を区別するため、テンプレートの定義と完全に一致させる必要があります。USER_NAME、userName、user_name のいずれも有効です。送信時に定義と同じ表記を使用してください。
| 項目 | 詳細 |
|---|---|
| 予約名 | FIRST_NAME、LAST_NAME、EMAIL、UNSUBSCRIBE_URL、contact、this |
| フォールバック値 | 任意です。設定されておらず、送信時に変数が指定されていない場合、送信は失敗します(422) |
| 併用不可 | html、text、react パラメーター |
| subject / from | テンプレートのデフォルト値は、送信ごとに上書きできます |
テンプレートは使用前に公開する必要があります。下書きのテンプレートでは送信できません。
API 経由でテンプレートを作成、更新、公開、削除するには、templates スキルを使用してください。
テスト
実在するメールプロバイダーで、偽のアドレスを使ってテストしないでください。
[email protected]、[email protected]、[email protected] のようなアドレスを使うと、次の問題が発生します。
- バウンスします — これらのアドレスは存在しません
- 送信者の評判を損ないます — 高いバウンス率はスパムフィルターの作動につながります
- ドメインがブロックリストに登録されます — プロバイダーはバウンス率の高いドメインにフラグを立てます
安全なテスト方法
| 方法 | アドレス | 結果 |
|---|---|---|
| 配信成功 | [email protected] | 配信成功をシミュレートします |
| バウンス | [email protected] | ハードバウンスをシミュレートします |
| 苦情 | [email protected] | スパム報告をシミュレートします |
| 自分のメールアドレス | 自分が実際に使用しているアドレス | 実際の配信テストを行います |
開発環境の場合: resend.dev のテスト用アドレスを使い、送信者の評判に影響を与えずにさまざまなシナリオをシミュレートしてください。
ステージング環境の場合: 自分が管理している実在のアドレス(チームメンバーや自分が所有するテストアカウント)に送信してください。
ドメインのウォームアップ
新しいドメインでは、評判を確立するために送信量を徐々に増やす必要があります。
重要な理由: 新しいドメインから突然大量に送信すると、スパムフィルターが作動します。ISP は段階的な増加を想定しています。
推奨スケジュール
既存のドメイン
| 日 | 1 日あたりのメッセージ数 | 1 時間あたりのメッセージ数 |
|---|---|---|
| 1 | 最大 1,000 通のメール | 最大 100 通 |
| 2 | 最大 2,500 通のメール | 最大 300 通 |
| 3 | 最大 5,000 通のメール | 最大 600 通 |
| 4 | 最大 5,000 通のメール | 最大 800 通 |
| 5 | 最大 7,500 通のメール | 最大 1,000 通 |
| 6 | 最大 7,500 通のメール | 最大 1,500 通 |
| 7 | 最大 10,000 通のメール | 最大 2,000 通 |
新しいドメイン
| 日 | 1 日あたりのメッセージ数 | 1 時間あたりのメッセージ数 |
|---|---|---|
| 1 | 最大 150 通のメール | |
| 2 | 最大 250 通のメール | |
| 3 | 最大 400 通のメール | |
| 4 | 最大 700 通のメール | 最大 50 通 |
| 5 | 最大 1,000 通のメール | 最大 75 通 |
| 6 | 最大 1,500 通のメール | 最大 100 通 |
| 7 | 最大 2,000 通のメール | 最大 150 通 |
これらの指標を監視してください
| 指標 | 目標 | 超過した場合の対応 |
|---|---|---|
| バウンス率 | < 4% | 送信ペースを落とし、リストを整理します |
| スパム報告率 | < 0.08% | 送信ペースを落とし、コンテンツを見直します |
サードパーティのウォームアップサービスは使用しないでください。 実際に関心を持っている受信者に、関連性の高いコンテンツを送ることに注力してください。
抑制リスト
Resend は、メールを送信すべきでないアドレスの抑制リストを自動的に管理します。
次の場合にアドレスが追加されます:
- メールがハードバウンスした場合(アドレスが存在しない)
- 受信者がメールをスパムとして報告した場合
- ダッシュボードから手動で追加した場合
処理内容: Resend は抑制されたアドレスへの配信を試みません。代わりに email.suppressed ウェブフックイベントが発生します。
重要な理由: バウンスや苦情があったアドレスへの送信を続けると、送信者の評判を損ないます。抑制リストが自動的に保護します。
管理: Resend ダッシュボードの Suppressions から、抑制されたアドレスを確認・管理できます。
よくある間違い
| 間違い | 修正方法 |
|---|---|
| 冪等性キーを付けずに再試行する | 再試行時の重複送信を防ぐため、必ず冪等性キーを含めてください |
| 添付ファイル付きメールにバッチを使用する | バッチは添付ファイルに対応していません。代わりに個別に送信してください |
| 送信前にバッチを検証しない | まずすべてのメールを検証してください。無効なメールが1件でもあると、バッチ全体が失敗します |
| 400/422 エラーを再試行する | これらは検証エラーです。リクエストを修正し、再試行しないでください |
| 同じ冪等性キーで異なるペイロードを送信する | 409 エラーが返されます。メール内容ごとに一意のキーを使用してください |
| トランザクションメールでトラッキングを有効にする | パスワードリセットや領収書では、開封・クリックのトラッキングを無効にしてください。到達率が低下します |
| 「no-reply」の送信者アドレスを使用する | support@ のような実在するアドレスを使用してください。メールプロバイダーからの信頼性が向上します |
| Webhook の署名を検証しない | 必ず検証してください。検証されていないイベントは信頼できません |
| 偽のメールアドレス([email protected])でテストする | [email protected] を使用してください。偽のアドレスはバウンスし、レピュテーションを損ないます |
| テンプレート変数名が一致しない | 変数名では大文字と小文字が区別されるため、テンプレート定義と完全に一致させる必要があります。大文字・小文字の組み合わせは自由です。送信時の呼び出しと一致していれば、USER_NAME と firstName のどちらも使用できます |
| 新しいドメインから大量に送信する | 徐々に送信量を増やしてください。急増するとスパムフィルターに引っかかります |
注意事項
fromアドレスには、検証済みのドメインを使用する必要があります- 送信元アドレスで返信を受信できない場合は、有効なアドレスを
reply_toパラメーターに設定してください。 - API キーは
RESEND_API_KEY環境変数に保存してください - Node.js SDK は、React Email コンポーネント用の
reactパラメーターに対応しています - Resend はレスポンスで
error、data、headersを返します。 - 成功時の Data は、単一送信では
{ id: "email-id" }、バッチ送信では ID の配列を返します - 大規模なリストへのマーケティングキャンペーンには、代わりに Resend Broadcasts を使用してください