JSONata Playground
Test and debug JSONata expressions with live evaluation. Paste a JSON payload and write expressions to transform it.
What is JSONata?
JSONata is a small expression language for querying and reshaping JSON. An expression such as data.object.customer_details.email walks down the document and returns the value it finds. The same expression can also do arithmetic, join strings, filter arrays, and build new objects, so one line often replaces a function full of property checks.
The playground above evaluates your expression against the JSON on the left on every keystroke. The examples below use this Stripe-style event:
{
"type": "checkout.session.completed",
"data": {
"object": {
"amount_total": 4999,
"currency": "usd",
"customer_details": { "email": "ada@example.com", "name": "Ada Lovelace" },
"metadata": { "plan": "pro" }
}
}
}JSONata cheat sheet
| Syntax | What it does |
|---|---|
a.b.c | Walk into nested objects. Missing paths return nothing instead of an error. |
items.name | Map over an array: returns the name of every item. |
items[0] | Pick an array element by index. Negative indexes count from the end. |
items[price > 10] | Filter an array with a predicate. |
"a" & b | Concatenate strings. Numbers are converted for you. |
{ "k": a.b } | Build a new object. |
cond ? x : y | Conditional (ternary) expression. |
$sum() $count() $uppercase() | Built-in functions for numbers, arrays, and strings. |
`X-Header-Name` | Backticks quote field names that contain dashes or spaces. |
Worked examples
Read a nested field
data.object.customer_details.email→ "ada@example.com"Convert cents to dollars
data.object.amount_total / 100→ 49.99Build a message string
"New " & data.object.metadata.plan & " signup: " & data.object.customer_details.name→ "New pro signup: Ada Lovelace"Reshape the payload for your own API
{
"email": data.object.customer_details.email,
"amount": data.object.amount_total / 100,
"currency": $uppercase(data.object.currency)
}→ {"email":"ada@example.com","amount":49.99,"currency":"USD"}Fall back to a default when a field is missing
data.object.metadata.coupon ? data.object.metadata.coupon : "none"→ "none"These use a GitHub push event with two commits:
Collect every commit message
commits.message→ ["Fix retry backoff","Add retry tests"]Filter commits by author
commits[author.name = "Grace"].id→ "d4e5f6"Get the branch name from the ref
$substringAfter(ref, "refs/heads/")→ "main"Turn a push into a Slack message
{ "text": pusher.name & " pushed " & $count(commits) & " commits to " & repository.full_name }→ {"text":"octocat pushed 2 commits to acme/api"}And a Shopify order with two line items, whose prices arrive as strings:
Compute the order total
$sum(line_items.($number(price) * quantity))→ 248Map line items to a smaller shape
line_items.{ "sku": sku, "qty": quantity }→ [{"sku":"TR-42","qty":2},{"sku":"WS-01","qty":2}]Common JSONata mistakes
- Wrong case.
data.object.Customer_details.emailreturns nothing, because paths are case-sensitive and JSONata does not report missing fields. - Comparing a string to a number. Shopify sends
"total_price": "248.00", sototal_price > 200fails with a type error. Use$number(total_price) > 200. - Single results lose their array. With one commit,
commits.messagereturns"Only commit"butcommits[].messagereturns["Only commit"]. - Dashes in field names. Write
headers.`X-GitHub-Event`, with backticks, or the dash is read as subtraction. - Equality uses one equals sign. JSONata compares with
=and!=, not==.
Run JSONata on live webhooks
Once an expression works here, you can attach it to a Hookbase route and every incoming webhook is transformed before delivery. If a transform breaks, you can replay the failed events after fixing it. See payload transforms or read the transforms guide.
Frequently asked questions
What is JSONata used for?+
JSONata is a query and transformation language for JSON. You use it to pick fields out of a document, compute new values, filter arrays, and build a new JSON shape, all in one expression. For webhooks it is a common way to turn a provider payload into the shape your API, Slack, or database expects.
Is this JSONata playground free?+
Yes. The playground runs entirely in your browser, needs no account, and does not send your payload anywhere. Paste any JSON, write an expression, and the output updates as you type.
Why does my JSONata expression return nothing?+
JSONata does not throw when a path is missing. It returns undefined, which the playground shows as an empty result. The usual causes are a typo, wrong letter case (paths are case-sensitive), or a field that is nested one level deeper than you think.
How do I get an array when only one item matches?+
JSONata unwraps a single-item result to a plain value. Add empty square brackets to the step you want kept as an array, for example commits[].message instead of commits.message.
Can I use JSONata to transform webhooks in production?+
Yes. Hookbase runs JSONata transforms on live webhook traffic: each event is transformed before it is delivered to a destination, and the payload is the root of the expression, exactly as in this playground. Hookbase also supports Liquid, XSLT, and JavaScript transforms.
Want more? Try JSONata transforms in Hookbase
Get started free with no credit card required.