Snippet references and arguments

Prev Next

Use a snippet to call a downstream system or API, or to turn a repeated part of your journey into one reusable definition. You can apply the same template to many steps while giving each use its own endpoint, identity context, selector, text or other arguments.

For example, one account-risk integration can serve both login and payment steps. One HTML template can add a notice to several pages. One header template can label requests differently for each origin route. The Marketplace packages demonstrate these same patterns: Ekata provides API operations, Dynamic Messaging expands into several HTML injections, and tag-only profiling creates an entire step.

Start with Making your own integrations for a complete API example. This reference explains how scopes, arguments, placement and shared updates work, then shows a reusable header and HTML example.

File, template and operation names

These names have different purposes:

Name Example Purpose
File path customer_account_risk.snippet Loads the snippet file through the journey's snippets list
Template name customer_account_risk Selects the definition inside that file
Operation name account_risk_lookup Identifies this use within the step's model operations
snippets:
  - customer_account_risk.snippet
# Inside the selected step:
models:
  - name: account_risk_lookup
    apply_template:
      name: customer_account_risk
      arguments:
        - name: api_base
          value: https://risk.example.invalid
        - name: auth_secret
          value: internal_risk_token
        - name: identity_context
          value: ACCOUNT

The models block above belongs inside a step, not at the journey root. The complete example journey in Making your own integrations shows its placement.

Keep template names unique across imported files and paths relative to the journey. Removing an import breaks references to its templates.

Two stages of substitution

At build time, snippet arguments become journey configuration. At runtime, event attributes and named secrets supply the values used by the operation.

In {{api_base}}, api_base is a snippet argument. It is replaced while the journey is built. In {{ identity['ACCOUNT'].customer_token.customer_token }}, the identity value comes from the event at runtime.

The custom example deliberately nests the argument {{identity_context}} inside the runtime attribute expression. After expansion, it becomes an ordinary runtime reference to the selected context. Likewise, {{ secret({{auth_secret}}) }} becomes {{ secret(internal_risk_token) }}.

An attribute path passed as an argument is just text unless the template places it in an attribute-aware field or runtime expression. This distinction matters when adapting requests: a literal card.bin_number in a URL does not read the event's BIN.

Encode for the outgoing request

Call URL percent-encodes runtime substitutions in its URL. Pass original attribute values rather than pre-encoded strings. The runtime request-body template uses the declared content type: with Content-Type: application/json, interpolated string values are JSON-escaped. Form bodies use field rules with application/x-www-form-urlencoded.

This runtime handling does not make arbitrary build-time text substitutions safe. If a snippet argument is inserted directly into JSON or JavaScript source, it becomes part of that source before runtime escaping. Prefer runtime attribute expressions for event data and use typed template parameters for reusable assets. Test quotes, ampersands, plus signs and empty values against the actual request format.

Choose a scope

A scope describes the kind of journey position the template can fill. It does not select a step or automatically make the operation run on every event.

Scope Template shape Snippets → Add behavior
model/operation List of model/action operations Choose an API or proxy step; opens Workflows → Models. This is the usual scope for a downstream API call.
html/operation List of HTML mapping rules Choose a compatible proxy step; adds to its response HTML mappings and opens Data Mappings.
header/operation List of header mapping rules Choose a proxy step; adds to its request header mappings and opens Data Mappings.
step One complete step object Creates a new step immediately; opens Customizations for its arguments.
url_query/operation List of query mapping rules The schema recognizes the scope, but the Add control does not place it automatically. Use manual YAML and validate it.

For HTML placement, the picker excludes responses already parsed as JSON, XML, protobuf, JWT and other incompatible formats. A missing response mapping can be created as HTML. An API step does not provide an HTML response to rewrite.

The mapping editor can also offer imported snippets at an existing HTML or header mapping. In that case, the mapping's location determines request versus response. This differs from the defaults chosen by Snippets → Add.

Additional loader scopes

Advanced YAML authoring can target the following scopes accepted by the journey loader. They are not all represented in the visual editor's scope type or automatic placement controls. Validate the exact position and template shape before using them.

Scope family Expected template shape
xml/operation, json/operation, multipart_body/operation, split_by_token/operation List of path or field mapping rules
body/operation, url_scheme/operation, url_host/operation, url_path/operation, url_fragment/operation One parsing-rule object
proxy_action/operation, decision_strategy/operation One model/action configuration object

Declare scope before template in the YAML file. The loader uses it to parse the template. A scope mismatch at the reference is an error. A whole-step template is one object; it is not a list of several steps.

Design the arguments

Declare what varies between uses. Keep the common request, mapping or injection logic in the template.

