コンテンツにスキップ

イベントタイプ

Webhook を作成するときに、これらのイベントタイプを任意に組み合わせて購読できます。

イベント 発火するタイミング last_event に設定される値
email.scheduled scheduled_at 付きのメールが受理されたとき。 scheduled
email.sent メールが Amazon SES に渡されたとき。 sent
email.delivered 受信者のメールサーバーがメールを受け付けたとき。 delivered
email.delivery_delayed 配信が遅延している、または一時的に失敗しているとき。SES は再試行を続けます。 delivery_delayed
email.bounced 恒久的な失敗(アドレスが存在しない、ドメインが拒否した)。 bounced
email.complained 受信者がメールを迷惑メールとして報告したとき。 complained
email.opened 受信者がメールを開いたとき(開封の追跡が必要です)。 opened
email.clicked 受信者がリンクをクリックしたとき(クリックの追跡が必要です)。 clicked
email.failed SpacePost または SES がメールを送信できなかったとき(拒否、レンダリングの失敗、チームまたはテナントの一時停止)。 failed
email.suppressed 宛先が送信停止リストに載っているためスキップされたとき。 suppressed

Webhook のボディは Resend のものとまったく同じなので、Resend 向けに書いたハンドラーもそのまま動作します。

{
"type": "email.delivered",
"created_at": "2026-10-23T14:02:10.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"broadcast_id": "0192e1c4-0000-7000-8000-0000000000bb",
"tenant_id": "0192e1c4-5555-7000-8000-0000000000cc",
"tags": { "category": "welcome" }
}
}
  • type はイベントで、created_at はイベントが発生した日時です。
  • data.email_id、from、to(影響を受けた宛先だけでなく、メールのすべての宛先)、subject、created_at(メールが作成された日時)は常に含まれます。
  • data.broadcast_id は、一斉配信のメールにのみ含まれます。
  • data.tenant_id は、メールがテナントのために送信された場合(プラットフォームモード)にのみ含まれます。これは SpacePost のテナント id であり、ご自身の external_id ではありません。
  • data.tags は、メールにタグがあった場合にのみ含まれ、オブジェクト({ "name": "value" })になります。
  • 一部のイベントでは、イベント名に対応するオブジェクトが data に 1 つ追加されます: bounce、click、open、failed、suppressed。以下に一覧を示します。それ以外は追加されません。トップレベルに bounceType、delayType、reason というキーはありません。
{
"type": "email.scheduled",
"created_at": "2026-10-23T14:02:09.700Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Your trial ends tomorrow",
"created_at": "2026-10-23T14:02:09.512Z"
}
}
{
"type": "email.sent",
"created_at": "2026-10-23T14:02:10.100Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z"
}
}
{
"type": "email.delivered",
"created_at": "2026-10-23T14:02:11.350Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z"
}
}

SES の配信遅延と、一時的なバウンスのときに発火します。単なる遅延には追加のフィールドはありません。一時的なバウンスには、bounce オブジェクトも付きます(下記を参照。type: "Transient")。

{
"type": "email.delivery_delayed",
"created_at": "2026-10-23T14:07:00.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z"
}
}

このイベントになるのは恒久的なバウンスだけで、アドレスが送信停止リストに追加されます。data.bounce には、type(Permanent)、subType、受信側サーバーの message が含まれます。

{
"type": "email.bounced",
"created_at": "2026-10-23T14:02:12.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["nobody@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"bounce": {
"type": "Permanent",
"subType": "General",
"message": "smtp; 550 5.1.1 The email account that you tried to reach does not exist."
}
}
}

バウンスの subType には、General、NoEmail、Suppressed、OnAccountSuppressionList、MailboxFull、MessageTooLarge、ContentRejected、AttachmentRejected があります。

追加のフィールドはありません。アドレスは送信停止リストに追加されます。

{
"type": "email.complained",
"created_at": "2026-10-23T15:30:00.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Our monthly newsletter",
"created_at": "2026-10-23T14:02:09.512Z"
}
}
{
"type": "email.opened",
"created_at": "2026-10-23T14:05:44.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"open": { "ipAddress": "203.0.113.7", "userAgent": "Mozilla/5.0 (Macintosh)" }
}
}
{
"type": "email.clicked",
"created_at": "2026-10-23T14:06:10.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"click": {
"link": "https://acme.com/get-started",
"ipAddress": "203.0.113.7",
"userAgent": "Mozilla/5.0 (Macintosh)",
"timestamp": "2026-10-23T14:06:10.000Z"
}
}
}
{
"type": "email.failed",
"created_at": "2026-10-23T14:02:10.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"failed": { "reason": "Attachment https://files.acme.com/report.pdf returned HTTP 404" }
}
}

suppressed.reason は、suppression_list(宛先が送信停止リストに載っている)または recipient_domain_does_not_accept_mail(宛先のドメインにメールサーバーがない)のどちらかです。

{
"type": "email.suppressed",
"created_at": "2026-10-23T14:02:10.000Z",
"data": {
"email_id": "0192e1c4-7a3b-7c1e-9d2f-3b5a8e6f4c10",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com", "other@example.com"],
"subject": "Welcome to Acme",
"created_at": "2026-10-23T14:02:09.512Z",
"suppressed": { "recipients": ["other@example.com"], "reason": "suppression_list" }
}
}

TypeScript でイベントに型を付ける

Section titled “TypeScript でイベントに型を付ける”

Node SDK は、type で判別される共用体型 WebhookPayload をエクスポートしており、spacepost.webhooks.verify() もこれを返します。そのため、event.type で絞り込むと、正しい data のフィールドが得られます。

import type { WebhookPayload } from "@spacepost/node";
function handle(event: WebhookPayload) {
switch (event.type) {
case "email.bounced":
return event.data.bounce?.subType;
case "email.clicked":
return event.data.click?.link;
case "email.suppressed":
return event.data.suppressed.recipients;
case "email.failed":
return event.data.failed.reason;
default:
return event.data.tenant_id; // present when the email was sent for a tenant
}
}