You have built a Contact Form 7 form. You have connected it to Keap (formerly Infusionsoft) through the "Contact Form to Any API" plugin. You have entered your API credentials and mapped the fields. And yet, when a user submits the form, no contact appears in your Keap CRM.
This is a frustratingly common problem. The good news? The issue is almost always one of four things, and each has a clear fix. This guide walks through the exact debugging process, common error patterns, and verified solutions.
Understanding the Data Flow
When a user submits your CF7 form with Keap contact creation enabled, here is what should happen:
User submits form → Plugin captures data → API request sent to Keap → Contact created
When it breaks, the failure happens at one of the last two stages. Your first diagnostic tool is the plugin's API Logs page. It shows whether a request was sent, the exact JSON payload, and the response from Keap. If no request appears in the logs, the problem is on the WordPress side. For a deeper breakdown of that specific scenario, see this guide on Contact Form 7 data not reaching the API.
Failure #1: The Infusionsoft Field Prefix Is Missing
What you see: The plugin's logs are empty, or Keap returns an error. The form submits successfully, but no contact is created.
Why it happens: Older CF7-to-Infusionsoft integrations require a specific field naming convention. Every form field that should be sent to Infusionsoft must be prefixed with infusionsoft-. If your CF7 field is named your-email but the integration expects infusionsoft-email, the data never reaches the API.
The fix:
Step 1: Rename your CF7 fields. In the CF7 form editor, ensure every field you want to send to Keap uses the infusionsoft- prefix.
For example:
[text* infusionsoft-first-name placeholder "First Name"]
[email* infusionsoft-email placeholder "Email"]
[tel infusionsoft-phone placeholder "Phone"]
Step 2: Update your field mappings. In the API plugin's mapping configuration, match the prefixed CF7 field names to the Keap API parameters.
Step 3: Test with a minimal form. Create a simple test form with only infusionsoft-first-name and infusionsoft-email. Submit it and check Keap for the new contact.
Important context: If you are using the "Contact Form to Any API" plugin rather than a dedicated Infusionsoft add-on, you may be building the JSON payload manually. In that case, the prefix requirement does not apply, but the field mapping to Keap's API parameters must still be exact.
Failure #2: OAuth Authentication Is Not Configured Correctly
What you see: Keap returns a 401 Unauthorized or "Developer Inactive" error. No contact is created.
Why it happens: Keap uses OAuth 2.0 for API authentication . The API token must be valid, and the refresh token must be properly managed. A common issue is that the access token expires, and the integration cannot refresh it automatically.
A Keap developer described this exact problem: "I am creating a new access token manually and replacing daily because I can't seem to figure out this OAuth process for simple API calls" . Another user reported getting "Developer Inactive" errors when trying to use a refreshed token .
The fix:
Step 1: Verify your OAuth credentials. In Keap, navigate to Settings → API Settings. Copy your Client ID and Client Secret .
Step 2: Generate a fresh API token. According to Keap's OAuth documentation, you need to generate an API token through the developer portal .
Step 3: Configure authentication in the plugin. Add the Bearer token to the Authorization header:
Authorization: Bearer YOUR_ACCESS_TOKEN
Step 4: Handle token refresh. Access tokens expire. If your plugin supports OAuth token refresh, ensure the refresh token is stored and used correctly. Note that when a refresh token is used, both the access and refresh tokens are invalidated, and a new pair is provided .
Alternative: Personal Access Tokens. Keap also supports Personal Access Tokens (PAT), which are simpler for scripting integrations. You can create a PAT from Settings → API Settings .
Failure #3: The API Payload Structure Is Incorrect
What you see: Keap returns a 400 Bad Request error. The response mentions "Field is invalid" or "Bad Request."
Why it happens: Keap's API is strict about payload structure. The contact creation endpoint expects a specific JSON format with nested objects for email addresses and phone numbers.
A Keap developer reported: "The error that I am receiving is only this: {message: 'Field is invalid'}. It does not even say what the 'Field' is that is throwing the error!" .
The fix:
Step 1: Start with a minimal payload. For Keap's REST API, a minimal contact creation payload looks like:
{
"given_name": "[infusionsoft-first-name]",
"family_name": "[infusionsoft-last-name]",
"email_addresses": [
{
"email": "[infusionsoft-email]",
"field": "EMAIL1"
}
]
}
Step 2: Use the correct field names. Keap's API uses specific field identifiers:
-
given_namefor first name -
family_namefor last name -
email_addressesas an array withemailandfieldproperties -
phone_numbersas an array withnumberandfieldproperties
For phone numbers, you must include the field property: "field": "PHONE1" .
Step 3: Check the Content-Type header. Ensure your request includes:
Content-Type: application/json
Step 4: Use the correct endpoint. The contact creation endpoint is:
https://api.infusionsoft.com/crm/rest/v1/contacts
Note on region codes: If you include an address, the region field must use ISO region codes (e.g., US-CO for Colorado), not plain text abbreviations .
For a deeper dive into JSON structure mapping, read this guide on Contact Form 7 JSON mapping.
Failure #4: Duplicate Contact Detection Is Blocking Creation
What you see: No new contact appears in Keap. The API returns a 200 OK response instead of 201 Created.
Why it happens: Keap's API may detect that a contact with the same email address already exists and return the existing contact instead of creating a new one. This is by design, but it can appear as a failure if you are checking for a new contact.
The fix:
Step 1: Check the API response body. A 200 response means a duplicate was found and the existing contact was returned. A 201 response means a new contact was created .
Step 2: Use the duplicate_option parameter. Keap's API supports a duplicate_option parameter to control duplicate detection. Available values include EmailAndName and EmailAndNameAndCompany .
Step 3: Verify in Keap directly. Search for the contact by email address. If it already exists, the integration is working correctly — it is just updating an existing record rather than creating a new one.
The Debugging Checklist
Work through this sequence every time a contact fails to create:
| Step | Action | What It Tells You |
|---|---|---|
| 1 | Check the plugin's API Logs | Was a request sent? What response code came back? |
| 2 | Verify field naming prefix | Are fields prefixed with infusionsoft-? |
| 3 | Check OAuth token | Is it valid and not expired? |
| 4 | Inspect the JSON payload | Does it use the correct nested structure? |
| 5 | Check for duplicates | Does the contact already exist in Keap? |
| 6 | Test with minimal payload | Hardcode values to isolate structure issues. |
For a comprehensive breakdown of authentication errors across different APIs, see this guide on Contact Form 7 API authentication errors.
Beyond Contacts: One Form, Multiple Destinations
Once your Keap integration works, you might want to send the same submission to other tools: a different CRM, an email marketing platform, or a help desk system.
A good connector plugin supports multiple API integrations from a single form submission. You can create a Keap contact, add the lead to HubSpot, and send an SMS via Twilio, all from one CF7 submission. For a cost comparison, see this article on Zapier vs a dedicated API plugin.
Key Takeaways
Field naming may require the infusionsoft- prefix. Older integrations expect this convention. Rename your CF7 fields accordingly.
OAuth authentication must be configured correctly. Access tokens expire. Ensure your integration can refresh them, or use a Personal Access Token for simpler setups .
Keap's API expects a specific JSON structure. Use email_addresses and phone_numbers arrays with the correct field identifiers .
Duplicate detection may return 200 instead of 201. Check the response code and verify in Keap whether the contact already exists .
Start with a minimal payload. Hardcode a test contact first. Once that creates a record in Keap, add additional fields one at a time.
With the correct field naming, valid OAuth credentials, and a properly structured payload, your CF7-to-Keap integration will create contacts reliably.
Top comments (0)