Webhook Engine, explained simply.
A complete guide for people who do not write code. Every feature, every step, in plain English. (Pro) marks anything that needs the paid add-on — see the pricing page. This is Part 1, covering setup and sending. The reference and troubleshooting half is on a second page.
What it does · Words you will see · Installing · Your first form · How the answer comes back · Callback mode · Where the answer appears · Chat mode · Saving a reply · Reference & troubleshooting →
What this plugin does
Webhook Engine connects your WordPress site to an automation platform — a separate service where you build the actual logic, such as n8n, Make, Zapier, Power Automate, or a script written by your developer.
It connects the two in two directions. You can use either one on its own.
Your site asks, and shows the answer
A visitor fills in a form. Their answers go to your automation platform. Whatever it sends back appears on the page, without the page reloading.
Good for: an “ask our assistant” box, a postcode lookup, a contact form that files an enquiry.
Your platform sends information in
Your platform sends information whenever it likes. Your site stores it and shows it on any page. Nobody has to click anything.
Good for: a news feed that updates itself, a daily summary saved as a draft, a live statistics panel.
Inside the plugin’s own screens these are labelled Flow A — Outbound and Flow B — Inbound. This guide uses plain descriptions, but the labels are there so you can match them up.
The important idea
Webhook Engine does not think. It has no artificial intelligence of its own, stores no AI keys, and makes no decisions. It is a pipe. All the intelligence lives in your automation platform, where you control it. That is deliberate: you can change model, provider or logic whenever you like, and your WordPress site never needs to know.
Words you will see in this guide
Read this once and the rest will make sense.
| Word | What it means |
|---|---|
| Webhook | A web address that accepts information sent to it by another computer. Think of it as a letterbox with a URL instead of a street address. |
| Automation platform | The outside service where you build your logic — n8n, Make, Zapier, Power Automate, or anything similar. |
| Workflow | One piece of logic you have built there. For example: receive a question, search my documents, ask an AI to answer, send the answer back. |
| JSON | A simple text format computers use to exchange information. It looks like {"question": "Is the clinic open?"}. You will mostly see it, not write it. |
| Shortcode | Text in square brackets that you type into a page. WordPress replaces it with something real — becomes a working form. |
| Endpoint | A specific web address that accepts information. |
| Payload | One package of information sent from one computer to another. |
| Field | One box on a form. “Your name” is a field. |
| Markdown | A simple way of writing formatted text. Two asterisks around a word make it bold; two hashes make a heading. Your workflow can send Markdown and the plugin formats it properly. |
Installing the plugin
Before you start
- A WordPress site where you are an administrator.
- An automation platform account with at least one workflow that can receive information at a web address. Every major platform can do this.
- A few minutes to test. Always test on a page only you can see before putting a form in front of visitors.
You do not need any coding ability, an AI subscription, or a developer.
Installing the free plugin
- Go to Plugins → Add New.
- Search for Webhook Engine, or click Upload Plugin and choose the zip file.
- Click Install Now.
- Click Activate.
- A new Webhook Engine item appears in the left-hand menu.
Installing Pro (optional)
- Install and activate the free plugin first. Pro will not work without it.
- Install and activate Webhook Engine Pro the same way.
- Pro adds no menu of its own. It raises the limits inside the screens you already have, and adds Account and Contact support links at the top of Settings.
If the plugin will not activate
If WordPress says “Plugin file does not exist”, the plugin folder is one level too deep. This happens when a zip is unpacked by a file manager before uploading.
- Open your hosting file manager and go to
wp-content/plugins/. - Look for a folder not named exactly
webhook-engine. - If there is a
webhook-enginefolder inside it, move that inner folder up one level. - Delete the empty outer folder, then activate.
The four screens
| Screen | What it is for |
|---|---|
| Settings | Site-wide defaults, used by anything that does not set its own. |
| Forms | Your forms. Each can point at a different workflow and look different. |
| Channels | The streams of information your platform sends into your site. |
| Shortcode guide | A built-in reference, always matching your installed version. |
If the activation email does not arrive, check your spam or junk folder before anything else — licence and activation emails are very often filtered there. The purchase itself has almost certainly gone through, so please look there before assuming it failed or asking for a refund.
Your first form, step by step
Step 1 — Get a web address from your platform
- In your automation platform, create a new workflow.
- Add a trigger step that receives information from the web. In n8n this is a Webhook node; in Make it is Custom webhook; in Zapier it is Webhooks by Zapier → Catch Hook.
- Set it to accept POST.
- Copy the web address it gives you.
Step 2 — Create the form
- Go to Webhook Engine → Forms.
- In Form ID, type a short name using lowercase letters, numbers and dashes, such as
ask-health. This cannot be changed later. - In Label, type a heading to show above the form. Optional.
- In Webhook URL, paste the address from Step 1.
- In Fields, describe the boxes you want, one per line.
- In Button text, type what the button should say.
- In Waiting message, type what shows while your workflow is thinking.
- Click Add form.
question | Your question | textarea | required email | Your email address | email
| Part | What it means |
|---|---|
| name | What your workflow will see. Keep it simple and lowercase. |
| Label | What the visitor reads. |
| type | text, email, textarea (a large box), number, tel, url or hidden. |
| required | Add this word if the visitor must fill it in. Leave it off if optional. |
Common mistake
Only the fields you list here are ever sent to your workflow. Anything else on the page is silently dropped. If a value is not arriving, check its spelling in this box first.
Step 3 — Check it can reach your workflow
- Click Test webhook on the same screen.
- The plugin sends a real, clearly-marked test with sample values.
- You should see a success message, and the test should appear in your workflow’s history.
A test is marked as a test and carries no return address. If you are using callback mode, a test cannot be replied to. That is expected — use it to confirm the connection, then test the reply from a real page.
Step 4 — Put the form on a page
- Create or edit a page.
- Add the shortcode where you want the form:
- Save the page as a draft first.
- Click Preview and try the form yourself.
- Publish when you are happy.
Step 5 — Send an answer back
In your workflow, send back a small piece of JSON containing the answer.
{ "reply": "Yes, the clinic is open from 8am to 4pm on weekdays." }
The word reply is not special. The plugin understands many names for the same thing — see field names. Your answer can use Markdown for formatting.
Choosing how the answer comes back
This is the setting people most often get stuck on. Open a form and find Response handling. There are four choices.
| Choice | What happens |
|---|---|
| Use the site default | Whatever you picked under Settings. |
| Wait for and show the reply | Your site holds the line open and waits. The answer appears on the page. |
| Send only | Your site sends the information and shows a success message. Any reply is ignored. |
| Callback | Your site does not wait. It gives your workflow a return address to send the answer to later. |
Which should I choose?
- Does the visitor need to see an answer? No → choose Send only. Done.
- Can your platform reply on the same connection, and does your workflow finish within about 25 seconds? Yes → choose Wait for and show the reply.
- Otherwise → choose Callback.
How do I know if my platform can reply on the same connection?
If it has a step whose job is to answer the incoming request, it can.
- n8n — a “Respond to Webhook” node.
- Make — a “Webhook response” module.
- Power Automate — a “Response” action, which needs a paid plan.
- Zapier — limited; usually returns its own acknowledgement rather than your content.
If you cannot find such a step, or it is behind a paywall, or your workflow takes minutes rather than seconds, use Callback.
Rule of thumb
If your workflow involves an AI writing more than a paragraph or two, several steps in sequence, or a human approving something, use Callback.
Callback mode, in detail
What problem it solves
When your site sends a question to your workflow, it normally waits on the open line for the answer, like staying on hold on the phone. That has two problems.
- Some platforms cannot answer on that line at all. They accept your message and hang up. There is nothing wrong with them — many are built that way.
- Nobody can stay on hold forever. Your site will not wait longer than 30 seconds, because waiting ties up part of your server. A workflow that takes two minutes cannot possibly answer in time.
Callback mode fixes both. Instead of staying on hold, your site says: here is my return address, send the answer when you have it. Then it hangs up. The visitor still sees the waiting message. Behind the scenes their browser quietly checks back every couple of seconds until the answer arrives.
Sending a message to a web address is something every automation platform can do. That is why this works everywhere.
How to turn it on
- Go to Webhook Engine → Forms and open your form.
- Set Response handling to Callback.
- Optionally set Callback deadline — how many seconds the visitor waits before being told nothing arrived. Leave it empty to use the site-wide value.
- Click Save form.
There is nothing to configure on your automation platform.
What your workflow receives
Every submission now carries three extra items alongside the normal fields.
{ "source": "form", "endpoint": "ask-health", "fields": { "question": "Is the clinic open?" }, "return_url": "https://example.com/wp-json/webhook-engine/v1/return/<id>?token=<token>", "request_id": "<id>", "deadline": "2026-01-01T12:02:00+00:00" }
| Item | What it is |
|---|---|
return_url | The address to send your answer to. A different one every time. |
request_id | A reference for this one submission, in case you want to log it. |
deadline | The moment the visitor stops waiting. Answering after this is too late. |
You do not paste this anywhere
Your workflow reads return_url out of each incoming message, the same way it reads the visitor’s question. There is nothing to keep updated, and nothing breaks if you move your site to a new domain.
In n8n you would write {{ $json.return_url }}. Other platforms have their own way of referring to an incoming value — look for “expressions” or “mapping” in their documentation.
What to send back
Send a normal web message (a POST) to that return_url. You have two options, and both work.
Option one — just send text
Send your answer as plain text, with no structure at all.
Yes, the clinic is open from 8am to 4pm on weekdays.
The whole message becomes the reply. You do not need to build any JSON. If your platform can only send text to an address, you are finished.
Option two — send JSON
If you prefer structure, the plugin looks for your answer under any of these names:
body · markdown · content · text · answer · reply · message · output · article · description · summary
So all of these mean exactly the same thing:
{ "reply": "Yes, we are open." } { "answer": "Yes, we are open." } { "text": "Yes, we are open." } { "output": "Yes, we are open." }
The reason there are so many names is simple: whatever your AI step already calls its output, it very likely matches one of them. You should not have to add a step just to rename a field.
Name matching is forgiving. Capital letters, underscores, dashes and spaces are ignored. postTitle, post_title and "Post Title" are all the same name.
Wrappers are removed automatically, up to four layers deep. All of these work:
{ "reply": "Yes, we are open." } { "data": { "body": "Yes, we are open." } } { "result": { "output": { "text": "Yes, we are open." } } } [ { "message": "Yes, we are open." } ]
Wrapper names removed: data, payload, result, results, json, output, item, items, record, fields, attributes, object — plus a list containing exactly one item.
You can add a heading. Include a title and it appears above the answer.
{ "title": "Opening hours", "body": "We are open 8am to 4pm on weekdays." }
If nothing matches, it still works. Send something with no recognised answer field and the plugin shows it as a neat labelled table instead of failing. That is genuinely useful for lookups that return facts rather than prose.
{ "city": "Lagos", "temperature": 21, "humidity": 60 }
| Response rendering | What it does |
|---|---|
| Auto (default) | A recognised answer field is formatted as an article. Anything else becomes a table. |
| Markdown | Always format as an article. |
| Table | Always show as a labelled table. |
| JSON | Show the raw structure. Useful while building. |
Keeping the password out of the address
The return address has a one-time password in it, after ?token=. Web servers often record addresses in their logs, so if that bothers you, move it:
- Remove everything from
?token=onwards. - Send the token as a header named
X-Webhook-Engine-Tokeninstead.
Both work identically. The address version is the default only because it works with the simplest possible sender.
Categories and tags
The answer can carry more than the text itself. Categories and tags come back as small labels above and below the answer — and if you have turned on draft post creation, they are applied to the post as real categories and tags.
{ "title": "Opening hours", "body": "We are open 8am to 4pm on weekdays.", "categories": ["Clinic"], "tags": ["hours", "reception"] }
Category names understood: categories, category, cats, sections, topics. Tag names understood: tags, tag, keywords, terms, labels.
The shape is forgiving. A proper list and one plain line with commas mean the same thing — ["hours", "reception"] or "hours, reception".
This is the setup for “the form writes a post for me.” A visitor describes what they want, your AI step writes it, and the answer comes back carrying a title, the article itself, and the categories and tags to file it under. Turn on Draft post creation on the form (Pro) and the whole thing lands in your drafts, ready for you to review. See Turning replies into draft posts in Part 2.
Everything except the answer itself is optional. Leave out the title, the categories, the tags — or all three — and nothing changes: no empty heading appears and no stray labels are added. Send only what you have.
Telling the visitor something went wrong
If your workflow fails, do not leave the visitor waiting. Send this instead:
{ "status": "error", "error_message": "The document search timed out." }
The visitor immediately sees your normal failure wording. Your message is not shown to them — it is recorded under Settings → Recent send problems, where only administrators can see it. That split is deliberate: error messages often contain server names and internal addresses, which should never appear on a public page.
The deadline
- Minimum 15 seconds, maximum 10 minutes, normally 120 seconds.
- Set it site-wide under Settings, or per form.
- Leave the per-form box empty to inherit the site-wide value.
Unlike the Request timeout setting, a long deadline here costs your server nothing. The submission has already finished; the visitor’s browser is simply checking back. So you can be generous.
Tip: set the deadline comfortably above your workflow’s slowest realistic run. If it usually takes 40 seconds, set 120, not 45.
What the visitor sees while waiting
- Your waiting message, with a spinner.
- After 5 seconds, a counter showing how long it has been.
- Their typed text stays in the box, and the button is disabled so they cannot submit twice.
When the answer arrives it appears in place and the button becomes available again. Their typed text stays in the box — a question box behaves like a search box, not a contact form, so they can adjust the wording and ask again. Only Send only mode clears the form, because there is no reply to compare against. If the deadline passes, they see “No reply arrived in time. Please try again.” with their text preserved.
Retries are safe
If your platform sends the same answer twice — many retry automatically — the second is politely accepted and ignored. The visitor’s answer is never replaced, and your platform sees a success so its own run is not marked as failed.
Common mistakes
| Mistake | What you see | Fix |
|---|---|---|
| Using a saved copy of an old return address | Nothing arrives; the visitor times out | Read it from each incoming message |
| Answering after the deadline | Nothing appears | Raise the deadline, or speed up the workflow |
| Sending the answer to your own webhook address | Nothing arrives | The return address is on your WordPress site |
| Leaving a “respond to webhook” step in place too | Works, but slower | Harmless — your site stops waiting after 10 seconds and watches for the callback |
| Turning on callback for a chat form | The option is not available | Chat forms always wait for the reply directly |
| A security service blocking the return address | Nothing arrives; your platform reports an error | See security software |
Does callback work with everything else?
| Feature | Works with callback? |
|---|---|
Placing the answer elsewhere with | Yes — see below |
| Response rendering (Markdown, table, JSON) | Yes, identically |
| Copy and Export buttons | Yes |
| Draft post creation (Pro) | Yes, with no extra setup |
| Your own bridged form | Yes |
| Chat mode | No. Chat forms wait for the reply directly |
Where the answer appears on your page
By default the answer appears directly underneath the form. You can put it anywhere instead — a sidebar, a second column, further down the page. This works in every response mode, including callback.
How to do it
- Edit the page and put the form shortcode where you want the form:
- Put the answer shortcode wherever you want the answer:
- Go to Webhook Engine → Forms, open the form, and find Response location.
- Type
#wengine-response-ask-health, replacingask-healthwith your own Form ID. - Click Save form.
Now the waiting spinner, the counter and the eventual answer all appear in the second location — even if the answer takes two minutes to arrive.
Tip: the id in both shortcodes and the name in Response location must all match your Form ID exactly.
Common mistake
No data yet. is for form answers only. It is not the same as , which shows information your platform sent into your site on its own.
Does the answer stay on the page?
No. An answer belongs to the one visitor who asked for it. It is shown to them and gone when they reload. Nothing is stored. If you want an answer to become permanent content, use Draft post creation.
Chat mode
Turning on Conversation mode changes a form into a chat. Messages appear as bubbles, and each new message sends the whole conversation so far to your workflow — so it can answer with context, remembering what was said earlier.
Setting it up
- Open your form under Webhook Engine → Forms.
- Tick Conversation mode.
- Optionally type a Welcome message — a first message from your assistant.
- Click Save form.
The first visible field becomes the message box. Other visible fields are ignored in chat mode. Hidden fields are still sent every time, which is handy for routing.
{ "fields": { "question": "What about for children?" }, "conversation": { "history": [ { "role": "user", "content": "Is the vaccine available?" }, { "role": "assistant", "content": "Yes, as of..." } ] } }
Things to know
- Nothing is stored on your site. The conversation lives only in the visitor’s browser and disappears when they reload. For a site answering sensitive questions, that is a feature.
- The history sent to your workflow is capped: the last 20 messages, 4,000 characters each, 20,000 in total.
- Enter sends. Shift + Enter starts a new line.
- Answers appear all at once when ready, not word by word.
- Callback mode and Draft post creation are not available in chat mode.
The Enter key on ordinary forms
Every non-chat form has an Enter key setting:
- Auto — if the form is a single large box, Enter sends it and Shift+Enter adds a line. Multi-field forms are left alone.
- Enter always submits — useful for a search-box style layout.
- Enter never submits — use this when visitors write longer text.
Letting visitors save a reply
Because chat conversations are never stored, every answer carries a Copy button and an Export menu so a visitor can keep it.
| Option | What they get |
|---|---|
| Copy | The answer’s text, copied to their clipboard. |
| Export → Markdown | The original formatted text your workflow sent. |
| Export → Text | Plain text, as a file. |
| Export → HTML | A small readable web page they can open on their own computer. |
These appear on every answer, chat or not, including callback answers — but only once there is something to save. Never during the waiting spinner, on an error, or in Send-only mode. It all happens in the visitor’s browser; nothing is sent anywhere or stored.
Part 2: reference & troubleshooting
Bringing information into your site, turning it into posts, the full shortcode and field reference, what to do when something goes wrong, and the FAQ.
