Webhook Event Log and Replay
The gateway persists outbound webhook events and their delivery attempts so operators and integrators can inspect failures, replay events, and manage retention without digging directly through service logs.
This page describes the persisted webhook-event surface, the difference between event replay and DLQ retry, and the SDK helpers exposed from the normal admin clients.
Core API surfaces
| Purpose | Endpoint |
|---|---|
| List persisted events | GET /api/v1/webhook-events |
| Get one event | GET /api/v1/webhook-events/{eventId} |
| List delivery attempts for an event | GET /api/v1/webhook-events/{eventId}/deliveries |
| Replay an event to active subscriptions | POST /api/v1/webhook-events/{eventId}/replay |
| Retry one DLQ delivery row | POST /api/v1/webhook-deliveries/{deliveryId}/retry |
| Read self-scoped retention config | GET /api/v1/webhook-events/retention |
| Update self-scoped retention config | PUT /api/v1/webhook-events/retention |
| Admin list retention overrides | GET /api/v1/admin/webhook-events/retention |
| Admin update one org retention override | PUT /api/v1/admin/webhook-events/retention/{organizationId} |
Replay vs. DLQ retry
These two actions are related but not interchangeable.
Replay an event
Use event replay when you want to enqueue delivery again from the persisted event record.
- Endpoint:
POST /api/v1/webhook-events/{eventId}/replay - Typical use: replay the event to every active subscription, or to a filtered subset of subscriptions
- Result: new delivery attempt rows are queued for that event
Retry a DLQ delivery
Use DLQ retry when a specific delivery row already failed all automatic
attempts and was marked DLQ_PENDING or DLQ_EXHAUSTED.
- Endpoint:
POST /api/v1/webhook-deliveries/{deliveryId}/retry - Typical use: the merchant fixed their endpoint and you want to re-drive the exact failed delivery row
- Result: the gateway resets that delivery row back into the delivery worker
Rule of thumb:
- if you are operating from an event-centric view, use replay
- if you are operating from a delivery-row / DLQ view, use retry
SDK helpers
The persisted-event surface is exposed from the normal admin clients in both SDKs.
TypeScript
import { GatewayAdminClient } from '@gateway/sdk'
const client = new GatewayAdminClient({
environment: 'staging',
tokenProvider: async () => await firebaseUser.getIdToken(),
})
const details = await client.webhookEvents.getDetails('evt_123')
// Replay only failed / DLQ deliveries for the event.
await client.webhookEvents.replayFailedDeliveries(details.event.id)
// Or replay a specific subset of prior delivery rows.
await client.webhookEvents.replayDeliveries(details.event.id, {
deliveryIds: details.deliveries.filter((delivery) => delivery.status === 'FAILED').map((delivery) => delivery.id),
})
// Retry one DLQ delivery row directly.
await client.webhookEvents.retryDeliveryFromDlq('del_456')
const retention = await client.webhookEvents.findRetentionConfigForOrganization('org_123')
Kotlin
import com.myriad.gateway.GatewayAdminClient
import com.myriad.gateway.GatewayConfig
suspend fun operateWebhooks() {
val client = GatewayAdminClient(GatewayConfig("client-id", "client-secret"))
val details = client.webhookEvents.getDetails("evt_123")
client.webhookEvents.replayFailedDeliveries(details.event.id)
client.webhookEvents.replayDeliveries(
eventId = details.event.id,
deliveryIds =
details.deliveries
.filter { it.status == "FAILED" }
.map { it.id }
.toSet(),
)
client.webhookEvents.retryDeliveryFromDlq("del_456")
val retention = client.webhookEvents.findRetentionConfigForOrganization("org_123")
client.close()
}
Delivery diagnostics
Persisted delivery rows can include:
- delivery status
- HTTP status from the destination endpoint
- attempt count
- last error message
- allowlisted response headers (
lastResponseHeaders) - replay lineage (
replayOfDeliveryId)
That data is the first place to look before jumping to raw service logs.
Correlation IDs inside received webhook handlers
If your receiver wants a durable way to map a received webhook back to gateway traces or support investigations, use the verifier helpers that preserve the delivery correlation id.
- TypeScript:
WebhookVerifier.verifyDelivery(...) - Kotlin:
WebhookVerifier.verifyDelivery(...)
Those helpers return the decoded event plus a correlationId extracted from
traceparent, X-Cloud-Trace-Context, or X-Request-Id headers when present.
Related docs
- Gift Card Webhook Events — one concrete webhook-event catalogue.
- Webhook DLQ depth runbook — operator
flow when deliveries are already in
DLQ_PENDING. - TypeScript SDK and Kotlin SDK — broader client usage docs.