How We Fixed 5,000+ Duplicate Time Entries in a QuickBooks API Integration
A misconfigured pagination parameter caused 5,000+ duplicate time entries in a QuickBooks automation. Here's how we diagnosed and fixed the STARTPOSITION bug.
When your automation loops through QuickBooks time entries using API pagination, each new page must start exactly 1,000 records ahead of the last — not 1. A single-digit error in the STARTPOSITION parameter is enough to cause near-total record duplication, inflating imported data by thousands of hours before anyone notices.
Here is how we diagnosed and fixed this exact issue for an architecture and design firm.
Background
The firm needed to sync all approved billable time entries from QuickBooks Online into their project management platform. Because the QuickBooks API returns a maximum of 1,000 records per call, the integration used paginated queries — iterating through batches of time entries until the full history was retrieved.
Before the historical import began, all existing time entries were cleared to ensure a clean slate. The workflow appeared correctly configured. Then the import ran — and something was clearly wrong.
The Challenge
Within the first pass, total imported hours far exceeded what the entire department had actually worked. A closer look at a single project revealed one employee's 8-hour time entry appearing three times on the same date.
The client pulled screenshots directly from QuickBooks to compare — the source data showed the correct single entry. The automation was creating the duplicates.
Root Cause Investigation
Live troubleshooting confirmed the issue quickly. By pulling two consecutive pages from the QuickBooks time entry API and comparing them side-by-side, the team found identical records on Page 1 and Page 2.
The QuickBooks Online API uses offset-based pagination with STARTPOSITION and MAXRESULTS:
SELECT * FROM TimeActivity STARTPOSITION 1 MAXRESULTS 1000
SELECT * FROM TimeActivity STARTPOSITION 2 MAXRESULTS 1000
The error: STARTPOSITION was incrementing by 1 on each iteration instead of 1,000.
So Page 1 retrieved records 1–1,000. Page 2 started at position 2 — returning records 2–1,001. Page 3 started at 3 — returning records 3–1,002. Every record except the very first was being imported multiple times, once per iteration.
⚠️
The key insight: QuickBooks' STARTPOSITION is a record offset, not a page number. To get the next full page of 1,000 records, you must add 1,000 to the start position — not 1.
The Solution
Step 1 — Clear corrupted data
All incorrectly imported time entries were deleted before reimporting. Attempting to deduplicate in place was not practical given the volume.
Step 2 — Fix the pagination loop
The workflow was updated so STARTPOSITION increments by 1,000 on each iteration:
Iteration 1: STARTPOSITION = 1 → records 1–1,000
Iteration 2: STARTPOSITION = 1001 → records 1,001–2,000
Iteration 3: STARTPOSITION = 2001 → records 2,001–3,000
Step 3 — Staged verification before full import
Rather than running the corrected import all at once, the first 20 iterations (up to 20,000 records) were run and then paused. The client reviewed the results for accuracy before the full import continued. This approach limits the blast radius if any secondary issue surfaces.
Step 4 — Add project name filters
A second issue was discovered during the same session: some non-architecture projects had slipped through because the workflow lacked a project name filter. The fix added a required condition — project names must contain "architecture" or "design" (case-sensitive, uppercase) before being processed. This matched the firm's existing naming convention and prevented unrelated projects from being imported.
Results
Duplicate time entries were eliminated after clearing and reimporting with the corrected pagination
Accuracy was confirmed on the first 20 iterations before full processing continued
A queue of 5,509 records was cleanly reimported without duplication
Non-architecture projects were filtered out completely going forward
Key Takeaway
When building paginated imports from QuickBooks Online, always increment STARTPOSITION by the same value as MAXRESULTS. A page size of 1,000 means the next page starts at previous start + 1,000 — not previous start + 1.
This principle applies to any system using offset-based pagination: the starting offset of each page must equal the previous starting offset plus the page size. Getting this wrong by even a single digit creates cascading duplicates across every record after the first.
If your QuickBooks integration is returning inflated record counts or producing duplicate entries in a connected system, STARTPOSITION is the first parameter to audit.
Ready to build QuickBooks automations that are accurate from day one?Book a free discovery call with the Connex Digital team and let's get your data flowing cleanly.