Webhooks and HTTP requests
Two builder actions talk to systems outside WordPress:
| Action | Direction | What for |
|---|---|---|
| Send webhook | site → other system | Notify n8n, Zapier, Make, a Joinotify Cloud flow or your ERP |
| HTTP request | round trip | Query an API and use the response in the next actions of the same workflow |
Both only call public addresses: local and private network addresses (localhost,
127.0.0.1, 10.x, 192.168.x and the like) are refused, including when they show up in a
redirect. Whoever edits a workflow cannot use them to reach the server's internal network.
Send webhook
Available since 2.5.0.
| Field | What it does |
|---|---|
| URL | The address that receives the call |
| Method | The HTTP method of the call |
| Body | The trigger's data (order, customer, user, cart) or Custom JSON |
| JSON | The JSON you write, with placeholders — when the body is custom |
| Headers | Extra headers, such as a token for the receiving system |
| Signing secret | Optional. Signs every call so the destination knows it came from your site |
With the trigger's data, the body is the same one the Joinotify Cloud sync builds: the order with the customer's purchase history and the links to pay, view and review it; the user; the cart; or the form entry.
Verifying the signature
With a secret filled in, every call carries two headers:
X-Joinotify-Timestamp: 1730640000
X-Joinotify-Signature-256: sha256=<HMAC-SHA256 of "timestamp.body" with the secret>It is the same scheme as Joinotify Cloud's webhooks, so the same verification code works — see Verify the signature.
Backslashes in the JSON
Until 2.7.0, saving the workflow dropped the backslashes typed in it, and an escaped quote
(\") in a JSON body turned into invalid JSON — the action never sent. 2.7.0 fixed it: workflows
keep backslashes as typed. A backslash lost in an earlier save has to be typed again.
HTTP request
Available since 2.7.0. Calls any public API and keeps the response under a name, which the following actions read as a placeholder.
| Field | What it does |
|---|---|
| Method and URL | GET, POST, PUT, PATCH or DELETE, and the address — which takes placeholders |
| Query parameters | Key and value pairs appended to the URL, already encoded |
| Headers | Extra headers. Yours win over the defaults (Accept, User-Agent, Content-Type) |
| Authentication | None, Bearer token, Basic (user and password) or API key in a header |
| Body | JSON, form fields, raw text, the trigger's data or no body |
| Response name | The name the next actions use to read the response |
| Timeout | Seconds to wait for the response: 10 by default, from 1 to 30 |
| When the request fails | Continue with the next actions (the default) or Stop the workflow |
Placeholders inside the strings of a JSON body are filled without breaking it, whatever quotes the value has. If the body is not valid JSON once filled in, the call does not go out and the reason is written to the log.
Reading the response
With the response kept as address, for example:
| Placeholder | What it carries |
|---|---|
{{ http:address.status }} | The HTTP code, such as 200 |
{{ http:address.ok }} | true for a 2xx code, false for anything else |
{{ http:address.error }} | The reason, when the call did not complete |
{{ http:address }} | The whole body (a JSON object comes out as JSON) |
{{ http:address.body.street }} | A field of the JSON body. Dots for nested keys and list positions: body.items.0.name |
They work in any action after the request — including after a Delay — and take
modifiers. To pick the path by the outcome, use a
Condition on {{ http:address.ok }}.
Response limits
The response is read up to 256 KB and follows at most 3 redirects. A body above 4 KB, JSON
encoded, is not kept — the HTTP code is. The limit exists because the response travels with the
workflow when a delay follows; developers change it with the
Joinotify/Builder/Http_Request_Action/Max_Stored_Bytes filter.
The credential
The token, the password or the API key are encrypted when the workflow is saved and never show on screen again — to change one, type it again. On another site (an imported workflow, a template) the credential does not come along and has to be typed again; until then, the action logs the error and does not call the API.
The AI workflow generator never uses this action.
For developers
The HTTP request is built on the same extension point any plugin can use: writes_payload on
joinotify_register_action(), which lets an action hand values to the next ones, and the
Joinotify/Builder/Sealed_Action_Fields filter, which encrypts secret fields on save. See
Developer resources.