Skip to main content
Webhook triggers are not enabled by default. Contact support@integrate.io or your Customer Success Manager to have the feature turned on for your account before you follow this guide.

Overview

A webhook trigger gives a package a public URL. When an external application POSTs a JSON body to that URL, Integrate.io ETL reads the body into package variables and runs the package as a job on the cluster named in the URL. The payload arrives as variables, not as records. A package still needs a source component to produce at least one record before the rest of the dataflow can run, so a webhook package uses a source component that produces a single record and takes its values from the variables in a Select component downstream.

Trigger URL

Prerequisites

  • Webhook triggers enabled on your account by the Integrate.io team.
  • A running cluster. See Creating a Cluster.
  • An external application that can send outbound webhooks to a URL you supply.
  • A connection created for the destination you plan to write to.

Build order

You cannot define the package variables until an event has arrived, because the variable names come from the payload. Build the package in two passes, in this order.

Building the webhook package

1

Prepare the cluster

Use a running cluster rather than an on-demand one. An on-demand cluster starts up for each job, and that startup time is added to every event.A webhook runs only on the cluster named in its URL. Adding a second cluster does not spread the load of a single webhook. To spread load, create separate packages on separate clusters and point different event types at each one.
2

Add the source component

Add one source component that produces a single record. Do not map any fields yet.
3

Generate the URL and register it

  1. Generate the trigger URL from the package settings. Do not assemble or edit the URL by hand.
  2. Register the URL in the external application, subscribed to a single event type.
4

Send a few sample events

  1. Enable the webhook in the external application.
  2. Send two or three real events.
  3. Disable the webhook.
  4. Complete steps 5 to 8 using the jobs those events created.
  5. Re-enable the webhook.
Events that arrive while the package is incomplete are not replayed, so keep the webhook disabled while you build.
5

Read the variable names

Open the job created by one of your sample events and go to the Variables tab in Job details. The list is read-only and is the definitive source for the variable names.Do not copy names from the external application’s sample payload. Integrate.io ETL derives the names from the payload structure, and they will not always match that application’s documentation.

Sample payload

Resulting variables

The list is truncated here. A production payload commonly produces 100 or more variables.

How the payload maps to variable names

Nested keys are joined with underscores. Arrays produce two kinds of variable: one holding the whole array as a JSON string, and one per element position.
6

Define the package variables

In the package designer, open Variables and select the Package tab. Add one variable for each field you plan to use, copying each name exactly from step 5. Set each value to two single quotes (''), which acts as an empty default until the payload supplies the real value.For the payload above, define these:
See Using and Setting Variables for how variables are evaluated and scoped.
7

Map the variables to fields

Add a Select component after the source. Reference each variable with $ and enclose it in single quotes, because the value is a string.Convert data types and clean values in the same component.
8

Configure the destination

9

Re-enable and verify

  1. Send an event and confirm the job succeeds.
  2. Confirm every column has a value. An empty column usually means the variable name does not match, so go back to step 5.
  3. Send an event with an empty array and one with a missing optional field.
  4. Send two or three events in quick succession and check that the jobs complete.

Processing nested arrays

An array in the payload does not have the same number of elements in every event, so the position-indexed variables (data_appointments_0_id and similar) break as soon as the length changes. Use the variable that holds the whole array and expand it in two Select components.

First Select component: flatten the array

JsonStringToBag converts the JSON string into a bag, and Flatten turns the bag into one record per element. The fields from the parent object pass through unchanged, so each record keeps the keys that identify the event.

Second Select component: extract the fields

Each record now holds one array element in the appointment field. Extract the values you need from it. Two components are required. Extraction only works on a record that already holds a single element, so flattening and extraction cannot share one Select component.

Choosing the extraction function

For more on maps, bags, and JSONPath, see Processing JSON Data.

Splitting the dataflow

The fields from the parent object produce one record per event, while the array produces one record per element. Those cannot be written to the same destination, so use a separate dataflow and a separate destination for each.
  • Give each dataflow its own source component.
  • The parent dataflow needs one Select component. The array dataflow needs two.
  • Carry the same key fields through every dataflow, so the records can be matched later.
  • Join the results in the database, not inside the package.
  • Prefix component names with the dataflow they belong to.
This example needs two dataflows. Add one more for each additional array in the payload.

Sending outbound requests

A package can POST to an HTTP endpoint, once per record. The most common use is starting another Integrate.io ETL package through its trigger URL, but the same approach works for any API that accepts a JSON body. There are three parts: read the data you want to send, build it into a JSON body, then send the request and read the response.

1. Read the data you want to send

Read the records you want to send from wherever they live, using a Database Source, a File Storage Source, or the output of an earlier transformation. One request is sent per record, so make sure each record represents exactly one call. Use a Filter or Aggregate component upstream to control how many requests the job makes. If the package sends a single fixed payload rather than one per record, use a Dummy Source and build the values from expressions and variables.

2. Build the payload

Build the JSON body in a Select component. TOMAP pairs each key with its value, and ToJson converts the result into a JSON string. Keys are literal strings in single quotes. Values are field names or expressions. Add a key and a value to add another field to the payload.

3. Send the request

Curl takes the URL, the method, the headers as a JSON string, and the request body. Give the output field a name of its own, such as api_response, so it does not clash with the fields you extract from it in the next step.
The Accept header with version=2 is required when calling the Integrate.io gateway. For any other endpoint, send the headers that API expects. For calls that need authentication, use CCurl and pass a connection ID as the last argument. You can find the ID on the connection’s page. Do not put a token directly into an expression.

4. Read the response

Curl returns a map with three keys: status, body, and headers. Extract the ones you need in a second Select component. request_id is optional and gives each call a unique value you can match against later. The request does not wait for the receiving system to finish its work. A 2xx status means the endpoint accepted the request, not that the work behind it succeeded. Write api_status_code and api_body to a destination if you need a record of what happened.

Cluster sizing

Naming and tracking

  • Name the package after the exact event it handles.
  • Note which package version is known to work. Webhook packages are edited often.
  • Keep a record of which event type points at which package, cluster, and target tables. The link exists only as a URL inside the external application, so nothing in Integrate.io ETL shows it.

Troubleshooting

URL and registration

Variables

Arrays

Destination

Runtime

FAQ

How do I enable webhook triggers on my account? Contact support@integrate.io or your Customer Success Manager. Webhook triggers are not self-serve, and the trigger URL cannot be generated until the feature is turned on. Can one webhook run on more than one cluster? No. A webhook runs only on the cluster named in its URL. To spread load, create separate packages on separate clusters and point different event types at each one. Why is a destination column empty when the job succeeded? The variable name in the package does not match the name in the payload. Open the Variables tab in Job details, copy the name exactly, and check the capitalization. Should I use data_appointments_0_id or data_appointments_json? Use data_appointments_json. Position-indexed variables stop matching as soon as the array length changes between events. What is the difference between a webhook trigger and a service hook? A webhook trigger is incoming: an external application POSTs to Integrate.io ETL to start a job. A service hook is outgoing: Integrate.io ETL POSTs to a URL you own when something happens on the platform, such as a job failing or a cluster idling. Are events replayed if the package is not working? No. Events that arrive while the package is broken are lost. Disable the webhook in the external application while you build, and re-enable it once you have verified the package.

Dummy Source

Using and Setting Variables

Processing JSON Data

Select Transformation

Database Destination

Service Hooks

Creating a Cluster

Curl

Last modified on October 27, 2026