DEV Community

Cover image for How to Trigger a Mailchimp Drip Sequence from a CF7 Form (Without a Checkbox)
Rahul Sharma
Rahul Sharma

Posted on

How to Trigger a Mailchimp Drip Sequence from a CF7 Form (Without a Checkbox)

A developer posted this on the WordPress support forums:

"We'd like to send the auto-reply email after a visitor submits a CF7 form directly from Mailchimp. We have a drip campaign set up and a dedicated Mailchimp list. Is it possible to sign up everyone that submits a contact form to this list without displaying a checkbox?"

The reply was a link to a code snippet for setting a Mailchimp tag on CF7 submission. One sentence. Thread closed.

That answer is technically correct but skips everything that matters: how Mailchimp's automation system actually works, what the consent implications of silent opt-in are, and how to build the full CF7 to Mailchimp automation flow properly.

This post covers all of it.

What the Developer Is Actually Trying to Build

The goal is:

  1. Visitor submits CF7 contact form
  2. Visitor is added to a Mailchimp audience silently (no checkbox)
  3. A tag is applied to that contact
  4. A Mailchimp automation triggers based on that tag
  5. The automation sends a sequence of emails (drip campaign)

This is a legitimate use case. It is used for post-inquiry follow-up sequences where the "subscription" is incidental to the contact request, not a marketing list signup.

Before building it, the consent question matters.

The Consent Question: Can You Silent-Subscribe Someone?

Mailchimp's terms of service require that contacts added to an audience have given consent to receive marketing emails. Adding someone to a Mailchimp audience without their knowledge and then sending them a marketing drip sequence is a violation of Mailchimp's terms and, depending on jurisdiction, of GDPR, CAN-SPAM, or CASL.

However, the developer's use case is transactional auto-replies, not marketing. This is a meaningful distinction:

Transactional emails are messages sent in direct response to an action the user took (submitting a form, making a purchase, requesting information). These do not require marketing consent under most regulations.

Marketing emails are messages sent to promote products, services, or content. These require explicit consent.

If your Mailchimp drip sequence is genuinely transactional (confirmation of their inquiry, information they requested, follow-up on their specific request), the consent requirement is lower. If it promotes your services beyond what was requested, it is marketing and requires consent.

Mailchimp itself does not distinguish transactional from marketing in its standard Audiences. For genuine transactional email, Mailchimp Transactional (formerly Mandrill) is the correct product. For a marketing automation triggered by a form submission with implied consent, a clear notice in your form's privacy policy link is the minimum acceptable approach.

For this post, we will assume the use case is legitimate auto-replies where the contact has reasonable expectation of receiving follow-up communication.

How Mailchimp Automations and Tags Work

Understanding the Mailchimp data model is required before writing any code.

Audience (formerly List): The top-level container for contacts in Mailchimp. Every contact belongs to one or more audiences. You pay per contact per audience.

Tag: A label applied to a contact within an audience. Tags do not add costs. A contact can have multiple tags.

Automation (Customer Journey): A sequence of emails and actions triggered by a specific event. The event that triggers the developer's drip sequence is "contact is added to audience" or "tag is applied to contact."

The correct architecture for this use case:

CF7 submission
    |
    v
Add contact to Mailchimp audience via API
    |
    v
Apply specific tag (e.g. "contact-form-inquiry")
    |
    v
Mailchimp automation triggers on tag applied
    |
    v
Drip email 1 sent immediately
    |
    v (7 days later)
Drip email 2 sent
Enter fullscreen mode Exit fullscreen mode

The tag is the trigger, not the audience membership alone. This lets you have one audience with multiple automations triggered by different tags from different forms.


Implementation: Three Approaches

Approach 1: MC4WP Plugin + Code Snippet (What the Forum Suggested)

The MC4WP plugin connects CF7 to Mailchimp. By default it shows a checkbox. To remove the checkbox and subscribe silently, add a tag based on which form was submitted:

// Add to functions.php
// Source: ibericode/mailchimp-for-wordpress sample snippets

add_filter('mc4wp_integration_cf7_tags', function($tags, $form) {
    // Apply different tags based on form ID
    $form_tag_map = [
        123 => ['contact-form-inquiry'],    // replace with your form IDs
        456 => ['quote-request'],
        789 => ['newsletter-signup'],
    ];

    $form_id = (int) $form->id();

    if (isset($form_tag_map[$form_id])) {
        $tags = array_merge($tags, $form_tag_map[$form_id]);
    }

    return $tags;
}, 10, 2);
Enter fullscreen mode Exit fullscreen mode

For silent subscription (no checkbox), configure MC4WP's CF7 integration with "Implicit sign-up" enabled in the plugin settings. This subscribes the contact on every form submission without showing a UI element.

Limitation: MC4WP's implicit signup adds contacts to whichever audience you configure globally. If you need different audiences per form, you need the approach below.

Approach 2: Direct Mailchimp API Call from CF7 Hook

