API v1 contact_sync returns "Invalid Request"

The code below is written for a Code by Zapier action using ActiveCampaign’s API version 1 and contact_sync api action, as directed by AC Support for my use case.

It appears to work but returns the following:

INFO Response Text: {“result_code”:0,“result_message”:“Invalid request”,“result_output”:“json”}

Since I’m new to using the fetch method in Zapier’s code action, any help troubleshooting is appreciated.

Note: Code in separate reply below due to 403 error when I tried to save an edit.

const apiKey = 'xxxxxx';
const apiURL = 'https://myaccount.api-us1.com/admin/api.php?api_key=' + apiKey + '&api_action=contact_sync' + '&api_output=json';

var emailAddress = 'zapier-test@gmail.com'; //inputData.emailAddress;
var FirstName = 'FFFFF'; //inputData.FirstName;
var LastName = 'LLLLL'; //inputData.LastName;

const postData = {
  email: emailAddress, // Replace with the email of the contact you want to sync
  first_name: FirstName, // Replace with the first name of the contact
  last_name: LastName,
  form: 22
};

fetch(apiURL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: new URLSearchParams(postData),
})
.then(response => response.text()) // Read the response as text
.then(text => {
  console.log('Response Text:', text); // Log the response text for debugging
  try {
    const data = JSON.parse(text); // Parse the response text as JSON
    callback(null, data);
  } catch (error) {
    callback(error, null); // Handle JSON parsing error
  }
})
.catch(error => {
  callback(error, null);
});

Any help troubleshooting is appreciated.

ChatGPT is my friend for this stuff

const url = 'https://xxx.api-us1.com/admin/api.php';
const apiKey = 'xxxxx';

const params = {
    api_action: 'contact_sync',
    api_output: 'json', 
};

const postData = {
    email: 'test@example.com',
    first_name: 'FirstName',
    last_name: 'LastName',
    form: 22,
 };

// Construct the query string from params
const queryString = new URLSearchParams(params).toString();

// Construct the body data from postData
const bodyData = new URLSearchParams(postData).toString();

// Construct the full URL with query string
const fullUrl = `${url}?${queryString}`;

const options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'API-TOKEN': apiKey
    },
    body: bodyData
};

fetch(fullUrl, options)
    .then(response => response.json()) // Changed to response.json() to directly handle JSON response
    .then(data => {
        // Use callback to return data
        callback(null, data);
    })
    .catch(error => {
        console.error('Error:', error);
        callback(error, null);
    });
1 Like

@RobertSegelquist - this works brilliantly! I tested it, and it created a new contact in AC, subscribed to the correct list, set the status as Unconfirmed AND sent the opt-in email!

Where there’s a will, there’s a way! Thank you!

Aside: I too was using ChatGPT but wasn’t quiet able to get G to generate that flawless code - what prompt(s) did you feed to get that result?

The complete solution, ready for Zapier:

/*
This script is written for a Code by Zapier action using ActiveCampaign's API version 1 and contact_sync api action.

With a properly configured form in AC that implements double opt-in, the script will create a new contact in AC, subscribe the contact
to the correct list, set the contact's status as Unconfirmed, and send an opt-in email.

Created 2024-05-06 by West Wind Web Works and Zephyr Mays with a MASSIVE assist from Robert Segelquist, ActiveCampaign Superuser.

See forum post here: https://community.activecampaign.com/t/api-v1-contact-sync-returns-invalid-request/22875

*/

const url = 'https://myaccount.api-us1.com/admin/api.php';
const apiKey = 'abc123...';


//Values from previous Zapier action, e.g. external lead generator that does not natively integrate with AC.
var emailAddress = inputData.emailAddress; 
var FirstName = inputData.FirstName;
var LastName = inputData.LastName;

const params = {
    api_action: 'contact_sync',
    api_output: 'json', 
};

const postData = {
    email: emailAddress,
    first_name: FirstName,
    last_name: LastName,
    form: 123, // this value is the form # found at https://myaccount.activehosted.com/app/forms/123
 };

// Construct the query string from params
const queryString = new URLSearchParams(params).toString();

// Construct the body data from postData
const bodyData = new URLSearchParams(postData).toString();

// Construct the full URL with query string
const fullUrl = `${url}?${queryString}`;

const options = {
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'API-TOKEN': apiKey
    },
    body: bodyData
};

fetch(fullUrl, options)
    .then(response => response.json()) // Changed to response.json() to directly handle JSON response
    .then(data => {
        // Use callback to return data
        callback(null, data);
    })
    .catch(error => {
        console.error('Error:', error);
        callback(error, null);
});

@RobertSegelquist — again, thanks for bringing this solution to life!

I’ve just tinkered enough to figure out the back and forth.

Gist of it is saying, “made that update, now this error…”

here’s the thread https://chat.openai.com/share/859f413e-3636-4e5e-960a-b2ff10381912