Webhook Payload Viewer
Inspect webhook JSON events with pretty printing and nested key flattening for debugging and documentation.
Back to all tools on ToolForge
Pretty JSON
Flattened Paths
About Webhook Payload Viewer
This webhook payload viewer pretty prints JSON webhook events and flattens nested object keys into readable dot-notation paths for easier inspection and documentation.
It is useful for webhook debugging, API integration testing, event payload inspection, generating type definitions, documenting webhook structures for team reference, and understanding the complete field hierarchy of complex nested payloads from services like GitHub, Stripe, and Slack.
Webhook Payload Structure
Most webhook providers follow a consistent structure with event metadata and a data object:
{
"id": "evt_123456", // Unique event ID
"event": "user.created", // Event type
"created_at": 1234567890, // Unix timestamp
"data": { // Resource data
"id": "usr_789",
"email": "[email protected]",
"profile": { ... }
}
}
Common Webhook Providers
| Provider | Root Keys | Common Events |
|---|---|---|
| GitHub | action, sender, repository, pull_request | push, pull_request, issues, release |
| Stripe | id, object, type, api_version | payment_intent.succeeded, customer.created |
| Slack | type, event, authed_users, team_id | message, app_mention, reaction_added |
| Shopify | id, topic, shop, order/product | orders/create, products/update |
| Discord | type, d (data), t (type) | MESSAGE_CREATE, GUILD_MEMBER_ADD |
JSON Flattening Algorithm
The flattening process converts nested objects into dot-notation paths:
// Flattening examples:
Input: { data: { user: { email: "[email protected]" } } }
Output: data.user.email: [email protected]
Input: { items: [{ name: "A" }, { name: "B" }] }
Output: items[0].name: A
items[1].name: B
// Recursive traversal:
function flatten(value, prefix, output) {
if (Array.isArray(value)) {
value.forEach((item, i) => flatten(item, `${prefix}[${i}]`, output))
} else if (value && typeof value === "object") {
Object.keys(value).forEach(key =>
flatten(value[key], prefix ? `${prefix}.${key}` : key, output)
)
} else {
output.push(`${prefix}: ${String(value)}`)
}
}
Webhook HTTP Headers
Webhook requests include headers for verification and routing:
| Header | Purpose | Example |
|---|---|---|
| Content-Type | Payload format | application/json |
| X-Hub-Signature | HMAC signature (GitHub) | sha256=abc123... |
| X-Stripe-Signature | Signing header (Stripe) | t=123,v1=abc |
| X-Slack-Signature | Request verification | v0=abc123... |
| X-Event-Key | Event type identifier | pull_request.opened |
Common Use Cases
- Webhook debugging: Inspect actual payload structure during development
- API integration: Understand field paths before writing parser code
- Documentation: Generate field reference docs for team wikis
- Type generation: Create TypeScript interfaces from sample payloads
- Testing: Verify webhook payloads match expected schemas
- Support troubleshooting: Analyze customer webhook delivery issues
Webhook Security Considerations
- Signature verification: Always verify HMAC signatures to confirm sender identity
- HTTPS only: Webhook endpoints must use HTTPS to encrypt payloads in transit
- Replay protection: Check event IDs or timestamps to prevent replay attacks
- Rate limiting: Implement rate limits to handle burst traffic from webhook storms
- Idempotency: Design handlers to safely process duplicate deliveries
Payload Inspection Tips
- Start with root-level keys to identify the event type and structure
- Use flattened paths to quickly locate deeply nested fields
- Compare multiple payloads to identify variable vs constant fields
- Look for timestamp fields to understand event ordering
- Check for nested objects that may contain related resource data
Frequently Asked Questions
- What is a webhook payload?
- A webhook payload is a JSON object sent by a service to notify your application of an event. It contains event metadata (event type, timestamp, ID) and a data object with details about the resource that changed. Common examples include GitHub push events, Stripe payment notifications, and Slack message events.
- How do I flatten nested JSON keys?
- Flattening converts nested paths like data.user.email into readable dot notation. For arrays, bracket notation is used: items[0].name. The flattening process recursively traverses each level, building the full path from root to leaf value. This makes it easy to locate specific fields in large payloads.
- What are common webhook event types?
- Common webhook events include: GitHub (push, pull_request, issues, release), Stripe (payment_intent.succeeded, customer.created, invoice.paid), Slack (message, app_mention, reaction_added), Shopify (orders/create, products/update), and Discord (MESSAGE_CREATE, GUILD_MEMBER_ADD). Each event has a unique payload structure.
- Why flatten webhook payload keys?
- Flattening reveals the complete structure of deeply nested payloads, making it easier to write code that accesses specific fields. Instead of guessing the path to data.user.profile.email, you see the exact flattened key. This is especially useful for documentation, debugging, and generating type definitions.
- How do I validate webhook JSON structure?
- Validate JSON by parsing it with JSON.parse() to check syntax. Then inspect the root-level keys: most webhooks include an 'event' or 'type' field, an 'id' for the event, a 'created_at' timestamp, and a 'data' or 'object' containing the resource. Use pretty printing to verify proper nesting and array structures.
- What is the difference between webhook and API polling?
- Webhooks push events to your endpoint in real-time when something happens, reducing latency and server load. API polling requires periodic requests to check for changes, which introduces delay and consumes rate limits. Webhooks are more efficient for event-driven architectures; polling is simpler for infrequent checks.