Webhook Inspector
Inbound deliveries with payload and response. Signature status is its own field, never folded into the status code — a 200 with an invalid signature is a forged request your handler accepted.
src/components/ui/webhook-inspector.tsxAbout
From the component's own source, where it was written.
Inbound webhook deliveries, with payload and response.
Both directions are kept: what arrived and what we answered. A webhook failure is nearly always a disagreement between the two, and a log that stores only the payload cannot tell you whether the sender was wrong or your handler was.
Signature verification status is its own field, separate from the response code. A delivery can return 200 and have failed verification — that is a forged request your handler accepted, and it must not be buried under a green status.
Retries are grouped under their original delivery rather than listed separately, so five rows of the same event read as one problem rather than five.
Install
npx astralyx-ui add webhook-inspector
Usage
import { WebhookInspector } from '@/components/ui/webhook-inspector'
<WebhookInspector deliveries={deliveries} onReplay={replay} />Composer
Change the props and the source below follows.
<WebhookInspector deliveries={deliveries} onReplay={replay} />Examples
Deliveries, one of them failing
<WebhookInspector deliveries={deliveries} now={now} onReplay={replay} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
WebhookInspector
Extends Omit<ComponentProps<'div'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| deliveries | WebhookDelivery[] | required | { id, event, at, status?, durationMs?, payload?, responseBody?, signature?, attempt? }. |
| onReplay | (id: string) => void | — | Omit for a read-only log. |
| now | Date | — | — |
| locale | string | 'en-GB' | — |
| emptyLabel | ReactNode | 'No deliveries yet' | — |
| payloadLabel | ReactNode | 'Payload' | — |
| responseLabel | ReactNode | 'Response' | — |
| replayLabel | ReactNode | 'Replay' | — |
| attemptLabel | (attempt: number, max?: number) => ReactNode | DEFAULT_ATTEMPT_LABEL | — |
| forgedNote | ReactNode | 'This request was accepted with an invalid signature — it may not have come from the sender you expect.' | Shown when a delivery succeeded despite a bad signature. |
Types
WebhookDelivery
Inbound webhook deliveries, with payload and response.
| Field | Type | Description |
|---|---|---|
| id | string | — |
| event | string | — |
| at | Date | — |
| status? | number | — |
| durationMs? | number | — |
| payload? | Json | — |
| responseBody? | string | — |
| signature? | 'valid' | 'invalid' | 'missing' | 'unchecked' | Separate from the status. A delivery that returned 200 with an invalid signature is called out explicitly. |
| attempt? | number | — |
| maxAttempts? | number | — |
Behaviour
| Topic | Detail | Description |
|---|---|---|
| both directions | kept | What arrived and what you answered. A webhook failure is a disagreement between the two, and storing only the payload cannot say which side was wrong. |