Skip to content

Events and replay

Every accepted inbound request and every outbound send creates a webhook event record.

Terminal window
type WebhookEvent = {
id: string
direction: "inbound" | "outbound"
namespace: string
name: string
provider: string
eventType: string
externalEventId?: string
status: "accepted" | "duplicate" | "signature_failed" | "queued" | "processing" | "processed" | "failed"
receivedAt: string
processedAt?: string
payload: unknown
headers: Record<string, string>
payloadRef?: string
signatureStatus?: "verified" | "failed" | "skipped"
dedupeKey?: string
error?: string
}
Terminal window
const recent = await stripe.events.list({
limit: 25,
})

Filter by status:

Terminal window
const failed = await stripe.events.list({
status: "failed",
limit: 100,
})

Filter by direction:

Terminal window
const outbound = await billingEvents.events.list({
direction: "outbound",
})
Terminal window
const event = await stripe.events.get("whevt_123")
if (event?.status === "failed") {
console.error(event.error)
}

Use event details in support tools:

Terminal window
app.get("/admin/webhooks/:eventId", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const eventId = pathSegments[3]
const event = await stripe.events.get(eventId)
if (!event) {
return Response.json({ error: "Event not found" }, { status: 404 })
}
return Response.json({ event })
})

Replay runs the stored event through the same processing path:

Terminal window
await stripe.events.replay("whevt_123")

A replay is useful after:

  • A downstream outage is fixed.
  • A handler bug is deployed.
  • A manual support action needs to retry one event.
  • A partner asks for a missed outbound event to be sent again.
Terminal window
app.post("/admin/webhooks/:eventId/replay", async (request) => {
const pathSegments = new URL(request.url).pathname.split("/")
const eventId = pathSegments[3]
const result = await stripe.events.replay(eventId)
return Response.json(result)
})

Protect admin routes with Auth and Policy in production apps.

StatusMeaning
acceptedEvent was recorded and accepted.
duplicateDedupe matched an earlier event.
signature_failedSignature verification failed.
queuedEvent is waiting for processing or delivery.
processingHandler or delivery is running.
processedHandler or delivery completed.
failedHandler or delivery failed.