Docs: Reference & Troubleshooting

Documentation — Part 2

Deftmind Hookwright: reference & troubleshooting.

The second half of the guide. If you are setting up your first form, start with Part 1. (Pro) marks anything needing the paid add-on.

Bringing information in · Posts and pages · Draft posts (Pro) · Your existing form · Making it look right · When something goes wrong · Security software · Shortcode reference · Field names · Keeping your site safe · FAQ · Events · Glossary

← Back to Part 1: getting started · Part 3: sending a webhook when you publish (Pro) →

Bringing information into your site

This direction works the other way round: your platform sends information whenever it likes, and your site displays it.

Step 1 — Turn the door on

The plugin refuses all incoming information until you set a password. This is deliberate.

  1. Go to Deftmind Hookwright → Settings.
  2. Find Inbound shared secret.
  3. Type a long random password — at least 16 characters.
  4. Click Save Changes.
  5. Copy the Endpoint URL shown just above it.

Common mistake

Leaving the secret empty. Nothing will arrive and it will look broken. It is not broken — it is locked.

Step 2 — Send something

Have your workflow send a POST to that address, with a header named X-Hookwright-Secret containing your secret, and a body like this:

Sending information in
{
  "channel": "health-news",
  "title":   "New clinic opening in Kano",
  "body":    "## Opening times\n\nThe clinic opens on **Monday**."
}

channel is just a label you invent — a named stream. Channels create themselves the first time something arrives. Leave it out and it goes to a channel called default.

Step 3 — Show it on a page

Three common displays

No data yet.

No data yet.

No data yet.

The first shows the most recent item, the second shows a list, and the third updates itself every 30 seconds without a reload. Full options are in the shortcode reference.

How much is kept

Each channel remembers a set number of recent items — 10 by default, adjustable from 1 to 50 under Settings → Payloads kept per channel. Older items drop off automatically. Any posts already created from them are unaffected.

Turning what arrives into posts and pages

  1. Go to Deftmind Hookwright → Channels.
  2. In Add a rule, choose the Channel. You may name one that does not exist yet.
  3. Choose whether to create a Post or a Page.
  4. Choose a Status: Draft (always available), Pending review (Pro), or Publish immediately (Pro).
  5. Choose an Author — a real user allowed to write posts.
  6. For pages only, optionally choose a Parent page.
  7. Optionally choose a Default featured image.
  8. Click Add rule.

Strong recommendation

Start with Draft. Review a few, then switch to automatic publishing only once you trust the workflow. Automatic publishing means your secret alone can put content live on your site.

In the messageBecomes
titleThe post title
bodyThe post content, with Markdown formatted properly
categoriesAttached to existing categories only. Unknown names are skipped.
tagsAttached, and created if they do not exist.
An image fieldThe featured image

Duplicates are prevented automatically: the same channel, title and content will never create a second post, so a retry cannot double-publish.

Featured images

  1. image_id — the ID of something already in your Media Library. Free, and the safest.
  2. image_base64 — the image data sent directly. (Pro), and needs Inline image data switched on. Best when an AI generates the picture.
  3. image — a web address to download from. (Pro), and only from hosts you list under Allowed image hosts. Empty by default, so this is off until you allow a host.
  4. The rule’s default image — used when nothing else is supplied.

Every image is checked to confirm it really is a JPEG, PNG, GIF or WebP by examining the file itself, not by trusting its name. Oversized images are skipped and the post is still created.

Turning replies into draft posts (Pro)

This works the other way round: it saves the answers your workflow gives to form submissions.

  1. Open a form under Deftmind Hookwright → Forms.
  2. Scroll to Publish replies.
  3. Tick to enable it, and choose the post type, status, author and default image.
  4. Click Save form.

“Create as” offers every post type on your site — Post, Page, and any custom post type you have, such as Products, Events or Staff. A form’s answers can be filed straight into whichever kind of content they belong to.

  • Works with Wait for and show the reply and with Callback, with no extra setup in either case.
  • Not available in chat mode, because every chat message is an answer and you would drown in drafts.
  • Identical answers never create a second post.

Using this to generate content

This is what people usually reach for it: your workflow writes something, and it lands in WordPress as a post you can review.

