The Webhook action sends each submission to any web address you choose — your own endpoint, an automation service like Zapier or Make, or another app’s API. It’s the most flexible action: you decide the address, the request method, and exactly which fields are sent and under what names.
Settings
- URL — The address the submission is sent to. It has to start with
http://orhttps://. You can build the URL from submitted values using field variables. - Method — The HTTP method for the request. POST (the default) is what most endpoints expect. GET sends the fields as a query string on the URL. PUT, PATCH, and DELETE are there for REST-style APIs.
- Body — The data to send, as key/value pairs. The key is the name the field arrives under on the receiving side; the value is what’s sent — type a fixed value, or insert a form field with a variable. Add one row per field you want to include. This is where you map “my form field → the name the endpoint expects.”
More options
- Body format — How the body is encoded for POST, PUT, PATCH, and DELETE requests. JSON (the default) sends a JSON object; Form-encoded sends it the way a normal HTML form would. For GET requests the fields always go in the query string, so this setting doesn’t apply. Mosaic sets the matching
Content-Typeheader for you unless you set your own. - Headers — Extra HTTP headers to send, as key/value pairs. Use these for authentication (for example an
AuthorizationorX-API-Keyheader) or to set your ownContent-Type. Header values are hidden in your stored submission logs so credentials stay out of your records.
Test on the frontend, as the backend Preview doesn’t run actions!
Good to know
- The request waits up to 10 seconds for a reply and does not follow redirects, so point the URL at the exact endpoint.
- If the endpoint returns an error or can’t be reached, the action is marked as failed on the submission and can be retried from your WordPress dashboard. A short excerpt of the response is saved to help you debug, with your header values masked out.
- The Webhook action doesn’t store the submission in WordPress on its own. If you also want a record under Mosaic → Form submissions, add an Email, Mailchimp, or MailerLite action to the same form.
Example
A minimal PHP endpoint for testing the Webhook action — it logs every request it receives, so you can see exactly what your form sends.
How to use
- Put this file somewhere your Mosaic site can reach over http/https — for example
.../wp-content/uploads/webhook-test.php(on a local install, the same domain works). - In the Webhook action, set the URL to this file, e.g.
https://your-site.com/wp-content/uploads/webhook-test.php. - Submit the form on the frontend of your website (not in the backend Preview, as that doesn’t run actions). Each request is appended to a
webhook-test.logfile next to it — open it to see the method, headers, and the data Mosaic sent.
<?php
/**
* Minimal webhook receiver for testing the Mosaic Form "Webhook" action.
*/
// --- collect the request -----------------------------------------------------
$method = $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN';
$headers = function_exists('getallheaders') ? getallheaders() : [];
$rawBody = file_get_contents('php://input');
// Try to decode the body: JSON first, then form-encoded, else raw.
$parsed = json_decode($rawBody, true);
if (json_last_error() !== JSON_ERROR_NONE) {
if ($rawBody !== '') {
parse_str($rawBody, $parsed); // form-encoded body
} else {
$parsed = $_GET; // GET: data is in the query string
}
}
// --- build a readable log entry ---------------------------------------------
$entry = str_repeat('=', 60) . "\n";
$entry .= '[' . date('Y-m-d H:i:s') . "] {$method} request\n";
$entry .= "-- Headers --\n";
foreach ($headers as $name => $value) {
$entry .= " {$name}: {$value}\n";
}
$entry .= "-- Raw body --\n " . ($rawBody !== '' ? $rawBody : '(empty)') . "\n";
$entry .= "-- Parsed data --\n";
$entry .= ' ' . print_r($parsed, true) . "\n";
// --- write it next to this file ---------------------------------------------
file_put_contents(__DIR__ . '/webhook-test.log', $entry, FILE_APPEND | LOCK_EX);
// --- respond 200 so the action counts as delivered --------------------------
http_response_code(200);
header('Content-Type: application/json');
echo json_encode(['ok' => true, 'received' => $parsed]);