Siphondocs
Connector Spec

Transform

Map raw, enriched records to canonical fields with JSONata.

transform maps each raw (and enriched) record to your canonical entity — the shape you actually deliver. The only engine is JSONata, a declarative query/transform language.

transform:
  engine: jsonata
  expression: |
    {
      "externalId": $string(id),
      "DEAL_ID": $string(id),
      "CLIENT_NAME": clientName,
      "CLIENT_EMAIL": _client.email,
      "STAGE": $lookup($stages, $string(stage)),
      "AMOUNT_PAID": _payments.amountPaid,
      "SOURCE_UPDATED_AT_UTC": createdAt
    }

The expression runs against the enriched record — the raw fetch fields plus everything enrich attached (_client, _payments, …). It must produce an object; that object is what gets validated and delivered.

externalId is required

Every transformed record must yield an externalId — the stable per-record key used for idempotent delivery and change detection. It's conventional to also map your typed output columns here (uppercased, by convention).

Lookups

transform.lookups declares named constant tables you can reference from the expression — handy for mapping enum codes to labels:

transform:
  engine: jsonata
  lookups:
    stages: { "0": InProgress, "1": ClosedWon, "2": ClosedLost }
  expression: |
    { "STAGE": $lookup($stages, $string(stage)) }

Null-safety

JSONata returns undefined for missing paths, which serializes to null — good. But functions throw on null. Guard string/number ops on optional fields:

/* $substring(null, ...) throws — guard it */
"NOTE": locationDetails ? $substring(locationDetails, 0, 100) : null

A transform failure quarantines just that record (it doesn't fail the run), and the Run Inspector shows the expression error.

Flatten and dedupe

JSONata makes reshaping enriched arrays easy — e.g. collapse a unit list into a distinct, comma-joined floor string:

(
  $floors := $distinct(_units.floors.floorNumber);
  { "FLOORS": $floors ? $join($map($floors, function($n){ $string($n) }), ", ") : null }
)

Testing a transform

Author transforms against real samples in the Connector Builder test panel, or ship fixture tests in the spec so the mapping is verified with zero network calls.

On this page