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.
-
Erstelle einen Endpoint, der
POSTmit JSON-Body akzeptiert und schnell mit2xxantwortet. -
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);Terminal-Fenster curl -X POST https://api.spacepost.dev/webhooks \-H "Authorization: Bearer $SPACEPOST_API_KEY" -H "Content-Type: application/json" \-d '{"endpoint": "https://acme.com/webhooks/spacepost","events": ["email.delivered", "email.bounced", "email.complained"]}'r = requests.post("https://api.spacepost.dev/webhooks",headers={"Authorization": f"Bearer {os.environ['SPACEPOST_API_KEY']}"},json={"endpoint": "https://acme.com/webhooks/spacepost", "events": ["email.delivered", "email.bounced"]},)print(r.json()["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"} -
Prüfe die Signatur bei jeder Anfrage. Siehe Signaturen prüfen.
-
Gib
2xxzurück. Alles andere (auch Weiterleitungen und Timeouts) wird wiederholt. Siehe Wiederholungen.
Format der Anfrage
Abschnitt betitelt „Format der Anfrage“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.
Webhooks verwalten
Abschnitt betitelt „Webhooks verwalten“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.
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);Anforderungen an Endpoints
Abschnitt betitelt „Anforderungen an Endpoints“https://in Produktion (reineshttp://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.