Webhook Payload Transformation: A Complete Guide
Learn how to transform webhook payloads on the fly using Hookbase's powerful transformation engine. Support for JSONata, JavaScript, Liquid templates, and XSLT.
Why Transform Webhook Payloads?
When integrating webhooks between services, the payload format rarely matches what your destination expects. A Stripe webhook doesn't look like a Slack message. A GitHub event isn't formatted for your CRM. Instead of writing backend code to transform every payload, Hookbase lets you transform webhooks on the fly.
Four Powerful Transform Engines
Hookbase supports four transformation languages, each suited for different use cases.
1. JSONata - Query and Transform JSON
JSONata is a lightweight query and transformation language for JSON data. It's perfect for restructuring payloads without writing code.
// Extract and reshape Stripe payment data
{
"customer": data.object.customer,
"amount": data.object.amount / 100,
"currency": $uppercase(data.object.currency),
"status": type = "payment_intent.succeeded" ? "paid" : "pending"
}
Best for: Simple restructuring, field extraction, conditional logic.
2. JavaScript - Full Programmatic Control
When you need loops, complex logic, or custom functions, JavaScript gives you full control in a secure sandbox.
// Flatten nested objects for analytics
function flatten(obj, prefix = '') {
return Object.keys(obj).reduce((acc, key) => {
const pre = prefix ? prefix + '.' : '';
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
Object.assign(acc, flatten(obj[key], pre + key));
} else {
acc[pre + key] = obj[key];
}
return acc;
}, {});
}
return flatten(payload);
Best for: Complex logic, loops, string manipulation, calculations.
3. Liquid - Template-Based Transforms
Liquid templates are ideal when you're generating formatted text or HTML, like Slack messages or email bodies.
🔔 *New Order Received*
*Order ID:* {{ payload.id }}
*Customer:* {{ payload.customer.email }}
*Total:* {{ payload.total | divided_by: 100 | prepend: "$" }}
*Items:*
{% for item in payload.items %}
- {{ item.name }} (x{{ item.quantity }})
{% endfor %}
Best for: Notification messages, formatted text, email templates.
4. XSLT - XML Transformations
For legacy systems that speak XML, XSLT transforms let you convert between JSON and XML or transform XML payloads.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<order>
<id><xsl:value-of select="//order_id"/></id>
<total><xsl:value-of select="//amount"/></total>
</order>
</xsl:template>
</xsl:stylesheet>
Best for: XML integrations, SOAP services, enterprise systems.
Real-World Examples
Stripe to Slack
Transform a Stripe payment webhook into a Slack notification:
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "💰 *Payment Received*\n" &
"*Amount:* $" & (data.object.amount / 100) & "\n" &
"*Customer:* " & data.object.customer_email
}
}
]
}
GitHub PR to Discord
Notify your team about pull requests:
{
"content": "📝 **" & action & "** PR #" & pull_request.number,
"embeds": [{
"title": pull_request.title,
"url": pull_request.html_url,
"author": { "name": pull_request.user.login },
"color": action = "opened" ? 5763719 : 15105570
}]
}
Mask Sensitive Data
Remove or mask sensitive fields before forwarding:
const sensitiveFields = ['password', 'ssn', 'credit_card', 'api_key'];
function maskSensitive(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
return Object.keys(obj).reduce((acc, key) => {
if (sensitiveFields.includes(key.toLowerCase())) {
acc[key] = '***REDACTED***';
} else if (typeof obj[key] === 'object') {
acc[key] = maskSensitive(obj[key]);
} else {
acc[key] = obj[key];
}
return acc;
}, Array.isArray(obj) ? [] : {});
}
return maskSensitive(payload);
Built-In Template Library
Don't start from scratch. Hookbase includes 15+ pre-built templates for common integrations:
- Stripe → Slack: Payment notifications
- GitHub → Discord: PR and issue alerts
- Shopify → Inventory systems: Order processing
- Generic → Any: Flatten objects, mask fields, add metadata
Security Built In
Transforms run in a secure sandbox with:
- 5-second timeout: Prevents infinite loops
- No network access: JavaScript can't make HTTP requests
- No file system: Templates can't read or write files
- Safe built-ins only: Math, Date, JSON:nothing dangerous
Context Variables
Every transform has access to useful context:
| Variable | Description |
|----------|-------------|
| payload | The webhook payload (parsed JSON/XML) |
| headers | Original request headers |
| eventId | Unique event identifier |
| sourceId | Source that received the webhook |
Test Before You Deploy
Use the transform tester to validate your code before saving:
- Paste a sample payload
- Write your transform
- See the output instantly
- Fix errors before they affect production
Getting Started
- Create a transform in your Hookbase dashboard
- Choose your engine (JSONata for most cases)
- Write and test your transformation code
- Attach to a route to start transforming webhooks
Transforms are available on all paid plans. Start transforming your webhooks today.