Tutorial

How to make your chatbot dynamic with webhooks and live data

Connect your chatbot flows to live data. Learn how webhooks, expressions and splits turn a scripted bot into one that answers with real information.

A scripted chatbot gives everyone the same answer. A dynamic one answers this customer: their order, their balance, their next appointment. The bridge between the two is a webhook, a call from your flow to your own system in the middle of the conversation.

This guide shows how webhooks work in On-chat's flow builder, how to use the response in messages and branches, and how to design APIs that make flows fast and reliable.

What "dynamic" means in a flow

A flow becomes dynamic when its messages and paths depend on data rather than being fixed. In On-chat that data comes from four places:

Source Example expression Where it comes from
Contact @contact.first_name, @fields.plan The contact record and its custom fields
Results @results.order_number Answers collected earlier in the flow
Webhook @webhook.status The JSON returned by your last webhook call
Globals @globals.support_hours Workspace-wide values you manage in one place

Webhooks are the most powerful of the four, because they bring in anything your systems know.

How a webhook step works

Add a Call a webhook split to your flow and configure:

  • Method: GET to fetch data, POST to send data (for example, to create a lead).
  • URL: can include expressions, like https://api.example.com/orders/@results.order_number.
  • Headers: for example an Authorization header with your API key.
  • Body (POST): a JSON template that can use any expression.

When a contact reaches this step, On-chat calls the URL and waits for the response. The split then has two exits:

  • Success: your server answered with a successful (2xx) status.
  • Failure: an error status, a timeout or no response.

If the response body is JSON, it's available to the rest of the flow as @webhook.

Using the response in a message

Say your order API returns:

{
  "status": "shipped",
  "courier": "Aramex",
  "eta": "2026-11-02",
  "items": 3
}

You can write a message like:

Good news @contact.first_name! Your @webhook.items items have @webhook.status with @webhook.courier and should arrive on @(format_date(webhook.eta)).

@(…) lets you use functions inside a message. Useful ones include format_date, datetime_add, upper, title, round and default, which shows a fallback when a value is missing:

Your tracking code is @(default(webhook.tracking, "not available yet")).

The full list is in the expressions reference, and everything available in a flow is described in the flow context reference.

Branching on live data

The real power comes from changing the path based on the response. Add a Split by a custom expression after the webhook:

  • Expression: @webhook.status
  • Rules:
  • has only the phrase processing → "We're packing it now"
  • has only the phrase shipped → tracking message
  • has only the phrase delivered → "Delivered! How was everything?" → feedback flow
  • Other → open a ticket for the team

Numbers work too. Split on @webhook.balance with has a number below 0 to route overdue accounts to collections, and everyone else to a self-service menu.

Sending data to your systems

Webhooks aren't only for reading. Use POST to push what the bot collected into your CRM, booking system or spreadsheet automation:

{
  "name": "@contact.name",
  "phone": "@contact.urn",
  "interest": "@results.interest",
  "budget": "@results.budget"
}

If your system returns an ID, you can save it to the contact with Update the contact so future flows can use it.

No developer? Webhooks can also call Zapier or similar automation tools, which connect to thousands of apps.

Designing APIs that work well with flows

Your API is now part of a live conversation. Follow these rules:

  1. Be fast. The customer is waiting. Aim to respond in under a second or two and keep heavy work in the background.
  2. Return small, flat JSON. {"status": "shipped"} is easier to use than deeply nested objects.
  3. Return the words you want to branch on. Clear status values like shipped make splits simple.
  4. Use proper status codes. Return 2xx only when the lookup worked, so the Failure exit means something.
  5. Secure it. Require an API key in a header and check it on every request.
  6. Make POSTs idempotent. If a call is retried, it shouldn't create a duplicate lead or booking.

Always handle failure

Networks fail and IDs get mistyped. Connect the Failure exit to a path that still helps the customer:

  1. Apologise briefly and ask them to check the number, or
  2. Open a ticket with a human agent so a person can look it up.

Never let a failed webhook end the conversation silently.

Testing webhooks

Test webhooks in the simulator with a valid ID, an invalid ID and your API switched off, so you see every exit.

  • Use the Simulator to run the flow and check the webhook response in the simulator's event log.
  • Test with a valid ID, an invalid ID and with your API switched off.
  • Watch your server logs to confirm the URL and payload look the way you expect.

Ideas for dynamic flows

Any answer your systems already know can make a flow dynamic, from order status to available appointment slots.

Ready to connect your data? Start a free trial and add your first webhook in minutes.

Build your first dynamic flow today

30 days free. No credit card. Set up in minutes.

Create your free account