Webhooks in Workflows

Webhook workflows allow working with parameters fromĀ the workflow context.

Workflow diagram with a GET webhook block named contacts_get_by_email selected, showing its settings panel with the Manage Webhook button and Advanced parameters section, and the Webhook block highlighted in the left sidebar

This request uploads and sends the contact’s data from Reteno to other systems and contrariwise collects data into Reteno from external systems. Using this as a part of a workflow, you can:

  1. Address your own resource, which will process the request and return data for
  • Personalization (for example, a personal promo code or a token for authorization) in the message.
  • Checking response parameters.
  1. Send data from an event or from the contact’s card (for example, order id, additional field contact’s id in messenger or Birthday) to an external resource.
šŸ“˜

Note

Only the contact’s data (fields + additional fields) and the parameters from an event that triggered a workflow with a webhook can be sent through a webhook. In most cases, data transfer in webhooks is configured in JSON format, but XML and text formats are also available.

The Webhook block only calls an external API. To send WhatsApp messages through a webhook, you need an account with a WhatsApp Business API provider; the requirements for the business account, sender number, and message templates are defined by Meta and the chosen provider — follow their documentation.

Account-level data — such as your tariff/plan or billing status — is not available inside a workflow and cannot be referenced in a webhook block. The Webhook block can only call an external endpoint or send/receive contact- and event-level data.

Using Webhook Responses in Messages and Workflows

You can seamlessly use JSON responses received from external services via webhook calls directly in your workflows. This allows you to fully leverage real-time data, such as from your CRM, to personalize communication and drive intelligent workflow decisions.

Key Benefits:

  • Personalize messages with dynamic data tailored to each user
  • Route contacts through different branches in your workflow using data-driven logic (via the Condition block)

This approach allows you to create deeply personalized communications tailored to each user's context.

How It Works

When a webhook returns a JSON response, the data is stored in the workflow under an object named after your data source (i.e., the webhook name). You can reference this data:

  • In messages using Velocity syntax
  • In subsequent Condition and Webhook blocks in the workflow — using regular expressions

Example: Using Workflow Response in Messages

Suppose you send a request to a webhook data source called crmWebhook to retrieve a personal promo code. The response might look like this:

{  
  "externalId": "user_12345",  
  "promoCode": "WELCOME-5OFF"  
}

To display the promo code in a message within the workflow, use the following Velocity syntax:

  • $!crmWebhook.promoCode

This short form is the most convenient for inline use in messages. The longer form below returns the same value and is useful when the data source name is stored in a variable or needs to be built dynamically:

  • $!data.get("crmWebhook").get("promoCode")

Where

  • crmWebhook is the name of your webhook data source
  • promoCode is the field returned in the response
Email editor showing the Velocity expression $!crmWebhook.promoCode highlighted in the message body, above a Grab your code section

As a result, each contact will see their own unique promo code retrieved from your external system.

Example: Using Workflow Response in the Condition Block

Let’s say you want to check if a contact is a member of your loyalty program. You send a request to crmWebhook, and the service responds with:

{  
  "externalId": "user_98765",  
  "isLoyaltyMember": true  
}

To configure the Condition → Variable matches regular expression block:

  • In the Name field, enter the data source name: crmWebhook
  • In the Pattern field, enter a regex pattern to match the desired value, for example: .*true.*.
Workflow canvas with a Condition block selected, showing its Variable matches regular expression settings panel with Name set to crmWebhook and Pattern set to a regex matching true

If the value of isLoyaltyMember is true, the contact proceeds down the Yes path. Otherwise, they follow the No path.

These examples demonstrate just a few ways you can integrate external data into your workflows. You can expand on this approach by:

  • Checking for specific values or nested fields
  • Applying multiple regular expressions
  • Combining Velocity logic for dynamic content rendering

Use webhook responses to power smarter automations and deliver meaningful, real-time personalization at scale.

Creating a Webhook in a Workflow

  1. Go to Automation → Workflows and click the New workflow button.
Automation section navigation with the Workflows tab and New workflow button highlighted
  1. Open the Other tab on the left panel, and select Webhook.
Workflow editor left sidebar with the Other tab expanded and the Webhook block highlighted
  1. Click theĀ Select webhookĀ button on theĀ SettingsĀ panel on the right side.
