Skip to content

Parameter Mapping

Parameter mapping is how data flows between steps in an orchestration. When one step produces output, subsequent steps can reference that output as input -- chaining data through the entire workflow.


The Basics

Every step in an orchestration stores its output in the execution context under the step's name. Subsequent steps reference this output using the ${step_name.field} syntax.

Example

Step 1: "fetch_customer" (API Call)
  Output: { "id": 42, "name": "Jane Smith", "email": "jane@example.com" }

Step 2: "send_welcome" (API Call)
  Parameters:
    recipient_email: ${fetch_customer.email}       → "jane@example.com"
    recipient_name:  ${fetch_customer.name}        → "Jane Smith"

The ${} expression is resolved at runtime, just before the step executes.


Reference Syntax

Step Outputs

Reference any field from a previous step's output:

${step_name.field}
${step_name.nested.field}
${step_name.array[0].field}

Examples:

Expression Resolves To
${decode_vin.response.Make} The "Make" field from the decode_vin step's response
${fetch_list.response.items[0].id} The ID of the first item in the list
${transform.output.total_count} The total_count from a transform step

Input Parameters

Reference the orchestration's input parameters:

${parameters.vin}
${parameters.customer_id}
${parameters.date_range.start}

Context Variables

Reference built-in execution context:

${_context.timestamp}          -- Current UTC timestamp (ISO 8601)
${_context.execution_id}       -- Unique execution ID
${_context.orchestration_id}   -- Orchestration ID
${_context.enterprise_id}      -- Enterprise ID

JSONPath Expressions

For complex data extraction, DIBOP supports JSONPath expressions within the ${} syntax.

Common Patterns

Pattern Description Example
$.field Direct field access ${step.response.name}
$.array[0] First element of an array ${step.response.items[0]}
$.array[-1] Last element of an array ${step.response.items[-1]}
$.array[*].field Extract a field from every array element ${step.response.items[*].name}
$.array[?(@.status=='active')] Filter array elements ${step.response.items[?(@.status=='active')]}
$.object..field Recursive descent (find field at any depth) ${step.response..email}

Example: Extract All Active Vehicle IDs

${fetch_vehicles.response.vehicles[?(@.status=='active')].id}

This returns an array of IDs for all vehicles with status "active".


Static Values

Not every parameter needs to be dynamic. You can use static values alongside dynamic references:

{
  "vin": "${parameters.vin}",
  "format": "json",
  "include_specs": true,
  "api_version": "2.1"
}

In this example, vin is dynamic (from input), while format, include_specs, and api_version are static.


Template Strings

You can embed references within larger strings using the template syntax:

"Vehicle ${decode_vin.response.Make} ${decode_vin.response.Model} (${decode_vin.response.ModelYear})"

Resolves to: "Vehicle Mercedes-Benz C-Class (2024)"

This is useful for:

  • Constructing dynamic URLs: "https://api.example.com/vehicles/${parameters.vin}/details"
  • Building log messages: "Processed ${transform.output.count} records"
  • Formatting display values: "${fetch_customer.name} <${fetch_customer.email}>"

Type Handling

DIBOP attempts to preserve data types through parameter mapping:

Source Type Mapped As
String String
Number Number
Boolean Boolean
Object Object (deep copy)
Array Array (deep copy)
Null Null

When a reference is embedded in a template string, all values are converted to their string representation.

Type Mismatches

If a target step expects a number but receives a string (e.g., "42" instead of 42), DIBOP will attempt to coerce the type. If coercion fails, the step will error with a type mismatch message.


Default Values

You can specify a default value for a reference that might not exist:

${step_name.optional_field ?? "default_value"}

If optional_field is null or undefined, the default value is used instead.

Example: Optional Description

{
  "name": "${fetch_vehicle.response.name}",
  "description": "${fetch_vehicle.response.description ?? 'No description available'}"
}

Working with Arrays

Iterating Over Arrays

When an API call returns an array of records, you may need to process each record individually. Use the For Each modifier on a step to iterate:

Step: "process_vehicle" (API Call)
  For Each: ${fetch_vehicles.response.vehicles}
  Current Item Variable: vehicle
  Parameters:
    vin: ${vehicle.vin}
    stock_number: ${vehicle.stock_number}

This executes the step once for each element in the array.

Array Indexing

Access specific elements by index:

${step.response.items[0]}    -- First element
${step.response.items[1]}    -- Second element
${step.response.items[-1]}   -- Last element

Array Length

Check the number of elements:

${step.response.items.length}

Debugging Parameter Mapping

If a parameter mapping does not resolve as expected:

  1. Check the Execution Trace -- the Execution Trace shows the resolved value for every parameter at every step
  2. Check the step output -- click on a step in the trace to see its full output, then verify the field paths
  3. Check for typos -- field names are case-sensitive (Make is not the same as make)
  4. Check for null values -- if a step failed or was skipped, its output may be null

Use the Test Runner

When building orchestrations, use the Test Run feature frequently. It executes the orchestration and shows you the resolved values at each step, making it easy to spot mapping issues.


Best Practices

  1. Name your steps clearly -- since other steps reference them by name, use descriptive names like fetch_customer rather than step_1
  2. Use defaults for optional fields -- prevent null reference errors by providing defaults with the ?? operator
  3. Keep mappings simple -- if a mapping becomes very complex, consider adding an intermediate Transform step to simplify
  4. Document your mappings -- use the step description field to explain what each mapping does and why

Next Steps