Skip to Content
MappingsJSONata basics

JSONata basics

JSONata  is a JSON query and transformation language. Mappings are pure JSONata expressions: input is the source row, output is the destination payload.

The mental model

  • The whole expression is a single value — usually an object.
  • Bare names are field lookups on the current context ($).
  • . navigates into nested values; [] filters or maps arrays.
  • $ prefixes a built-in function ($lowercase, $string, …).

Patterns you’ll use constantly

Renaming a field

{ "title": name }

Optional / fallback values

{ "vendor": manufacturer ? manufacturer : "Unknown" }

Mapping an array of children

{ "variants": variants.{ "sku": sku, "price": $string(price) } }

The variants.{ … } form maps every element of variants through the template, returning an array.

Filtering an array

images[role = "main"].url

Returns the URLs of every image whose role is "main".

Concatenating strings

{ "handle": $lowercase(name & "-" & sku) }

Conditionals on the whole record

status = "enabled" ? { "title": name, "status": "ACTIVE" } : { "title": name, "status": "ARCHIVED" }

Built-in Graftport helpers

Alongside JSONata’s own functions, every mapping has a small set of Graftport helpers in scope. They exist because each one is easy to get subtly wrong by hand, and a mapping that hand-rolls them is longer and harder to review for no benefit.

$normCountry(value)

Turns whatever the source calls a country into the two-letter code the destination expects. It understands local spellings and common misspellings (“Danmark”, “Deutschland”, “Holland”), passes real codes through, and returns nothing for a value it can’t resolve — so one unrecognisable country never sinks the rest of an address.

{ "country": $normCountry(Country) }

Reach for this instead of writing your own country list. A mapping that opens with a 200-line table of country names and codes is doing by hand what one call already does.

$money(amount, currency)

Builds a complete price value, rounded to two decimals, in the shape the destination requires.

{ "priceSet": $money($net, $currency) }

$giftcode(code)

Derives the gift-card code a legacy card converts to. Long legacy codes share prefixes and can’t simply be trimmed, so this derives a fixed 16-character code instead. It always returns the same code for the same input — which is what lets a customer’s printed card keep working — so never substitute your own version.

{ "code": $giftcode(GiftCardCode) }

Keep reference data out of the mapping

A mapping is a transformation, not a database. A handful of inline translations (three order statuses, a couple of product types) is fine and reads well. A long literal table of values is not: nobody can review it, and it gets copied into the next mapping that needs the same data. If you’re pasting a large table into a mapping, ask engineering whether it belongs in a helper or a lookup instead.

Escape hatches

If JSONata genuinely can’t express what you need, that’s a signal to talk to engineering — most “I need a loop with state” cases turn out to be a missing template helper, not a language limit.

Testing in the editor

The mapping editor evaluates as you type: step to a real record with the Row 1 of 5 control in the Preview header and watch the output change. Use real records from a recent extract — synthetic samples lie.

Last updated on