Skip to main content
An executor node sends data to an external service and receives data back. The service names its own fields, and your workflow names its own. Mappings are how you move values between the two: a list of source-to-target entries on the node, applied to the request before the call and to the response after it. You need this whenever the shape your workflow carries is not the shape the service accepts — a document that must travel without punctuation, an amount that belongs under a nested object, a score that a later node reads under a short name.

Before you start


  • A provider configuration for the service, and an executor node that references it. See Reference the provider configuration from a workflow node.
  • The field names the service expects. When the service’s OpenAPI document is in the registry, Derive an operation schema returns inputSchema — the operation’s request body — and outputSchema — its success response. Both give you the field names you write as mapping targets and sources.
  • A workflow in draft status. An active workflow is locked, so use Move workflow to draft before you edit a node, then activate it again.
Do not send executorId on a node that calls an operation of an uploaded OpenAPI document. Such a node names the operation with operation_path and operation_method. Flowker fills the executorId in for you, from the provider configuration the node points at, before it validates the workflow. It does this when you create the workflow and when you update it. Connecting your own API walks that whole path. The nodes on this page name http, the generic HTTP connector, which does need an explicit executorId.

Step 1: Know what a mapping can read


Every mapping reads from the workflow context — one JSON object that grows as the execution advances: Address a value by its path from one of those top-level keys:
A mapping source is a plain path. Do not wrap it in ${...} — braces belong to the node’s template fields (body, headers, query, path), and inside a mapping a ${...} string is read as a literal path name that selects nothing.

Step 2: Declare the input mapping


Input mappings live in an inputMapping array inside the executor node’s data object. Each entry moves one value into the outgoing request body. The mapped result is the request body. Write each target exactly as the service expects to receive it: there is no wrapper object and no prefix to add.
With a trigger payload of {"transactionId":"txn-98765","amount":1500.00,"customer":{"document":"12345678900"}}, the service receives:

When a source selects nothing

A source path that is absent from the context is not an error. The target is still written, with the value null, and the request goes out. Set required: true when the node must not call the service without a value. Flowker then checks every source path on that node before it builds the request, and fails the step when any of them is absent — the execution stops with FLK-0504 and the step reports input transformation failed.
required applies to the node, not to the one entry that carries it. If any entry in a node’s inputMapping sets required: true, every source path in that array must resolve. To keep some fields optional, leave required off across the whole node.
Give each target one entry. When two entries write the same target, the last one wins.

Step 3: Decide what builds the request body


A node has three sources for a request body. Only data.body is exclusive: when present, it is the whole body. Without it, Flowker composes the body from the other two sources, with the mapping overlay written over the config literals:
1

data.body

An explicit body template wins outright. Flowker resolves its ${...} references against the workflow context and sends the result. While data.body is present, inputMapping, transforms, and config contribute nothing to the body.Every ${...} reference here must resolve. One that does not fails the node with FLK-0143, before any call is made — the opposite of a mapping source, which resolves to null. Use data.body when a missing value must stop the workflow, and a mapping when the request must go out regardless.
2

inputMapping or transforms

Otherwise Flowker builds an overlay from inputMapping. When inputMapping is empty it builds the overlay from transforms instead. The two are mutually exclusive: a node with at least one inputMapping entry never runs its transforms on the input.
3

config literals

Literal values in data.config seed the body. With an overlay present, the literals are the base and the overlay wins on any key both set — so one node can combine fixed values with mapped ones. With no overlay, the literals are the body on their own.
Transport never becomes body content. Before config can seed the body, Flowker removes these names from it: method, path, url, endpointName, query, headers, auth, retry, timeout, timeout_seconds, request_format, success_status_codes, allowedHosts, and allowedPrivateHosts. A node that keeps transport in config by mistake therefore sends none of it to the destination, and an auth block placed there can never ship as request content. The node reads its own transport from the top of its data object — path, endpointName, method, headers, query, auth, timeout_seconds, retry, success_status_codes, and request_format. The outbound host allow-lists are not among them: you set allowedHosts and allowedPrivateHosts on the provider configuration, where each applies to every node that calls through it.
The literals and the mapped values merge, and nesting merges with nesting:

