Webhooks

  • JNext lesson
  • KPrevious lesson
  • FSearch lessons
  • EscClear search

Webhooks turn a form submission into an HTTP POST to any URL you choose, which makes Core Forms a front end for Zapier, n8n, Make, your CRM, or any API that accepts JSON. No integration plugin per service, just one webhook action pointed at the right endpoint.

Setting Up a Webhook

  1. Edit your form and go to the Actions tab.
  2. Select Trigger Webhook from the action type dropdown.
  3. Click Add Action.
  4. Configure the webhook settings.
  5. Save the form.

Configuration

Webhook URL (Required)

The URL that will receive the form data via POST request.

https://hooks.zapier.com/hooks/catch/123456/abcdef/

Content Type

Choose how the data is sent:

  • application/json – Sends the form data as a JSON object in the request body.
  • application/x-www-form-urlencoded – Sends the form data as URL-encoded form fields (default).

Authentication (Optional)

If the receiving endpoint requires authentication, you can set a custom header:

  • Header Name – The name of the authentication header (e.g., Authorization, X-API-Key, X-Auth-Token).
  • Header Value – The authentication value (e.g., Bearer your-api-token, sk_live_abc123).

Request Format

JSON Content Type

When using application/json, the request body contains the submission data as a JSON object:

{
    "name": "John Doe",
    "email": "john@example.com",
    "message": "Hello from Core Forms"
}

Form-Encoded Content Type

When using application/x-www-form-urlencoded, the data is sent as standard form fields:

name=John+Doe&email=john%40example.com&message=Hello+from+Core+Forms

Request Headers

Every webhook request includes:

  • Content-Type header matching the selected content type
  • Referer header set to the WordPress site URL
  • Custom authentication header (if configured)

Filtering the Request

Use the cf_webhook_request_args filter to modify the request before it is sent:

add_filter( 'cf_webhook_request_args', function( $args, $settings, $submission, $form ) {
    // Add a custom header
    $args['headers']['X-Form-ID'] = $form->ID;

    // Modify the body
    if ( $settings['content_type'] === 'json' ) {
        $data = json_decode( $args['body'], true );
        $data['source'] = 'website';
        $data['form_slug'] = $form->slug;
        $args['body'] = json_encode( $data );
    }

    return $args;
}, 10, 4 );

Handling the Response

The cf_webhook_response action fires after the request completes, giving you access to the response:

add_action( 'cf_webhook_response', function( $response, $settings, $submission, $form ) {
    if ( is_wp_error( $response ) ) {
        error_log( 'Webhook failed: ' . $response->get_error_message() );
        return;
    }

    $status_code = wp_remote_retrieve_response_code( $response );
    $body = wp_remote_retrieve_body( $response );

    if ( $status_code >= 400 ) {
        error_log( "Webhook returned $status_code: $body" );
    }
}, 10, 4 );

Multiple Webhooks

You can add multiple webhook actions to a single form. Each webhook runs independently with its own URL, content type, and authentication settings. All webhooks fire on every successful submission.

Error Handling

Webhook requests use WordPress’s wp_remote_post() function. If the request fails (network error, timeout, etc.), the function returns a WP_Error. The form submission still succeeds from the user’s perspective. Webhook failures do not prevent the success message from being shown.

If you need to track webhook failures, use the cf_webhook_response action to log errors.

Webhooks pair naturally with other form actions: email yourself AND push to the CRM. For inspecting what fires when, the hooks reference covers the underlying action.