The shape is always the same, and nothing about it is specific to any one kind of workflow:

  1. A visitor fills in the form — a topic, a question, a brief.
  2. Your workflow does whatever it does with that. It might look something up in a database, assemble a report from several sources, run a calculation, or call a language model to write an article.
  3. It sends back an answer carrying a title, the body in Markdown, and optionally categories and tags.
  4. Deftmind Hookwright shows the visitor the answer and saves it as content.

Two things make this safe to leave running

Draft is the default status. Generated content waits for you to read it before anything goes live. Only change that once you trust the workflow.

Identical answers never create a second post, so a retried submission cannot double-publish.

If the work takes a while — a long article, or several steps — use Callback so the visitor is not left waiting on an open connection. Publishing works exactly the same either way, with no extra setup.

You can also start this from the other direction, with no visitor involved at all: have a scheduled job in your automation platform send finished content to your site’s inbound address, and turn on publishing for that channel (see Turning what arrives into posts and pages). Same result, no form.

Using a form you already have

If you already have a form and do not want to rebuild it, you can hand its submissions to Deftmind Hookwright. This step needs someone comfortable editing HTML.

Add one attribute to your form
<form data-hookwright-bridge
      data-hookwright-endpoint="ask-health"
      data-hookwright-response="#my-answer">
  <input type="text" name="question" />
  <button type="submit">Ask</button>
</form>

<div id="my-answer"></div>
  • data-hookwright-endpoint chooses which saved form’s settings to use — including its response mode, so callback works here too. The web address always stays on the server; the browser never sees it.
  • data-hookwright-response is optional. Without it, the answer appears just after the form.

Important

Do not add this to forms built by WPForms, Gravity Forms, Contact Form 7 or a page builder. Those run their own submission code and the two will fight.

Making it look right

Without writing any code

SettingWhat it does
Accent colourTints the button and the form’s border.
LayoutStacked puts labels above boxes. Inline puts everything on one row, like a search box.
BorderMatch the accent colour, pick a custom colour, or remove it.
Chat area colourThe background behind chat messages.
Extra CSS classFor a designer to target this one form.

None of these change what is sent or received. They are purely visual.

With CSS

Go to Appearance → Customize → Additional CSS.

Common adjustments
/* Remove the card, leaving plain fields */
.hookwright-form { border: none; padding: 0; background: transparent; }