Argument type Editor control / purpose
string Text input; endpoint, text or another scalar setting
xpath Text input for a path; it is not an automatic element picker
attribute Attribute selector; the template must use the selected path in an attribute-aware field or expression
context Context selector; also specify the context family, such as IdentityContext or AddressContext
boolean Switch; use YAML true / false
integer Integer input
list Single selection from the declared options
string_or_string_array A string or comma-separated values represented as a string list
url_glob_regex URL glob input, converted to a regular expression during expansion

Use display_name for the label and documentation for helper text. Supply a default where appropriate. Every declared argument without a default needs a value. An explicitly supplied empty value does not mean “use the default”.

The editor commonly writes defaults into each reference when you add a template. Changing a default later does not override values already saved in those references. Review each use when changing defaults or adding required arguments.

Some fields are typed before expansion. For example, use timeout: 1000 in a call_url; a quoted {{timeout_ms}} in that field is rejected even when the declared argument type is integer.

Journey variables can supply arguments using {{var.api_base}}. An exact variable reference can retain a number, boolean or list type; embedding it in a longer string produces text. Undefined variables fail validation.

Reuse a header across steps

This complete file sets a request header for your origin service. The route label varies at each use:

api_version: darwinium.com/api/snippet/v1
snippets:
  - name: customer_route_header
    display_name: Set customer route header
    scope: header/operation
    mode: Merge
    arguments:
      - name: route
        display_name: Route name
        type: string
        default: account
    validation: |
      return item !== undefined && item.name === 'X-Customer-Route';
    template:
      - name: X-Customer-Route
        inject:
          mode: OverwriteOrInsertContent
          content: "{{route}}"

Save it as customer_shared.snippet, import it, then add Set customer route header to your login and payment steps. Set route to sign-in on one and payment on the other. Both steps reference the same definition; their argument values remain independent.

The literal header name gives the placement helper a suitable destination. The validation function further restricts where the editor offers the snippet. It receives stepDef, path and item; it is an editor eligibility check, not a runtime condition or security boundary. Put event conditions in the generated journey operations.

Reuse HTML and supporting files

Append an HTML definition to the same file's snippets list:

  - name: customer_notice
    display_name: Add customer notice
    scope: html/operation
    mode: Merge
    arguments:
      - name: message
        display_name: Notice text
        type: string
        default: Check the details before continuing.
    validation: |
      return true;
    template:
      - name: "{{name}}"
        inject:
          mode: AfterContent
          template_from_file: customer-notice.html
          template_parameters:
            - key: message
              value: "{{message}}"
              data_type: String

Create customer-notice.html beside the snippet:

<p class="customer-notice" role="note">{{ message }}</p>

Import the file once, then add Add customer notice to each HTML page step. Set a different message at each use. {{name}} receives the surrounding mapping rule's name, such as /html/body; do not declare it as a separate selector argument. In this example, AfterContent places the notice after the selected element's existing content.

Supporting-file paths in the snippet resolve relative to the snippet file's directory. Keep the HTML, JavaScript, WebAssembly or other referenced assets with the definition when moving it. template_parameters passes typed values to a templated asset; the profiling packages use this pattern extensively for boolean flags, numeric limits and script settings.

The Dynamic Messaging package demonstrates a larger version: one reference expands into a script-loader injection in the document head and a message injection in the body. A template can generate several compatible operations at one reference.

Reuse a complete step

For scope: step, the template describes a complete configurable step. The tag-only profiling package uses this to create a serving endpoint with a host, listen URL, assets and arguments. Add it from the Snippets tab, then configure it under Customizations.

Adding the template again creates another step with its own name and arguments. It does not modify every existing step or provide a way to replace an existing step in place. Review URL matching so the new endpoint does not overlap unintentionally with another step.

Basic authentication with named secrets

The supplied Jira and Twilio headers build Basic authentication from a quoted user:password string. Inserting a nested secret expression into that string is not equivalent to evaluating the secret.

For an adapted local template, use a runtime expression that concatenates the account value and the secret before encoding. For example:

Basic {{ ('service@customer.com:' ~ secret(jira_api_token)) | b64encode }}

Use your Jira API account email, or the Twilio Account SID for the corresponding integration. Validate the expanded header without exposing the credential in logs. Base64 encoding is the HTTP authentication format; it does not protect a credential stored in source.

Change and validate a shared snippet

Changes to an imported file affect its references when their journeys are rebuilt and deployed. Review affected arguments, dependencies, assets and output attributes. Update every intended deployment; saving a workspace file does not change an already deployed journey.

The file's mode: Merge / Create metadata does not provide a Marketplace upgrade or a customization merge. Preserve custom copies before reinstalling. Removing a file from the journey's Snippets list removes the import, not the workspace file; references still using it will fail to load.

Give each template a unique name across all imports. Prefer a customer-specific prefix for your own library. Before deployment, check a reference using defaults, one with overridden arguments, missing input, and every step or target affected by a shared change.