Documentation

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.

Direction oneFlow A

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.

Direction twoFlow B

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.

WordWhat it means
WebhookA 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 platformThe outside service where you build your logic — n8n, Make, Zapier, Power Automate, or anything similar.
WorkflowOne piece of logic you have built there. For example: receive a question, search my documents, ask an AI to answer, send the answer back.
JSONA simple text format computers use to exchange information. It looks like {"question": "Is the clinic open?"}. You will mostly see it, not write it.
ShortcodeText in square brackets that you type into a page. WordPress replaces it with something real — becomes a working form.
EndpointA specific web address that accepts information.
PayloadOne package of information sent from one computer to another.
FieldOne box on a form. “Your name” is a field.
MarkdownA 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

  1. A WordPress site where you are an administrator.
  2. An automation platform account with at least one workflow that can receive information at a web address. Every major platform can do this.
  3. 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

  1. Go to Plugins → Add New.
  2. Search for Webhook Engine, or click Upload Plugin and choose the zip file.
  3. Click Install Now.
  4. Click Activate.
  5. A new Webhook Engine item appears in the left-hand menu.

Installing Pro (optional)

  1. Install and activate the free plugin first. Pro will not work without it.
  2. Install and activate Webhook Engine Pro the same way.
  3. 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.

  1. Open your hosting file manager and go to wp-content/plugins/.
  2. Look for a folder not named exactly webhook-engine.
  3. If there is a webhook-engine folder inside it, move that inner folder up one level.
  4. Delete the empty outer folder, then activate.

The four screens

ScreenWhat it is for
SettingsSite-wide defaults, used by anything that does not set its own.
FormsYour forms. Each can point at a different workflow and look different.
ChannelsThe streams of information your platform sends into your site.
Shortcode guideA 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

  1. In your automation platform, create a new workflow.
  2. 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.
  3. Set it to accept POST.
  4. Copy the web address it gives you.

Step 2 — Create the form

  1. Go to Webhook Engine → Forms.
  2. In Form ID, type a short name using lowercase letters, numbers and dashes, such as ask-health. This cannot be changed later.
  3. In Label, type a heading to show above the form. Optional.
  4. In Webhook URL, paste the address from Step 1.
  5. In Fields, describe the boxes you want, one per line.
  6. In Button text, type what the button should say.
  7. In Waiting message, type what shows while your workflow is thinking.
  8. Click Add form.
The Fields box — one field per line
question | Your question | textarea | required
email    | Your email address | email
PartWhat it means
nameWhat your workflow will see. Keep it simple and lowercase.
LabelWhat the visitor reads.
typetext, email, textarea (a large box), number, tel, url or hidden.
requiredAdd 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

  1. Click Test webhook on the same screen.
  2. The plugin sends a real, clearly-marked test with sample values.
  3. 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

  1. Create or edit a page.
  2. Add the shortcode where you want the form:
  3. Save the page as a draft first.
  4. Click Preview and try the form yourself.
  5. Publish when you are happy.

Step 5 — Send an answer back

In your workflow, send back a small piece of JSON containing the answer.

A complete 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.

ChoiceWhat happens
Use the site defaultWhatever you picked under Settings.
Wait for and show the replyYour site holds the line open and waits. The answer appears on the page.
Send onlyYour site sends the information and shows a success message. Any reply is ignored.
CallbackYour site does not wait. It gives your workflow a return address to send the answer to later.

Which should I choose?

  1. Does the visitor need to see an answer? No → choose Send only. Done.
  2. 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.
  3. 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.

New

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.

  1. 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.
  2. 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

  1. Go to Webhook Engine → Forms and open your form.
  2. Set Response handling to Callback.
  3. Optionally set Callback deadline — how many seconds the visitor waits before being told nothing arrived. Leave it empty to use the site-wide value.
  4. 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.

What arrives at your workflow
{
  "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"
}
ItemWhat it is
return_urlThe address to send your answer to. A different one every time.
request_idA reference for this one submission, in case you want to log it.
deadlineThe 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.

A complete, valid answer
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:

All identical in effect
{ "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:

Wrappers are unwrapped for you
{ "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.

With a heading
{ "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.

Displayed as a table
{ "city": "Lagos", "temperature": 21, "humidity": 60 }
Response renderingWhat it does
Auto (default)A recognised answer field is formatted as an article. Anything else becomes a table.
MarkdownAlways format as an article.
TableAlways show as a labelled table.
JSONShow 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:

  1. Remove everything from ?token= onwards.
  2. Send the token as a header named X-Webhook-Engine-Token instead.

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.

A reply that files itself
{
  "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:

Reporting a failure
{ "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

MistakeWhat you seeFix
Using a saved copy of an old return addressNothing arrives; the visitor times outRead it from each incoming message
Answering after the deadlineNothing appearsRaise the deadline, or speed up the workflow
Sending the answer to your own webhook addressNothing arrivesThe return address is on your WordPress site
Leaving a “respond to webhook” step in place tooWorks, but slowerHarmless — your site stops waiting after 10 seconds and watches for the callback
Turning on callback for a chat formThe option is not availableChat forms always wait for the reply directly
A security service blocking the return addressNothing arrives; your platform reports an errorSee security software

Does callback work with everything else?

FeatureWorks with callback?
Placing the answer elsewhere with
Yes — see below
Response rendering (Markdown, table, JSON)Yes, identically
Copy and Export buttonsYes
Draft post creation (Pro)Yes, with no extra setup
Your own bridged formYes
Chat modeNo. 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

  1. Edit the page and put the form shortcode where you want the form:
  2. Put the answer shortcode wherever you want the answer:
  3. Go to Webhook Engine → Forms, open the form, and find Response location.
  4. Type #wengine-response-ask-health, replacing ask-health with your own Form ID.
  5. 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

is for form answers only. It is not the same as

No data yet.

, 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

  1. Open your form under Webhook Engine → Forms.
  2. Tick Conversation mode.
  3. Optionally type a Welcome message — a first message from your assistant.
  4. 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.

What your workflow receives each turn
{
  "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.

OptionWhat they get
CopyThe answer’s text, copied to their clipboard.
Export → MarkdownThe original formatted text your workflow sent.
Export → TextPlain text, as a file.
Export → HTMLA 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.

Continued

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.