Workflow canvas with a Webhook block selected, showing its settings panel on the right with the Select webhook button highlighted
  1. Select an existing webhook or create a new one.
Webhook management dialog listing existing webhooks with a Select button highlighted for each row, and the New webhook button in the top right
  1. In the new webhook configuration window, enter a name, description (optional), and select the request type from the drop-down menu: GET or POST.
Create webhook window with empty Name and Description fields highlighted, and the request type dropdown open showing GET selected and POST as an option

Data Substitution from the Workflow Context

To obtain data in the block, use Velocity variables in the following formats. Contact field names are case-insensitive during workflow execution. When entering event data manually for a webhook test, match the letter case used in the webhook variables.

FormatVariableDescription
Shorthand$discountIf the variable does not exist, the literal text $discount is output
Silent$!discountIf the value is missing, nothing is rendered
Alternate value${discount|$otherGift}If the variable value is missing, a fallback value is inserted
šŸ“˜

Please note

If the context contains both a value from external data (for example, "firstname": "Maggy") and a value from the contact card (for example, firstname = "Margaret") for the same field, the external value ("Maggy") will be used in the substitution.

Working with GET Request

Use this request type to retrieve data from an external resource and add it to the workflow context. Pass request parameters as name-value pairs in the URL query string.

## Working with GET Request

In order to configure the webhook:

  1. Enter the webhook name using any symbols (required field) and description (optional field).
  2. Enter the resource URL over secure HTTPS; the system does not save URLs that use HTTP. Add the required variables as query parameters after the question mark (?). In this example, the webhook passes the contact’s $EMAIL value to the external resource.
  3. If your resource reads parameters from headers, enable Pass parameters in headers slide button and enter corresponding variables and values you want to address.
Webhook settings with the Pass parameters in headers toggle enabled and an email parameter set to $EMAIL

Below are examples of parameter names and their values that can be used:

ParameterValue
phone$phone
email$email
name$name
city$city
contactID$contact_ID
param$workflowInstanceId

For example, a URL using all of the parameters above would look like this:

https://api.example.com/endpoint?phone=$phone&email=$email&name=$name&city=$city&contactID=$contact_ID&param=$workflowInstanceId
ā—ļø

Important

For GET requests, the $workflowInstanceId value can be passed in the webhook parameters — it is a unique identifier for the workflow instance. It allows identifying which specific events belong to the instance and, based on that, calculating statistics and conversions.

For $workflowInstanceId, the character case matters, while for contact fields, it does not.

  1. Enable Authentication slide button and select authentication connector. If you need to configure a new one, click the New connector button to open the Create connector window.
  2. In Create connector window enter the following details:
Create connector window with empty Connector name field, Authentication type set to Basic, and empty Login and Password fields
  • Connector name.
  • Authentication type from the drop-down list: Basic, Bearer token, API key, or OAuth 2.0.
  • Enter login and password/token/key.

For the OAuth 2.0 type, the connector form also contains the Provider field. When Other provider is selected, the Grant type field appears; it determines how the connection is authorized:

  • Authorization code — the standard flow with sign-in on the provider's side: after you click Connect, you are redirected to the provider's authorization page (the Authentication URL is used).
  • Client credentials — no user sign-in involved: the access token is requested directly from the Token URL using the Client ID, Client Secret, and Scopes specified under Advanced configuration. This flow suits server-to-server integrations, for example with Microsoft Entra ID.

The received token is automatically added to the Authorization: Bearer header of the requests and refreshed shortly before it expires.

Click the Done button to apply the new connector in the webhook automatically.

GET-request Testing

  1. Click the Send test button.
Create webhook window with the Send test button highlighted
  1. In the Dynamic data step, enter test data for variable substitution and click Next. Enter the data as a JSON object using the same letter case as the webhook variables, for example:

    {
      "EMAIL": "[email protected]"
    }
Sending GET request dialog showing the Dynamic data step with a request body containing EMAIL set to emmy@example.net
  1. Click Send request.
Sending GET request dialog on the Request step showing the resolved URL and headers, with the Send request button highlighted
  1. In the testing window, you get the response:
Sending GET request dialog showing a 200 response with a note that the response was transformed for use in messages, and the Transformed data tab showing the JSON result

