Home · Blog · Incoming webhook for a chatbot: how to start a flow from your own system
Incoming webhook for a chatbot: how to start a flow from your own system
Usually a person starts a bot flow: taps Start, types a word, opens the widget. But sometimes the event happens not in the messenger but in your own system: a request from a website form, an order in your accounting software, a payment in a service. To let such an event start a flow too, CHBT has the Incoming webhook trigger — an address your system sends a request to. Here is how to set it up, what you can pass, what the flow will do next and what this trigger honestly cannot do.
What an incoming webhook is
A webhook is an address one program sends a request to when something happens in it. “Outgoing” is when the bot itself sends data out: in CHBT that is the HTTP request action. “Incoming” is the other way round: an external system knocks on the bot’s door.
In CHBT an incoming webhook is one of the flow triggers, alongside Command (/start), Keywords and Deeplink. The trigger has its own address. As soon as a POST request arrives at it, the flow starts from the step you chose in Starting step.
The trigger is available both in Steps mode and on the Canvas, and it does not depend on the plan.
The main limitation — before you set it up
An incoming webhook starts the flow as a separate event in the website chat channel. It does not continue a specific customer’s conversation in Telegram, MAX or VK and cannot message them first. If a Message block is in such a branch, the text goes not to the customer’s messenger but to the webhook contact’s conversation — it will be visible in Conversations, and that is all.
So an incoming webhook is suitable for bringing an event into CHBT and having the team react to it: creating a deal, notifying an operator, setting a tag, passing data on. To tell a customer about an event in their messenger, you need a conversation that has already started: an operator or your system through the CHBT API can reply in it. Honest ways to notify customers — in the article on notifications through a bot.
What you need
- A connected website chat. The webhook flow runs in the widget channel. If the project has no such channel, the request gets a 404 response with the error
no web channel. - An enabled flow with the Incoming webhook trigger and a filled-in Webhook path. The webhook will not find a disabled flow — the response is 404
no_trigger. - A system that can send a POST request. It can be your website, CRM, accounting software, a form with a webhook setting or an automation service — Make, n8n, Albato.
On the Free plan every new webhook contact uses one of the 30 conversations of the month — keep this in mind if there are many events.
How to set up the trigger
- Open the flow and click Add trigger in the triggers panel.
- In When to start choose Incoming webhook.
- Webhook path — a short event name in Latin letters, for example
order-createdorsite-form. - A Secret is issued to a new trigger right away. The Generate button replaces it with a new one — after that the old address stops working, and the account will ask you to confirm.
- Copy the ready address from the URL for POST requests field. It looks like this:
https://app.chbt.io/webhook/inbound/<bot>/order-created?token=<secret>. - In Starting step choose the first step of the branch.
A flow can have several triggers, so the same flow can be started both by a webhook and, for example, by a keyword.
What to send in the request
The method is POST. CHBT reads three fields of the body:
uid(oruser_id) — who this is. One uid is one contact in CHBT: repeated requests with the same uid go to their card and conversation. It is convenient to pass an order number, a phone number or the customer’s id in your system. Without a uid every request creates a new contact.text(ormessage) — the event text. It is saved as the contact’s incoming message and is visible in Conversations.name— the contact name, up to 120 characters. You can insert it into texts as{{name}}.
Example:
curl -X POST "https://app.chbt.io/webhook/inbound/<bot>/site-form" \
-H "X-Webhook-Token: <secret>" \
-H "Content-Type: application/json" \
-d '{"uid":"79001234567","name":"Anna","text":"Website request: 3 m kitchen, measuring on Saturday"}'CHBT does not parse the other fields of the body: no separate variables will appear from them. Put everything the team needs to see into text.
The secret: in the address or in a header
The secret protects the address from other people’s requests. You can pass it in two ways:
- as the
?token=parameter in the address — suitable for systems where you can only enter a URL; - as the
X-Webhook-Tokenheader — if the system supports headers, this is neater: the secret does not end up in logs together with the address.
A request without the secret or with a wrong one gets a 401 unauthorized response, and the flow does not start. Old triggers created before secrets existed may not have one — then the webhook accepts requests without a check. Click Generate to turn the check on, and update the address in your system.
What to put after the trigger
A webhook branch is an ordinary flow, just without a live person on the other side. Useful steps:
- Action → CRM deal — a website request lands on the kanban board right away. In the deal name you can insert the name:
Website request — {{name}}, and set Amount and Stage. - Action → Notify an operator — the team gets a notification in the account and a push. Notification text supports variables too.
- Action → Add a tag — for example
site-request, so you can later filter such contacts in Contacts. - Action → HTTP request — pass the event on: to a Google Sheet, an external CRM, your own server. The event text will go into the request too.
- Condition — split events into branches, for example by the contact’s tag.
Which events are convenient to pass
- A request from a website or landing page form — so that it ends up in the same CRM as requests from messengers and the manager does not check two inboxes.
- A call or request from call tracking — a contact with the phone in uid and a short summary in text.
- A new order in your accounting system — a deal with the amount at the right stage and a notification to the person responsible.
- A payment on a third-party service — the
paidtag, so that such customers are visible in Contacts next to the others. - An event from Make or n8n — when an automation scenario has collected data from several sources and must hand the result to the team in CHBT.
What they all have in common: the event needs a reaction from the team, not an automatic reply to the customer in the messenger.
Example: a website request into the CRM in a minute
A furniture workshop receives requests through a form on its website. Every request should land in CHBT right away — where the manager already answers customers from Telegram and the widget.
- The “Website requests” flow: the Incoming webhook trigger, path
site-form. - The first step is an Action: Add a tag
site-request, a CRM deal namedWebsite — {{name}}at the New stage, Notify an operator with the textNew website request: {{name}}. - The website form sends a POST with
uid— the phone,name— the name andtext— what the customer wrote in the form.
The manager gets a push, opens the deal and sees the request text in Conversations. They can call or message the customer as usual. If the form itself cannot send such fields, put an automation service between it and CHBT: it will receive the form data and send it in the right shape.
How to test the webhook
The editor’s test chat will not help here: Check flow simulates a conversation, while the webhook comes from outside. Test with a real request:
- Send the request from the example above — from a terminal, Postman or your system’s test mode.
- A
{"ok":true}response means the flow has started. Error responses point to the cause: 401 — the secret, 404no_trigger— the path does not match or the flow is disabled, 404no web channel— there is no website chat, 400 — a wrong address. - Open Contacts: a contact with the name you passed has appeared, with the tag from the branch.
- Look at CRM and Conversations: the deal and the event text are there.
Use a separate uid for testing, for example test-1, so that you can easily find and delete the test contact later.
Incoming webhook, API and subscriptions — which to choose
| Task | Tool |
|---|---|
| An event in your system should trigger actions in CHBT: a deal, a tag, a notification | The Incoming webhook trigger |
| The bot should send customer data to an external system | The HTTP request action — in detail in the article on HTTP requests from a bot; for amoCRM and GetCourse there are ready-made integrations on the Request event |
| An external system should learn about messages and conversations | Event subscriptions in the integrations section |
| An external system should reply to a customer in a conversation that has already started | The CHBT API with a token from API connections |
The tools can be combined: for example, a webhook creates a website request, and an HTTP request in the same branch passes it on to your accounting system.
Common mistakes
- Expecting a message to the customer in Telegram. The webhook starts a flow but does not write to the customer in the messenger. For that you need their started conversation and a reply from an operator or the API.
- Passing data as separate fields. CHBT will not parse
phone,city,commentin the body — combine what you need intotext, and useuidandnamefor the contact. - No uid. Every request creates a new contact — and on the Free plan uses up a conversation of the month.
- Changed the secret and forgot about the system. After Generate the old address stops working — update it wherever the requests come from.
- Disabled the website chat. The webhook needs the widget channel; without it requests get a 404.
Chatbot integrationsHTTP request from a chatbotLeads from a bot in CRMCRM and contacts