DEV Community

Cover image for CF7 + ActiveCampaign: Why the "Account" Field Never Shows in Your Field Mapper
Rahul Sharma
Rahul Sharma

Posted on

CF7 + ActiveCampaign: Why the "Account" Field Never Shows in Your Field Mapper

A developer posted on the WordPress support forums that their CF7 to ActiveCampaign integration was missing the "Account" field in the mapping section. They could see the Account field clearly in their ActiveCampaign account. It just never appeared in the plugin's field mapper.

The plugin team said it was under development and would be released next week. The developer waited five weeks. Then posted again. The field was still missing. The thread was closed.

This is not a bug that will be fixed by waiting for a plugin update. The reason the Account field is missing from CF7 integration mappers is a fundamental difference in how ActiveCampaign structures its data.

Why the Account Field Is Different From Other Fields

In ActiveCampaign, a Contact and an Account are two separate types of records.

A Contact is a person: name, email, phone, custom contact fields. When your CF7 form submits and the plugin calls ActiveCampaign's API, it calls the Contacts endpoint and creates or updates a person record.

An Account in ActiveCampaign is a company record. It has its own fields: company name, website, industry, annual revenue. Contacts can be linked to Accounts, but an Account is not a field on a Contact. It is a separate object with its own API endpoint.

This is why the Account field does not appear in the field mapper. The plugin fetches the list of available fields from ActiveCampaign's Contact fields API. The Account field is not in that list because it is not a Contact field. It belongs to a different API endpoint entirely.

Most CF7 to ActiveCampaign integration plugins only work with the Contacts endpoint. They were not built to create or link Account records, which is a separate operation.

What the ActiveCampaign API Actually Requires

To create a Contact and link it to an Account in ActiveCampaign, you need two API calls.

The first call creates or updates the Contact:

POST https://youraccountname.api-us1.com/api/3/contacts
Enter fullscreen mode Exit fullscreen mode

The second call links that Contact to an Account:

POST https://youraccountname.api-us1.com/api/3/accountContacts
Enter fullscreen mode Exit fullscreen mode

The second call takes the Contact ID returned from the first call and the Account ID from ActiveCampaign. It creates the relationship between the two records.

If the Account does not exist yet, you first need to create it:

POST https://youraccountname.api-us1.com/api/3/accounts
Enter fullscreen mode Exit fullscreen mode

This is three API calls chained together, with IDs being passed from one response into the next request. That is a multi-step flow that most basic CF7 integration plugins were never designed to handle.

How to Actually Send Company Name to ActiveCampaign From CF7

There are two practical approaches depending on your situation.

The first approach is to store the company name as a custom Contact field in ActiveCampaign rather than as an Account. In your ActiveCampaign account, go to Settings then Custom Fields and create a new field called "Company" on the Contact object. This field will appear in your plugin's field mapper because it is a Contact field. Your CF7 form can map the company name field to it and it will be stored on the Contact record.

The downside is that this is not a proper ActiveCampaign Account record. It is just a text field on the Contact. If your team needs to use ActiveCampaign's Account features like account-level automation or company scoring, this workaround will not satisfy that requirement.

The second approach is to use a direct API integration that supports multi-step calls. Contact Form to API gives you control over the exact API endpoint and payload structure. You can configure it to call the ActiveCampaign Contacts endpoint with the person's details from your form. For the Account linking step, the Pro version supports chained API calls where the response from the first call is used in the second call.

The Faster Workaround: Use ActiveCampaign's Webhook Instead

If you need Account data in ActiveCampaign from CF7 submissions and do not want to build a custom PHP solution, you can use ActiveCampaign's own automation features as the middle layer.

Set up your CF7 integration to create the Contact record with whatever fields your plugin supports. Then create an ActiveCampaign automation that triggers when a new Contact is created. The automation can look up or create an Account based on the company name field you stored on the Contact, then link the Contact to that Account.

This pushes the Account logic into ActiveCampaign's automation engine where it belongs, and keeps your CF7 integration simple.

If You Need to Write This in PHP

For developers who want to own the full integration, here is the sequence of API calls:

add_action('wpcf7_before_send_mail', 'cf7_to_activecampaign_with_account');

function cf7_to_activecampaign_with_account($contact_form) {
    if ((int) $contact_form->id() !== YOUR_FORM_ID) return;

    $submission = WPCF7_Submission::get_instance();
    if (!$submission) return;

    $data    = $submission->get_posted_data();
    $api_key = defined('AC_API_KEY') ? AC_API_KEY : '';
    $api_url = defined('AC_API_URL') ? AC_API_URL : ''; // e.g. https://yourname.api-us1.com/api/3

    $headers = [
        'Api-Token'    => $api_key,
        'Content-Type' => 'application/json',
    ];

    // Step 1: Create or update the Contact
    $contact_res = wp_remote_post("$api_url/contacts", [
        'headers' => $headers,
        'body'    => wp_json_encode([
            'contact' => [
                'email'     => sanitize_email($data['your-email'] ?? ''),
                'firstName' => sanitize_text_field($data['your-firstname'] ?? ''),
                'lastName'  => sanitize_text_field($data['your-lastname'] ?? ''),
                'phone'     => sanitize_text_field($data['your-phone'] ?? ''),
            ],
        ]),
        'timeout' => 15,
    ]);

    $contact_body = json_decode(wp_remote_retrieve_body($contact_res), true);
    $contact_id   = $contact_body['contact']['id'] ?? null;
    if (!$contact_id) return;

    // Step 2: Create the Account (or find existing by name)
    $account_res = wp_remote_post("$api_url/accounts", [
        'headers' => $headers,
        'body'    => wp_json_encode([
            'account' => [
                'name' => sanitize_text_field($data['your-company'] ?? ''),
            ],
        ]),
        'timeout' => 15,
    ]);

    $account_body = json_decode(wp_remote_retrieve_body($account_res), true);
    $account_id   = $account_body['account']['id'] ?? null;
    if (!$account_id) return;

    // Step 3: Link the Contact to the Account
    wp_remote_post("$api_url/accountContacts", [
        'headers' => $headers,
        'body'    => wp_json_encode([
            'accountContact' => [
                'contact' => $contact_id,
                'account' => $account_id,
            ],
        ]),
        'timeout' => 15,
    ]);
}
Enter fullscreen mode Exit fullscreen mode

Store credentials in wp-config.php:

define('AC_API_KEY', 'your-activecampaign-api-key');
define('AC_API_URL', 'https://youraccountname.api-us1.com/api/3');
Enter fullscreen mode Exit fullscreen mode

Summary

The Account field is missing from CF7 integration mappers because it is not a Contact field in ActiveCampaign. It lives on a separate Account object that requires its own API endpoint and a separate API call to link to a Contact. Most CF7 plugins only map to Contact fields. The solutions are to store company name as a custom Contact field, use ActiveCampaign automations to handle the Account linking, or use a direct API integration that supports multi-step calls.

Top comments (0)