This gives full control: which audience, which tags, which status, per form. No MC4WP required.

add_action('wpcf7_before_send_mail', 'cf7_to_mailchimp_silent');

function cf7_to_mailchimp_silent($contact_form) {
    $form_id = (int) $contact_form->id();

    // Map form IDs to Mailchimp audience IDs and tags
    $form_config = [
        123 => [
            'audience_id' => 'abc123def4',   // your Mailchimp audience/list ID
            'tags'        => ['contact-form-inquiry'],
        ],
        456 => [
            'audience_id' => 'abc123def4',
            'tags'        => ['quote-request'],
        ],
    ];

    if (!isset($form_config[$form_id])) return;

    $config      = $form_config[$form_id];
    $submission  = WPCF7_Submission::get_instance();
    if (!$submission) return;

    $data        = $submission->get_posted_data();
    $email       = sanitize_email($data['your-email'] ?? '');
    $name_parts  = explode(' ', sanitize_text_field($data['your-name'] ?? ''), 2);
    $first_name  = $name_parts[0] ?? '';
    $last_name   = $name_parts[1] ?? '';

    if (empty($email)) return;

    $api_key     = defined('MAILCHIMP_API_KEY') ? MAILCHIMP_API_KEY : '';
    $server      = substr($api_key, strpos($api_key, '-') + 1); // e.g. "us21"
    $audience_id = $config['audience_id'];
    $member_hash = md5(strtolower($email));

    // Add or update the contact (PUT is idempotent - updates if exists)
    $response = wp_remote_request(
        "https://{$server}.api.mailchimp.com/3.0/lists/{$audience_id}/members/{$member_hash}",
        [
            'method'  => 'PUT',
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode('anystring:' . $api_key),
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode([
                'email_address' => $email,
                'status_if_new' => 'subscribed',  // only sets status for NEW contacts
                'merge_fields'  => [
                    'FNAME' => $first_name,
                    'LNAME' => $last_name,
                ],
            ]),
            'timeout' => 15,
        ]
    );

    if (is_wp_error($response)) {
        error_log('[CF7->Mailchimp] Member upsert failed: ' . $response->get_error_message());
        return;
    }

    $status_code = wp_remote_retrieve_response_code($response);
    if ($status_code >= 400) {
        error_log('[CF7->Mailchimp] API error ' . $status_code . ': ' . wp_remote_retrieve_body($response));
        return;
    }

    // Apply tags separately (tag endpoint accepts array of tag operations)
    $tags_payload = array_map(fn($tag) => ['name' => $tag, 'status' => 'active'], $config['tags']);

    wp_remote_post(
        "https://{$server}.api.mailchimp.com/3.0/lists/{$audience_id}/members/{$member_hash}/tags",
        [
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode('anystring:' . $api_key),
                'Content-Type'  => 'application/json',
            ],
            'body'    => wp_json_encode(['tags' => $tags_payload]),
            'timeout' => 15,
        ]
    );
}
Enter fullscreen mode Exit fullscreen mode

Store your API key in wp-config.php:

define('MAILCHIMP_API_KEY', 'your-key-here-us21');
Enter fullscreen mode Exit fullscreen mode

Key decisions in this code:

  • PUT to the member endpoint instead of POST. PUT is idempotent: if the contact already exists, it updates them. POST on an existing contact returns a 400 error. Using PUT prevents duplicates.
  • status_if_new: subscribed sets the status only for brand-new contacts. It does not change an existing contact's subscription status (so someone who previously unsubscribed stays unsubscribed).
  • Tags are applied in a separate API call via the /tags endpoint because the main PUT endpoint does not accept tag modifications directly.
  • member_hash is md5(lowercase email), which is how Mailchimp identifies members in its API.

Approach 3: Contact Form to API Plugin

Contact Form to API handles the Mailchimp API call from a configuration UI. Set the Mailchimp audience endpoint, configure the Authorization header with your API key, and map CF7 fields to the Mailchimp payload. No PHP deployment required, and the field mapping updates happen in the WordPress dashboard when form fields change.

Setting Up the Mailchimp Automation to Trigger on Tag

Once contacts are being added and tagged, configure the Mailchimp automation:

  1. Go to Automations > Customer Journeys
  2. Click Create Journey
  3. Set the starting point to "Tag is added"
  4. Select the tag you are applying from CF7 (e.g. contact-form-inquiry)
  5. Add your email steps with delays between them (e.g. immediate email, then one week later)
  6. Activate the journey

When CF7 applies the tag to a new contact, Mailchimp's automation fires immediately.

Important: the automation only fires for contacts who receive the tag while the journey is active. Contacts tagged before the journey was activated do not enter the journey retroactively.

Audience ID: Where to Find It

The audience ID is not the same as the audience name. Find it at:

Mailchimp > Audience > Manage Audience > Settings > Audience name and defaults

The ID is shown in the URL and in the settings panel. It looks like abc123def4 (10 characters, alphanumeric).

Top comments (0)