How to execute multiple HTTP requests within Zapier Code action and handle callback properly

I’m working on a Zapier Code action where I need to make several HTTP requests in sequence. My goal is to send 3 POST requests to an endpoint using a loop, but I’m running into issues with the callback function.

When I include the callback at the end, the HTTP requests don’t seem to execute properly. But if I remove the callback, I get an error saying I need to return proper data, even though the requests do work.

Here’s what I’m trying to do:

var endpoint = "https://webhook.site/test-endpoint";
var counter;
for (counter = 0; counter < 3; counter++) {
  var requestHeaders = {
    "Content-Type": "application/json",
  };

  var payload = JSON.stringify({ message: "Test message", index: counter });

  fetch(endpoint, { method: "POST", headers: requestHeaders, body: payload }).then((response) => {
      console.log(response);
    })
    .catch(callback);
}

callback(null, {});

Is there a proper way to ensure all the HTTP requests complete before calling the callback function? I need both the requests to execute successfully and the action to finish without errors.

You’re calling the callback before your async requests finish. Since fetch returns promises, your callback fires right away while the HTTP requests are still running. I’ve hit this same problem before - Promise.all() is the cleanest fix. Collect all your fetch promises first, then wait for them to finish:

var endpoint = "https://webhook.site/test-endpoint";
var promises = [];

for (var counter = 0; counter < 3; counter++) {
  var requestHeaders = {
    "Content-Type": "application/json",
  };
  
  var payload = JSON.stringify({ message: "Test message", index: counter });
  
  promises.push(
    fetch(endpoint, { 
      method: "POST", 
      headers: requestHeaders, 
      body: payload 
    })
  );
}

Promise.all(promises)
  .then(function(responses) {
    console.log("All requests completed");
    callback(null, { success: true, requestCount: responses.length });
  })
  .catch(function(error) {
    callback(error);
  });

This way all requests finish before your callback runs, plus it handles any errors properly.

classic async timing problm. your callback fires before the fetch requests finish. skip the loop and use a promise chain - much cleaner. or just use a counter to track completed requests and fire the callback when it hits your total. i’ve used both approaches in zapier automations.

Your callback runs immediately while the fetch requests are still going - that’s JavaScript’s async nature biting you. I hit this same problem building webhook integrations. You could use Promise.all(), but I like async/await better for sequential stuff:

var endpoint = "https://webhook.site/test-endpoint";

(async function() {
  try {
    var results = [];
    
    for (var counter = 0; counter < 3; counter++) {
      var requestHeaders = {
        "Content-Type": "application/json",
      };
      
      var payload = JSON.stringify({ message: "Test message", index: counter });
      
      var response = await fetch(endpoint, {
        method: "POST",
        headers: requestHeaders,
        body: payload
      });
      
      results.push(response.status);
    }
    
    callback(null, { completed: results.length, statuses: results });
  } catch (error) {
    callback(error);
  }
})();

This waits for each request to finish before moving to the next one. Handy if you need them in order or want to handle failures differently.