I’m working on a Zapier webhook that needs to fetch data from an API that returns paginated results. My current implementation is throwing an error about the output variable not being defined properly.
Here’s my current approach:
const recordsPerPage = 25;
const baseApiEndpoint = "https://api.example.com/items";
let currentCursor = null;
let finalOutput = null;
const fetchData = async function (cursorValue) {
let requestUrl = baseApiEndpoint + `?cursor=${cursorValue}&limit=${recordsPerPage}`;
var response = await fetch(requestUrl)
.then(data => {
return data.json;
});
}
const getAllRecords = async function (cursorValue) {
const data = await fetchData(cursorValue);
console.log("Fetching records for cursor: " + cursorValue);
if (data.meta.cursor !== "") {
return data.concat(await getAllRecords(data.meta.cursor));
} else {
return data;
}
};
(async() => {
const completeList = await getAllRecords();
console.log(completeList);
finalOutput = completeList;
callback(null, completeList);
})();
I keep getting this error message: You did not define output! Try output = {id: 1, hello: await Promise.resolve("world")};
What am I doing wrong with the output variable? How should I properly structure this for Zapier to recognize the results?
zapier needs an output variable, not finalOutput. change your last line to output = completeList; and drop the callback. also, you’re missing .json() in your fetch - it should be return data.json(); not return data.json;
Hit this exact issue building webhook integrations for a client. The missing output variable isn’t your only problem - you’ve got a timing issue with how Zapier runs webhook scripts. Zapier wants synchronous variable assignment at module level, but your IIFE creates an execution context that finishes before the async operations complete. The error happens because Zapier evaluates the script scope before your promise chain resolves. I fixed this by restructuring everything. Skip the callbacks and complex async wrappers - declare output right away and use simple pagination: javascript let output = []; const processPage = async (cursor) => { const response = await fetch(`https://api.example.com/items?cursor=${cursor}&limit=25`); const result = await response.json(); output = output.concat(result.records); if (result.meta.cursor) { await processPage(result.meta.cursor); } }; await processPage(null); This way output exists from script initialization and gets populated correctly during execution. Also fixed my timeout issues since there’s no callback overhead.
Zapier requires a specific variable name and structure. It’s important to wrap everything in an async function and directly assign the results to output. Also, your recursive approach might lead to memory issues with large datasets; using while loops typically results in better performance for pagination. Here’s a more efficient way to handle it:
const fetchAllData = async () => {
let allRecords = [];
let cursor = null;
while (true) {
const response = await fetch(`https://api.example.com/items?cursor=${cursor}&limit=25`);
const data = await response.json();
allRecords = allRecords.concat(data.records);
if (!data.meta.cursor) break;
cursor = data.meta.cursor;
}
return allRecords;
};
output = await fetchAllData();
This approach skips the callback pattern and provides a more efficient way to handle pagination.
Hit this exact same issue last month and wasted hours debugging it. The problem is Zapier’s webhook environment needs the output variable defined at the top level - not buried inside functions or callbacks. Your code structure finishes executing before output gets assigned.
What fixed it for me was ditching the IIFE pattern completely. Don’t wrap everything in an async function. Define your functions, then call them directly at the top level:
const fetchData = async function (cursor) {
const response = await fetch(`https://api.example.com/items?cursor=${cursor}&limit=25`);
return await response.json();
};
const getAllRecords = async function (cursor = null) {
const data = await fetchData(cursor);
if (data.meta.cursor) {
return data.records.concat(await getAllRecords(data.meta.cursor));
}
return data.records;
};
output = await getAllRecords();
The key difference: output gets assigned directly at the script level, which Zapier can actually recognize and process.
you’re overcomplicating this. put output = [] at the top before any functions, then push your paginated results into it. zapier freaks out when output isn’t declared upfront. also, your fetchData function has a bug - you’re missing parentheses on .json().
Zapier’s webhook pagination is a nightmare. Been through this mess too many times.
Yeah, you need that output variable, but here’s what nobody mentioned - you’ll hit timeouts with big datasets. Zapier’s execution limits are brutal.
I fought these same pagination issues until I moved to Latenode. It handles pagination automatically. No wrestling with variable names or timeout limits.
Just set your API endpoint, point to your cursor field, and it grabs everything in the background. No recursive functions, memory issues, or weird output requirements.
Migrated a workflow last month that kept failing in Zapier. 50+ lines of buggy code became a simple 3-step flow. Actually processes large datasets without dying.
Why fight platform limits when you can automate it right? Latenode’s made for these API headaches: https://latenode.com