Form action: Webhook

Form action: Webhook

This doc is about the Webhook action. Learn how to send form submissions to any HTTP endpoint — your own server, Zapier, Make, or another API — with configurable methods, field mapping, and headers.

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:// or https://. 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-Type header for you unless you set your own.
  • Headers — Extra HTTP headers to send, as key/value pairs. Use these for authentication (for example an Authorization or X-API-Key header) or to set your own Content-Type. Header values are hidden in your stored submission logs so credentials stay out of your records.
Notice

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.log file next to it — open it to see the method, headers, and the data Mosaic sent.
Code
<?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]);

Last updated: August 5, 2026

Still have more questions? Let us help!

Your cookie preferences

We use cookies to improve your experience, analyze traffic, and personalize content. By clicking "Accept all" you agree to storing them on your device. Read our privacy policy.