Transformations

Send your system the payload it actually wants.

Providers send what suits them: deep nesting, fields you never use, a customer's email address in a place it should not travel. A transformation is a small JSON rule on a forward destination that shapes every delivery into what your code expects. What the vault stored stays exactly as it arrived.

Rules, not scripts

A rule is a condition and an ordered list of typed steps. There is no code to host, no runtime to patch and nothing that can loop, so a rule costs the same on every delivery and the visual editor, the API and a model writing the document all produce exactly the same thing.

Say what to keep, the rest is gone

Each step does one job. Keep only the fields you need, rename the ones your code calls something else, redact what should never leave the vault, set a header your receiver checks, and write a summary line from placeholders. A when clause decides which webhooks the rule touches; the others pass through unchanged.

  • keep, remove, rename, move, set, default, redact, template, parseJson, toString and compute
  • Paths into the JSON body, the headers and the query string, arrays included
  • Conditions with equals, startsWith, contains, exists, numeric comparisons and safe regular expressions
  • Up to 20 rules per destination, run in order, each switched on or off on its own
Every step and bound →
invoices only, flattened✓ valid
{
  "version": 1,
  "when": { "all": [{ "path": "body.type",
             "op": "startsWith", "value": "invoice." }] },
  "steps": [
    { "op": "keep",   "paths": ["body.id", "body.type", "body.data.object"] },
    { "op": "rename", "from": "body.data.object.id", "to": "body.invoiceId" },
    { "op": "redact", "paths": ["body.data.object.customer_email"] },
    { "op": "set",    "path": "headers.X-Relayed-By", "value": "webhookvault" }
  ]
}

Work things out, without guessing

compute is the one step that calculates: the total of a line-item array, cents turned into a currency amount, an idempotency key hashed from a reference. It calls named functions from a fixed table, so there are no operators and no surprises.

A missing field is absent, never zero. Arithmetic on a value the sender left out produces nothing rather than a plausible wrong number, and the target is left as it was. In a payment payload that difference matters.

  • Text, numbers, collections, time, encoding and fallbacks
  • sum over body.items[*].amount adds every line
  • Ambiguous numbers like "1,234" are never guessed at
stripe · what your endpoint receives
# the sender's amount, in cents
"amount_due": 4900

# one compute step
{ "op": "compute", "path": "body.total",
  "fn": "round", "args": [{ "fn": "div",
  "args": ["body.amount_due", 100] }, 2] }

# delivered
"total": 49.00

Built against your own traffic

The editor lives on the endpoint page. Pick a request the vault has already captured as the sample, click a value in its tree to insert the path, build the pipeline as cards and watch the preview change as you type. Preview the whole set to see what the next delivery will really look like.

  • Every save is a version: read it, compare it line by line, restore it
  • View as JSON to copy, share or hand the document to a model
  • The Deliveries tab records what each rule and version did, next to exactly what was sent
  • Replays run through the rules as they are now, so a corrected rule applies to anything you replay
attempt 1 · transformations✓ 200 OK
# what the rules did on this delivery
strip credentials      v3  applied
invoices only, flat    v7  applied
refund summary         v2  not matched

# the stored capture: unchanged
# the delivery: shaped, sent, recorded

A rule never costs you a delivery

Transformations sit in the delivery path, so they are built to fail open. A step that cannot apply does nothing and says why on the attempt; the webhook still reaches you. A rule that fails on five deliveries in a row is switched off on its own, so a broken rule cannot quietly tax every webhook after it.

  • Switch-offs land in the audit log and on the transformation alert
  • Bounded by design: 64 steps, 32 KB per document, linear-time regular expressions
  • Body steps skip non-JSON bodies; header and query steps still apply
Alerts for every failure →
for models · llms-transformations.txt
# the full grammar, every op, six examples,
# the exact API calls: one plain text file
GET  /llms-transformations.txt

# the loop a model follows
write the rule
preview it against a real sampleRequestId
read every step note, adjust
save

Questions

Transformation questions, answered

What people ask before they put a rule between a provider and their code.

Does a transformation change what WebhookVault stores?

No. A rule shapes only the delivery to your forward destination. The captured request stays exactly as it arrived, so you can always see what the sender really sent, and replay it through a different rule later.

What happens when a rule cannot apply to a webhook?

The delivery still goes out. A step whose path is missing does nothing, a body that is not JSON skips the body steps, and the attempt records a note saying so. A rule that fails on five deliveries in a row is switched off, written to the audit log and announced on the transformation alert, so the rest of the set keeps working.

Can a model write the rules for me?

Yes. The whole grammar, every step and worked examples are published as one plain text file written for models, and the editor's Ask an LLM button copies the spec, a redacted sample and your intent in one go. Preview the result against a real captured request before you save it.

Which plans include transformations?

Rules apply to deliveries on Pro and Team. On Solo you can already build a rule and preview it through the API against your own traffic, so you know it works before you upgrade.

Shape every delivery.

Transformations apply on Pro and Team. Build and preview a rule from Solo, against your own traffic.