Click the Back arrow in the top left corner of the dialog window, and click the Done button.

Now the new webhook is available for selection in your workflow.

Webhook management dialog listing the newly created contacts_get_by_email webhook with a Select button, confirming it is now available for selection

Working with POST Requests

Let’s see how to send contact data to an external service in a POST request. In this example, we use Postman Echo to return the submitted request data for testing.

Follow the steps below to configure a webhook with the POST request:

  1. In the webhook block settings, click the Select webhook button.
Workflow canvas with a Webhook block selected, showing its settings panel on the right with the Select webhook button highlighted
  1. In the Webhook configuration window, enter post_city as the webhook name, select the POST request type, and enter the following URL:

    https://postman-echo.com/post
Create webhook window with post_city as the name, the POST method, and the URL https://postman-echo.com/post entered, with JSON request body enabled
  1. If your application reads parameters from headers, enable the Pass parameters in headers slide button and enter the corresponding variables and values. Postman Echo does not require additional headers for this example.
Create webhook window with the Pass parameters in headers toggle enabled and a city parameter set to $CITY
ā—ļø

Important

For POST requests, the $workflowInstanceId value can be passed in the webhook parameters — it is a unique identifier for the workflow instance. It allows identifying which specific events belong to the instance and, based on that, calculating statistics and conversions.

For $workflowInstanceId, the character case matters, while for contact fields, it does not.

  1. If the external service requires authentication, enable the Authentication slide button and select an existing connector or create a new one. Leave authentication disabled for Postman Echo.
Create webhook window with the Authentication toggle enabled and the test_basic connector selected
  1. Enable request body transmission, select JSON, and enter:

    {
      "city": "$CITY",
      "email": "$EMAIL"
    }

    You can also send request bodies in XML or text format when the external service requires them.

Create webhook window with the request body format dropdown open, showing JSON, Text, and XML options

To access event parameters, use Apache Velocity, for example: "param": "$param".

POST-request Testing

  1. Click the Send test button.
Edit webhook window for post_city with the Send test button highlighted
  1. Enter the test event data. Use the same letter case as in the webhook variables:

    {
      "CITY": "Kyiv",
      "EMAIL": "[email protected]"
    }
Sending POST request dialog showing the Dynamic data step with Event data request body set to CITY: Kyiv and EMAIL: emmy@example.net
  1. Click Next, review the substituted values, and click Send request. The response contains the submitted values in the json object:
Sending POST request dialog showing a 200 response with the Transformed data tab displaying the submitted city and email values returned by Postman Echo

To insert the returned city value into a message, use one of the following equivalent expressions:

  • $data.get('post_city').get('json').get('city')
  • $post_city.get('json').get('city')

Here, post_city is the webhook name, json is the object returned by Postman Echo, and city is the field containing the returned value. The second form is shorter and works the same way as the first — use whichever reads more clearly in your message.

Waiting for the Webhook Result

After sending a webhook, the workflow pauses until the webhook processor reports the final result. The workflow does not repeatedly request the intermediate status. When the result notification arrives, Reteno saves the response or error and continues the workflow. A fallback timeout prevents the workflow from waiting indefinitely, and duplicate notifications do not start the next block more than once.

This waiting mechanism does not change how failed requests are handled: server errors and timeouts still follow the retry rules below.

Retry Rules

If the endpoint returns a 5xx server error, Reteno repeats the request every 3 minutes, up to 3 retry attempts. Other response classes do not trigger these automatic retries.

Make the endpoint idempotent so that processing the same request more than once does not create duplicate operations.

Advanced Parameters

Workflow canvas with a Webhook block's settings panel open, showing the Manage Webhook button and the Advanced parameters link highlighted

The block contains advanced parameters, and the cases for filling them out are detailed in a separate article.

Webhook Management

Press Manage Webhook in the webhook block settings. The window containing the list of webhooks opens. There you can:

  • create a new webhook
  • edit existing webhooks
  • test webhooks
  • delete webhooks
  • view the list of deleted webhooks
Workflow canvas with a Webhook block's settings panel open and the Manage Webhook button highlighted

In the launch history of the workflow with a webhook, you will see the details of the request:

Workflow launch history page showing a webhook block's launch entry, with the Contact parameters panel highlighted on the right

Did this page help you?