/* Change just the border colour */
.hookwright-form { border-color: #cccccc; }

/* Target one form using its Extra CSS class */
.hookwright-form.my-form { border-radius: 0; }

Useful class names: .hookwright-form, .hookwright-submit, .hookwright-response, .hookwright-thread, .hookwright-bubble-user, .hookwright-bubble-assistant, .hookwright-items, .hookwright-item.

When something goes wrong

What visitors see

What happenedWhat they see
Your workflow was too slowThis is taking longer than usual. Please try again in a moment.
Your workflow could not be reachedThe service is temporarily unavailable.
Your workflow answered but sent nothingThat went through, but no reply came back to show.
A callback deadline passedNo reply arrived in time. Please try again.

Their typed text is always kept so they can retry without retyping.

Adding your own message

  1. Go to Settings → If a send fails, add for the whole site, or set it per form.
  2. Type something like: You can also email us at hello@example.com and we will reply personally.
  3. Save.

Plain text only, up to 500 characters. It appears only on genuine failures.

How you find out

Three places, all administrator-only, and all appearing only when something has actually gone wrong:

  1. Settings → Recent send problems — the full picture, kept for 24 hours.
  2. A Dashboard widget — the three most recent problems.
  3. An admin notice — elsewhere in the admin area.

Troubleshooting checklist

ProblemTry this
Nothing happens when I submitCheck the Form ID in the shortcode matches the form exactly.
“This form is not configured”The Webhook URL is empty or was rejected. It must be a public address.
Visitors see an error but my test worksLook at Recent send problems. A test and a real submission take different routes.
A field is not arrivingCheck its name is listed in the Fields box. Unlisted fields are dropped.
Nothing arrives from my platformThe Inbound shared secret is missing, or the header name is misspelled. It must be exactly X-Hookwright-Secret.
The answer shows as a table when I wanted proseYour field name is not one the plugin recognises, or set Response rendering to Markdown.
Callback answers never arriveConfirm your workflow reads the return address from each message, then read the next section.
Everything worked, then stoppedRead the next section.
Important

Security software that can break the plugin

This section exists because it is genuinely hard to diagnose, and it is not a fault in the plugin.

Many hosts and security services put a bot check in front of your site — a page saying “Checking your browser before accessing” that runs briefly before letting you through. A real person’s browser passes it without noticing.

Your automation platform is not a browser. It cannot pass that check. If your host applies it to the address your platform is sending to, then:

  • Information sent into your site never arrives.
  • Callback answers never arrive.
  • In the worst cases, ordinary form submissions fail now and then and visitors see “Something went wrong.”

How to tell if this is your problem

Everything looks correct, and your automation platform reports an error or a 403 when it tries to reach your site. Ask your host, or check your security plugin, and look at what happens to this address:

Check this address
https://your-site.com/wp-json/

If a bot check or firewall rule stands in front of it, that is your answer.

How to fix it

Ask your host, or use your security plugin’s settings, to exempt this address from bot checks and firewall rules:

Exempt this path
/wp-json/hookwright/

That is narrow enough to be safe. It exempts only this plugin’s own doors, which have their own passwords, and leaves the rest of your site protected.

Services that commonly do this: Cloudflare (Bot Fight Mode, WAF rules), Hostinger, SiteGround, WP Engine, Wordfence, Sucuri, All In One WP Security.

Tip

If you are testing and things behave inconsistently — working once, failing the next time — suspect this before suspecting the plugin.

Shortcode reference

— put a form on a page

OptionValuesNotes
ida Form IDLeave out to use the site-wide settings instead.
response_renderauto, markdown, table, jsonOnly used when id is left out.

— put a form’s answer somewhere else

OptionNotes
idThe Form ID this container belongs to.
classExtra CSS class names.

Works with callback mode — see where the answer appears.

No data yet.

— show information sent into your site

OptionValuesNotes
channelany nameWhich stream to show. Default default.
modelatest, listOne item, or a list.
count1 to 20How many items a list shows.
ordernewest, oldestSort direction.
offset0 to 49Skip this many first.
fielda pathShow only part, such as field="stats.views".
renderauto, markdown, table, jsonHow to display it.
refresh0, or 5 and aboveSeconds between automatic checks. 0 means never.
archivea web addressWhere category and tag links point.
metaauto, nonenone hides category and tag labels.

Letting people attach a file

Add a field of type file and the visitor gets a button to attach something:

A form that takes a receipt
receipt | Your receipt | file:pdf,png | required

The part after the colon lists what you will accept. Leave it off — just file — and everything the plugin can check is accepted:

PDF, JPEG, PNG, GIF, WebP, Word, Excel, PowerPoint, plain text and CSV. Nothing else. Naming a type that is not on that list simply drops it from your list rather than allowing it, and the report under the Fields box tells you so.

Every file is checked against what is inside it, not what it is called

Renaming something to .png does not get it through. Even a spreadsheet renamed to .docx is refused, because Word, Excel and PowerPoint files are told apart by their actual contents.

Two things are never accepted at all: SVG images, because they can carry hidden instructions, and zip files, because there is no way to tell a harmless one from a harmful one.

Nothing is stored on your site

Not in the Media Library, not in your uploads folder, not in your database. Each file is checked, passed straight to your webhook, and forgotten. There is no link for anyone to find later and nothing to tidy up.

What your workflow receives

Attachments do not arrive among the other answers. They come in a separate group called attachments, so a workflow that already reads your form’s answers cannot break when you add a file field.

What arrives at your webhook
{
  "fields": { "full_name": "Sam" },
  "attachments": {
    "receipt": {
      "filename": "receipt.pdf",
      "type": "application/pdf",
      "size": 184320,
      "data": "JVBERi0xLjcK…"
    }
  }
}

Look under attachments, not fields. The data part is the file itself, written the way files are normally sent inside a message like this. Most automation platforms have a step that turns it back into a file — in n8n it is Convert to File → Base64 to File.

Size, and what your host allows

You choose the limit on the Settings screen, and it starts at 2 MB per file. Some hosts cannot carry that much, so the screen tells you what your server will really accept, and visitors are held to the real figure rather than discovering it half way through an upload. Up to five files can be sent in one submission.

Before you promise anyone privacy

The file reaches your workflow intact and will usually sit in that platform’s history until you delete it or it ages out. If someone sends you a passport scan, that scan is in your automation tool’s logs.

Ask only for files you actually need, and say in your privacy policy what happens to them. “We do not store it” is true of this plugin and not necessarily true of the service you forward it to.

Field names the plugin understands

Whenever your workflow sends something — an answer to a form, or information into your site — the plugin looks for these names. Capital letters, underscores, dashes and spaces are ignored.

What it isNames it accepts
The main textbody, markdown, content, text, answer, reply, message, output, article, description, summary
A headingtitle, post_title, subject, heading, headline, name, label
Categoriescategories, category, cats, sections, topics
Tagstags, tag, keywords, terms, labels
An imageimage_id (free), image_base64 (Pro), image / featured_image / image_url (Pro)
The stream namechannel — only when sending information into your site

Wrappers removed automatically: data, payload, result, results, json, output, item, items, record, fields, attributes, object, and a list containing exactly one item. Up to four layers deep.

Nothing is required. If none of these names appear, your information is displayed as a labelled table instead of an article.

How your site is kept safe

  • The incoming door is locked by default. It stays shut until you set a password of at least 16 characters.
  • Your webhook address and any password attached to it never reach the visitor’s browser. Everything is sent from your server.
  • Your site will not be tricked into contacting itself or your internal network. Addresses are checked when saved and again every time they are used.
  • Failure messages give nothing away. A blocked address and an unreachable one produce exactly the same message, so nobody can use your form to map your network.
  • Nothing sent to your site can run code on your page. Text is displayed as text; HTML in a message is shown as characters, not executed.
  • Every image is verified by examining the file itself.
  • Forms are rate-limited per visitor, and a hidden trap field quietly absorbs automated spam.
  • Callback answers use two separate one-time passwords. One goes to your automation platform and can only deliver an answer. The other stays in the visitor’s browser and is the only thing that can read it. Knowing one never gives you the other, and both expire within minutes.

Reporting a security problem

If you believe you have found a vulnerability, please email support@deftmindlabs.com rather than posting it publicly, so it can be fixed before anyone can act on it. Reports are welcome, taken seriously, and acknowledged.

Frequently asked questions

QuestionAnswer
Can I get a refund?Billing is handled by Freemius as merchant of record, and their refund policy governs the transaction. The option chosen for these products is No refunds: because the plugin is a digital download, refunds are not generally offered. A full refund is given on request within 14 days only if the plugin was never downloaded. Requests after download are considered individually at our discretion, and must be made within 14 days of purchase. The paid 7-day trial exists precisely so you can evaluate the plugin in full before any charge is taken.
Do I need an AI subscription?No. The plugin has no AI of its own. If your workflow uses AI, that is arranged on your platform.
Where are my API keys stored?Not here. Any password you set for your webhook stays on your server and is never sent to a browser.
Can I have more than one form?Yes. The free plugin allows one saved form; Pro raises that considerably. You can always use the site-wide settings without creating a named form.
Can two forms use different workflows?Yes. Each form has its own address and settings.
Will this slow my site down?No. Nothing happens until someone submits a form or your platform sends something. Callback is lighter than waiting, because your server is not held open.
Can visitors see my webhook address?No. Submissions go to your own server first, which passes them on.
What if my workflow is down?The visitor sees a polite failure message with their text preserved, and you get a record under Recent send problems.
Does the answer stay after a reload?No. Use Publish replies if you want it saved.
Can I display a form answer with

No data yet.

?
No. That is only for information your platform sends in. Use
for form answers.
My workflow takes three minutes. Possible?Yes — use Callback mode and set the deadline high enough.
Can I use callback with chat?Not currently. Chat forms wait for the reply directly.
How do I test a callback without a real visitor?Put the form on a draft page and preview it yourself. The Test webhook button carries no return address, so it cannot test the reply itself.
Is my visitors’ data stored?Form submissions are passed to your workflow and not stored. Chat conversations are never stored. Only information sent into your site is stored, and only as much as your retention setting allows.

Events — sending what happens on your site

An event is a moment your automation platform should know about — a visitor landing on a page, clicking a button, or a post going live. Instead of polling on a schedule, your automation receives them the moment they happen.

Go to Deftmind Hookwright → Events, enter a webhook URL, and tick Enable website events. Two kinds are available and each is independent:

KindWhat fires it
Browser eventsA visitor loads a page, clicks an element, or follows a link — detected in their browser
WordPress eventsA post publishes for the first time, a comment is approved, or someone registers an account

Every payload includes a source field — "browser" or "wordpress" — so one workflow can handle both with a simple branch.

Browser events — what your visitors do

Each rule has a label (what fires it in your workflow), a trigger (Page loaded, Element clicked, or Link followed), a URL pattern (which pages), and optionally a CSS selector for click rules. Uncheck a row to pause it without deleting it.

URL patterns: / = homepage only · /shop/ = that page exactly · /shop/* = that page and everything below · * = every page.

Events only fire after your consent tool signals agreement by default. Change Consent to Do not require a consent signal if your setup does not need this. To capture data from a landing URL (for example an order ID after checkout), name the parameter under Capture query parameters.

Sample payload — browser event:

{
  "event_id": "f840100a-0f5f-4cc6-9a57-08d6f50d9324",
  "event_name": "page_view",
  "event_time": "2026-08-08T22:20:40+00:00",
  "source": "browser",
  "page_url": "https://example.com/",
  "page_title": "Welcome to our site",
  "referrer_url": "https://google.com/",
  "utm": { "utm_source": "google", "utm_medium": "organic", "utm_campaign": "" },
  "session_attribution": { "utm_source": "google", "utm_medium": "organic" },
  "event_data": { "rule_name": "Homepage viewed" }
}
FieldWhat it contains
event_idUnique ID — use it to deduplicate retries
event_namepage_view, click, or redirect
sourceAlways "browser" for this kind
page_url / page_titleThe page the visitor was on
referrer_urlWhere they came from — empty if they typed the address directly
utm / session_attributionCampaign parameters from this page’s URL, and the first ones seen this session
event_data.rule_nameThe label you gave this rule

WordPress events — what happens inside WordPress

No rules to write — tick which types to send: post published (first time only), comment approved, user registered. A post fires once; taking it back to draft and republishing does not fire again. Password-protected posts and autosaves are ignored.

Sample payload — WordPress event:

{
  "source": "wordpress",
  "site": "https://example.com",
  "data": {
    "post_id": 95,
    "post_type": "post",
    "title": "Our new product is here",
    "url": "https://example.com/our-new-product/",
    "excerpt": "A short preview of the post.",
    "author_id": 1,
    "author_name": "admin",
    "published": "2026-08-08T21:56:42+00:00",
    "categories": ["News", "Products"],
    "tags": ["launch"]
  }
}

The full post body is not included. Your workflow can fetch it from the REST API using the url in the payload. Email addresses in comment and registration events are off by default — turn them on in the Events settings if you need them.

Nothing is stored on your site. Each event is forwarded to your webhook and then forgotten — no cookie set, no visitor identifier created, no database row written.

Sending a webhook when you publish (Pro)

Everything above is about bringing information into your site. The opposite direction — sending a webhook out the moment a post, page or custom post type is published, with your own custom fields and optional signing — now has a page of its own.

Glossary

TermMeaning
Automation platformThe outside service where your logic runs — n8n, Make, Zapier and so on.
CallbackAnswering later, by sending the answer to an address, instead of staying on the line.
ChannelA named stream of information sent into your site.
DeadlineHow long a visitor waits for a callback answer.
EndpointA web address that accepts information.
FieldOne box on a form.
JSONA simple text format for exchanging information between computers.
MarkdownSimple formatting for text.
PayloadOne package of information.
POSTThe kind of web message used to send information somewhere.
Return URLThe one-time address your workflow sends a callback answer to.
ShortcodeText in square brackets that WordPress turns into something real.
WebhookA web address that accepts information sent by another computer.
WorkflowOne piece of automation logic you have built.