The Complete Guide to Webhook Payload Transformation
Third-party webhooks almost never have the payload shape your system expects. Here's a practical guide to transforming webhook payloads — from field renaming to complex restructuring — without writing custom code for every integration.
Jason Warner
March 5, 2026
The Complete Guide to Webhook Payload Transformation
The moment you start integrating more than one or two webhook sources into a real system, you hit the same problem: nobody agrees on payload shape. Stripe uses camelCase and sends amounts in cents. GitHub uses snake_case and has deeply nested objects. Your internal systems were designed by a different team entirely and expect something completely different.
The naive solution is writing a transformation layer in your webhook handler for every integration. It works. It also means you're maintaining custom translation code for every service you integrate with, and the moment any of those services changes their payload format, your code breaks silently.
There's a better approach.
What Payload Transformation Actually Means
At its simplest, transformation is just mapping field names:
incoming: { "amount_cents": 4999 }
→ outgoing: { "totalAmount": 4999 }
But it gets more complex:
- Type coercion: Converting
amount_cents: 4999toamount: 49.99 - Flattening:
data.object.customer.id→customerId - Restructuring: Building a new object shape from fields scattered across a nested payload
- Conditional values: Different output based on the value of an input field
- Multiple destinations: The same event needs to go to three services, each expecting a different shape
The Hard Way: Custom Handler Code
Writing custom transformation code isn't wrong. For a single integration with a stable schema, it's often the right call — it's explicit, testable, and lives close to your business logic.
The problem is scale. When you have six integrations, each with different payload shapes and different downstream systems, you're maintaining six separate transformation layers. When Stripe changes a field name (it happens), you find out when a customer reports a broken flow.
Field Mapping with Bluejay Relay
Bluejay Relay's field mapping UI lets you configure payload transformation visually, per destination, without code. You define which source fields map to which destination keys, and Bluejay Relay generates and applies the transformation at delivery time.
This is how it works in practice:
- Create an Integration in Bluejay Relay and point your webhook source at it
- Add a Destination with your actual endpoint URL
- In the destination settings, open the field mapping editor
- Define your mappings: source path → destination key, with optional transformations
You configure the transformation with a visual field mapper: pick each source field, set the destination key, and optionally apply a conversion. No code, and nothing to write by hand.
Example: Stripe to Internal CRM
Incoming Stripe payment_intent.succeeded:
{
"type": "payment_intent.succeeded",
"data": {
"object": {
"id": "pi_123",
"amount": 4999,
"currency": "usd",
"metadata": {
"user_id": "usr_456"
}
}
}
}
Your internal CRM expects:
{
"event": "payment_completed",
"userId": "usr_456",
"amountCents": 4999,
"currency": "USD",
"stripePaymentId": "pi_123"
}
In Bluejay Relay's mapper, you'd set up four mappings:
data.object.metadata.user_id→userIddata.object.amount→amountCentsdata.object.currency(uppercase transform) →currencydata.object.id→stripePaymentId- Static value
"payment_completed"→event
No code. No deployment. The transformation runs before every delivery.
Per-Destination Mappings
One of Bluejay Relay's more useful architectural features: each destination has its own independent mapping configuration. So if you're sending the same Stripe event to your billing service, your analytics pipeline, and your customer success platform, you can configure completely different transformations for each one.
This eliminates the need for a central "translation hub" in your application code. Each downstream system gets exactly the payload shape it needs, delivered directly.
What Happens When the Schema Changes?
Bluejay Relay monitors incoming payloads for schema changes using SHA-256 fingerprinting. When a new field appears or an existing field disappears, you get a notification and can view a diff in the dashboard.
This is important for transformation because your field mappings reference specific source paths. If Stripe renames data.object.amount to data.object.amount_received in a new API version, your existing mappings will produce null values for that field — silently, until a customer complains.
With schema change alerts, you know about it before it becomes a production incident.
Field mapping and payload transformation are available on every Bluejay Relay tier, including free. View pricing or start free.
// more articles
Keep reading
Reshape any payload without code.
Map and transform incoming webhooks before they reach your endpoint — no code required. Free to start.