Step 4: Reshape a value on its way through


When the service needs a value in a different form, attach a transformation to the mapping entry. It applies to the value after it lands on the target. These five are the whole set. A type outside it is rejected when you save the workflow, with FLK-0140. Two rules to write them by:
  • They act on text. A value that is not text reaches the target unchanged.
  • prefix and suffix each need at least one character, and a single space counts. characters needs at least one character that is not a space, a tab, or a line break. A value that does not meet this fails the step at run time with FLK-0504.
From {"customer":{"document":"123.456.789-00","name":"ada lovelace"},"transactionId":"txn-98765"}, the node sends:

Whole-document transforms

For work that entry-by-entry mapping does not express — combining two fields, choosing the first value that is present, filling a default — declare a transforms array instead. Each operation reads the whole workflow context and writes the whole overlay. Flowker accepts shift (move or rename), concat (join values), coalesce (first value present), default (fill a missing key), extract (lift a subtree to the root), delete (drop a key), timestamp, uuid, and pass. The five transformation types above are available here too; as operations they take the target path in the spec as path.
The node sends:
An operation may set require: true to demand that every path its spec names exists, the same way required works on a mapping entry.
transforms runs only when the node has no inputMapping. Use one or the other in a given node, never both.

Step 5: Read the response back out


Output mappings extract fields from the response and store them in the workflow context under the node’s id, so later nodes read short, stable names. Declare them in an outputMapping array in the node’s data, with the same four entry fields as an input mapping. An output source is a path into the response envelope, not into the response body: Response fields therefore sit under body:
On a node with the id score-transaction, that stores:
Downstream nodes then read ${score-transaction.score} and ${score-transaction.httpStatus}. A node that declares no outputMapping stores the whole envelope under its id instead, and downstream nodes read the envelope path directly — ${score-transaction.body.score}. Add an output mapping when you want the shorter name; skip it when the envelope path is clear enough. An output source that selects nothing behaves like an input one: the target is stored as null unless an entry on that node sets required: true.

Step 6: Check the mapping before you call the service


Preview an executor request assembles the request a node would send and returns it to you. It runs the same mapping, transformation, and authentication assembly an execution runs, and it never opens a connection to the service — so you can iterate on a mapping without a single call leaving your deployment. No credential appears anywhere in what it returns, including the curl. Send the node, the provider configuration it targets, and a sample payload. The provider configuration goes in the request itself, so the preview depends on nothing but what you send:
Your sampleInput becomes the trigger payload, so the mapping sources read it as workflow.* — exactly as they will at run time. The response is the assembled request:
Each transformation resolved: the punctuation is gone from the document, the name is uppercase, and the reference carries its prefix — and no call reached the service. Read it in this order:
1

Check the URL

It is the provider configuration’s base URL plus the node’s path. A path you did not expect is a node field to fix, not a mapping.
2

Check the body against the field names the service expects

Every target should appear where the service wants it. A field carrying null is a source path that selects nothing.
3

Check `unresolved`

It lists the ${...} references in the node’s template fields that your sample payload did not resolve. They are left literal in the rendered request. An empty array means every reference found a value.
To check a node’s fixed fields against the catalog executor’s schema as well, call Validate a node configuration with the node’s configuration in config and, in mappedTargets, the target paths your inputMapping supplies. Flowker counts those as satisfied, so a node that maps a required field from the trigger passes the check.

What goes wrong


See the Flowker error list for every code.

What’s next


Integration guide

Create the provider configuration a node calls through, and set its authentication.

Configuring a webhook trigger

Choose the payload contract that fills the workflow namespace your mappings read.