Zum Inhalt springen

Webhooks im Überblick

Webhooks schicken E-Mail-Events an deinen Server, sobald sie eintreten, sodass du GET /emails/{id} nicht abfragen musst. SpacePost signiert jede Anfrage nach dem Schema von Standard Webhooks (dem, das Svix und Resend verwenden), daher funktioniert bestehender Verifizierungscode unverändert.

  1. Erstelle einen Endpoint, der POST mit JSON-Body akzeptiert und schnell mit 2xx antwortet.

  2. Registriere ihn

    create-webhook.ts
    import { SpacePost } from "@spacepost/node";
    const spacepost = new SpacePost(process.env.SPACEPOST_API_KEY);
    const { data: webhook, error } = await spacepost.webhooks.create({
    endpoint: "https://acme.com/webhooks/spacepost",
    events: ["email.delivered", "email.bounced", "email.complained"],
    });
    if (error) throw new Error(`${error.name}: ${error.message}`);
    // Store this secret: you need it to verify signatures. It starts with "whsec_".
    console.log(webhook.id, webhook.signing_secret);
    Response
    {
    "object": "webhook",
    "id": "0192e1c4-0000-7000-8000-0000000000aa",
    "endpoint": "https://acme.com/webhooks/spacepost",
    "events": ["email.delivered", "email.bounced", "email.complained"],
    "status": "enabled",
    "created_at": "2026-10-23T14:00:00.000Z",
    "signing_secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
    }
  3. Prüfe die Signatur bei jeder Anfrage. Siehe Signaturen prüfen.

  4. Gib 2xx zurück. Alles andere (auch Weiterleitungen und Timeouts) wird wiederholt. Siehe Wiederholungen.

Jede Zustellung ist ein POST mit Content-Type: application/json und diesen Headern:

Header Wert
webhook-id Eindeutige ID dieser Zustellung. Bei jeder Wiederholung dieselbe ID, nutze sie also zur Deduplizierung.
webhook-timestamp Unix-Zeit in Sekunden, zu der dieser Versuch gesendet wurde.
webhook-signature v1,<base64 HMAC-SHA256>. Eine durch Leerzeichen getrennte Liste, wenn es mehrere Signaturen gibt.
svix-id, svix-timestamp, svix-signature Identische Duplikate der drei obigen Header, damit Svix-Bibliotheken unverändert funktionieren.

Der Body hat die Form { "type": "...", "created_at": "...", "data": { ... } }. Siehe Event-Typen.

POST /webhooks, GET /webhooks, GET /webhooks/{id}, PATCH /webhooks/{id} (ändert endpoint, events oder status: enabled oder disabled) und DELETE /webhooks/{id}. Das signing_secret wird beim Erstellen oder beim Abrufen eines einzelnen Webhooks zurückgegeben, nicht in Listen.

manage-webhooks.ts
import { SpacePost } from "@spacepost/node";
const spacepost = new SpacePost(process.env.SPACEPOST_API_KEY);
const id = "0192e1c4-0000-7000-8000-0000000000aa";
// Subscribe to more events and temporarily disable delivery.
await spacepost.webhooks.update({ id, events: ["email.delivered", "email.bounced", "email.opened"], status: "disabled" });
const { data } = await spacepost.webhooks.list({ limit: 20 });
console.log(data?.data.map((w) => `${w.id} ${w.status} ${w.endpoint}`));
await spacepost.webhooks.remove(id);
  • https:// in Produktion (reines http:// wird nur in der Entwicklung akzeptiert).
  • Der Host muss auf eine öffentliche Adresse auflösen. Localhost und private Netzwerke werden abgelehnt. Nutze für die lokale Entwicklung einen Tunnel wie ngrok oder Cloudflare Tunnel.
  • Antworte innerhalb von 15 Sekunden.
  • Weiterleitungen werden nicht verfolgt.