Making your own integrations

Prev Next

Create a snippet when you want to call a downstream service from a journey, or package configuration that you reuse across several steps. A .snippet file holds the shared definition; each use supplies arguments for that particular step.

For example, you can call your account-risk API during login and again before a payment, send a selected event to an internal case-management service, or reuse the same profiling injection across registration, login and checkout pages. Changing the shared definition updates its references when you rebuild and deploy the affected journeys.

Start from the closest pattern

Your requirement A Marketplace example to inspect What to reuse
Verify or enrich an event with a downstream API Turnstile, Ekata, AtData, Deduce or Google Geocoding model/operation, call_url, request fields and response-to-attribute mappings
Trigger an action in another system Jira or Twilio A conditional API call and a mapped response; review the adaptations described in those guides
Repeat HTML or JavaScript across pages Profiling, reCAPTCHA or Dynamic Messaging html/operation, injection targets and per-use arguments
Apply a standard header rule The profiling package's no-cache request header header/operation and a fixed header name
Create a complete configurable endpoint Tag-only profiling or the split-delivery deferred step step, with host, URL and behavior controlled by arguments

Open an installed .snippet file in Explorer to see its definitions. A file can hold several templates: the reCAPTCHA package, for example, separates widget placement, widget code and verification. Keep a custom copy under your own filename and use unique template names so a later Marketplace installation cannot overwrite your work.

The walkthrough below builds a complete downstream API integration. For reusable HTML and headers, see Snippet references and arguments.

Define the API contract

The example sends a GET request to:

https://risk.example.invalid/v1/account-risk?account=acct-123

The request uses a Bearer credential from the named secret internal_risk_token. The example response is:

{"score": 72, "status": "review"}

Replace the example hostname with your API. The API must be reachable from the deployment target; a private hostname needs an appropriate network path. Keep the request within the latency budget for the protected flow.

Create the file

Create customer_account_risk.snippet in your workspace with the following complete definition:

api_version: darwinium.com/api/snippet/v1
snippets:
  - name: customer_account_risk
    display_name: Customer account risk lookup
    scope: model/operation
    mode: Merge
    arguments:
      - name: api_base
        display_name: API base URL (without trailing slash)
        type: string
      - name: auth_secret
        display_name: Darwinium secret name
        type: string
        default: internal_risk_token
      - name: identity_context
        display_name: Identity context
        type: context
        context: IdentityContext
        default: ACCOUNT
    validation: |
      return true;
    template:
      - condition: >-
          identity['{{identity_context}}'].customer_token.customer_token != null
          AND identity['{{identity_context}}'].customer_token.customer_token != ""
        dependencies:
          - LOCAL.REQUEST
        call_url:
          url: "{{api_base}}/v1/account-risk?account={{ identity['{{identity_context}}'].customer_token.customer_token }}"
          method: GET
          timeout: 1000
          request:
            header_rules:
              - name: Authorization
                template: "Bearer {{ secret({{auth_secret}}) }}"
              - name: Accept
                content: application/json
          response:
            body_rule:
              jsonpath:
                - name: $.score
                  extract_to_attribute: custom.general_purpose['account_risk_score']
                - name: $.status
                  extract_to_attribute: custom.general_purpose['account_risk_status']

The template declares api_base, auth_secret and identity_context arguments. It runs only when the selected account token is present and waits for LOCAL.REQUEST, so request-body mappings are available. The timeout is a numeric literal in milliseconds. Call URL percent-encodes values substituted into the URL, so the account identifier should remain unencoded in its source attribute.

Add it to a journey

  1. Open the journey in Explorer and use Snippets → Add from file to import the file.
  2. Add Customer account risk lookup to the step where the account identifier is mapped.
  3. Set API base URL without a trailing slash, Darwinium secret name to internal_risk_token, and Identity context to the context containing the account identifier.
  4. Map the named secret on the deployment target. Save and validate the journey.
  5. Add a dependent rule or decision that consumes the returned score and status. Define the outcome when the lookup is skipped, unavailable or returns an unusable response.

For a complete example, save the following as marketplace-demo.journey.yaml beside the snippet:

api_version: darwinium.com/api/journey/v1
journey_name: market_demo
cookie_values: []
snippets:
  - customer_account_risk.snippet
steps:
  - step_name: account_lookup
    event_type: api_request
    proxy_event:
      method: POST
      url: /account/check
      request:
        body_rule:
          jsonpath:
            - name: $.account_id
              extract_to_attribute: identity['ACCOUNT'].customer_token.customer_token
    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 example journey maps $.account_id into identity['ACCOUNT'].customer_token.customer_token. A request containing {"account_id":"acct-123"} should therefore perform a lookup for acct-123.

Test an ordinary account ID, one containing reserved URL characters, missing input, a slow API and an invalid response. The supplied files demonstrate the configuration; replace the reserved example domain and validate against your own test API before deployment.

Verify the mapping before choosing an action

For the illustrative response {"score":72,"status":"review"}, the event should contain custom.general_purpose['account_risk_score'] = 72 and custom.general_purpose['account_risk_status'] = "review". In your test environment, inspect these attributes in Investigations alongside the mapped account identifier.

Make the consuming decision depend on the operation named account_risk_lookup. A condition such as custom.general_purpose['account_risk_status'] = "review" can select your review outcome. The value 72 has meaning only under your API's score contract; do not assume its scale or direction from this example.

If the account identifier is missing, the operation's condition skips the call. If the API times out or returns an incompatible body, the expected assessment fields may be absent. Define a separate unavailable-result outcome so neither situation silently becomes an approval. Then connect the chosen outcome to the action your application or edge deployment should take.

Reuse the integration on another step

Import the file once per journey. Select Add beside Customer account risk lookup again, choose another step and configure that use independently. For example, the login step can read ACCOUNT, while a transfer step reads BENEFICIARY if that is where you mapped the recipient's account identifier. Each step must populate its selected identifier before the lookup runs.

Keep the endpoint and secret name the same where the API contract is shared. Change only the arguments that vary. This avoids separate copies of request construction, credential handling and response mappings in every step.

If you need two calls in the same step, give their model operations distinct names and map their results to distinct destinations in your custom templates. The example's two fixed output attributes would otherwise be shared by both calls. Set downstream dependencies explicitly; the visual order of operations is not a substitute for their dependency graph.

Adapt the request and response

For a different API, change the method, endpoint, headers, body and response mappings together. Map an HTTP response field into a Darwinium attribute before using it in a rule. Keep correlation identifiers where the provider supplies them, and distinguish a successful assessment from a timeout, empty result or rejected request.

A GET lookup, a Jira issue creation and an SMS send have different retry consequences. For an action that creates something downstream, use the service's supported idempotency or deduplication mechanism and a deliberate event condition. A snippet does not add a retry or deduplication policy automatically.

Configure credentials through Connect credentials from a secret store, then test with your API's development environment. The example above has passed journey-loader validation; the reserved hostname must be replaced and the actual API contract tested before deployment.