Reshape a webhook payload
Two systems that both call themselves 'integrated' rarely agree on field names, nesting or even date formats. This endpoint sits between them and reshapes the payload one sends into the exact structure the other expects, without either side changing a line of its own code.
Run — free
Runs in your browser. Free, unlimited — your data never leaves this page.
The mismatch that breaks integrations
A payment processor sends amount_cents as an integer; your billing system expects amount as a decimal string nested three levels under totals.charge. A CRM fires a lead.created event with a flat object; your marketing tool wants an array under contacts even when there's only one. These aren't bugs — they're just two teams making different, reasonable decisions independently, and the resulting mismatch is exactly what breaks integrations that looked fine in a demo.
How the transformation runs
Send POST /dev/webhook-transform with the incoming payload and a mapping that describes the target shape — which source fields go where, any renames, type conversions or nested restructuring needed. The task returns a task_id immediately and runs the transformation in the background, so a slow or malformed payload never blocks the request that sent it. The reshaped payload arrives by a signed webhook call to your endpoint or waits behind a signed link valid for 24 hours.
Why this sits outside your application code
Hand-writing a transform function for every partner integration means that function lives inside your application, gets forgotten, and breaks quietly when the source system changes a field months later with no warning. Running the transform as an external, addressable step means the mapping logic is inspectable and testable on its own, separate from the business logic that consumes the result — and separate from whichever team owns the sending system.
Where it fits a wider automation
Teams that receive webhooks from several vendors — a payment processor, a CRM, a support desk — end up needing a small transform for each one before that data can land in one internal event format. Chaining this endpoint in front of an internal queue means new vendors can be onboarded by writing a mapping, not a deployment, and because pricing is a flat per-request fee with no charge on failure, testing a new mapping against real sample payloads costs nothing to get wrong the first few times.
What you can do with it
Payment provider normalization
A marketplace accepts webhooks from several payment providers and transforms each one into a single internal charge event before it reaches the order pipeline.
CRM to marketing automation bridge
A sales tool sends lead events in its own schema, and this endpoint reshapes them into the exact structure a marketing automation platform's API expects.
Legacy system field renaming
An older internal system uses cryptic abbreviated field names, and incoming webhooks are transformed into readable, documented field names before storage.
Multi-tenant partner integrations
A platform with dozens of partner integrations keeps one mapping per partner so onboarding a new one never requires touching shared application code.
FAQ
How do I transform a webhook payload with this API?
POST the incoming payload and a field mapping to /dev/webhook-transform, keep the returned task_id, and receive the reshaped payload by webhook or a signed link valid for 24 hours.
Is the webhook transformer API free?
No, there is no free tier or trial; it costs a flat $0.002 per request, and a failed transform is never charged.
What kind of transformations can it handle?
Field renames, type conversions, nested restructuring, and reshaping between flat and nested formats, based on the mapping you provide with the request.
Does it work with any payload format?
It works with structured JSON payloads, which cover the overwhelming majority of webhook traffic between modern systems.
Can I reuse the same mapping for many payloads?
Yes, most integrations submit the same mapping definition with every incoming payload from a given source, which is exactly how a stable partner integration is meant to work.
Can I transform payloads in bulk?
Yes, submit one async task per payload, or batch several through your own queue, and collect each result by webhook as it completes.
What happens if a field is missing from the source payload?
The transform applies the mapping to whatever fields are actually present; missing source fields simply produce missing target fields rather than a fabricated value.
Is this endpoint live?
Yes, /dev/webhook-transform is live and accepting requests now.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/dev/webhook-transform \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/dev/webhook-transform", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/dev/webhook-transform",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/dev/webhook-transform", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/dev/webhook-transform", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "dev.webhook_transform",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |