multi-delete logoTool in development

What the QuickBooks Online delete API actually does

We ran a series of delete tests against the QuickBooks Online sandbox and wrote down what happened. A delete has no undo, so the surprises matter more than the happy path — here is everything we observed, including the places the documentation and the API disagree.

Short answer

The API refuses almost nothing. A stale SyncToken, a reconciled record, a closed payment — all deleted without error. The one refusal we could find is a transaction inside a closed period (fault 6200). Batch deletes cap at 30 operations per call and reject the whole call if you exceed it. The batch endpoint throttles at about 50 consecutive calls, and queries silently cap at 100 rows unless you set a page size.

How we tested — and the limits of this page

Every observation below came from our own runs against the QuickBooks sandbox (a demo company, sandbox-quickbooks.api.intuit.com, at minorversion=75) in late September 2026. The runs were done by hand, and the raw log — including the experiments that failed or were mis-designed — is what this page is written from.

Two honest caveats. First, a sandbox is not production: the API is the same, but throttling and timing against a real company may differ, so treat throughput numbers as a shape rather than a promise. Second, Intuit can change any of this. Where we could not verify something, the page says so instead of guessing — that is the same rule we build to.

If you want the call shapes rather than the results, that is the developer guide to deleting transactions via the API. This page is the evidence behind it.

What the API refuses, and what it does not

ConditionDoes the API refuse the delete?What a tool has to do
A stale SyncTokenNo — accepted on both the batch and single pathsRe-read and compare the token yourself; the API will not.
A reconciled recordNo — deleted with no error, three runsDetect it and warn. Detection is possible (below).
A transaction inside a closed periodYes — fault 6200, per recordNothing. It fails safely and the reason is already readable.

The practical consequence: the API is a safety net for exactly one of the three. A closed period is protected. A stale version and a reconciled record are not — and those are the two that quietly change what gets deleted.

The SyncToken is not enforced on a delete

Every QuickBooks record carries a SyncToken, a small version stamp. The documented rule is absolute: every write, deletes included, sends the record’s current token, and a write based on a stale read is refused. That is optimistic concurrency — the thing that stops two people, or a person and a tool, silently clobbering each other.

On the paths a bulk tool actually uses, it does not hold. We read an invoice whose current token was 0, then deleted it presenting 999. The batch endpoint returned 200 Deleted. We repeated it on the single-record entity endpoint with a non-zero wrong token, and that was accepted too. Nothing was refused.

So “delete exactly the version the user reviewed” is a promise you have to keep yourself: re-read the record immediately before deleting it and compare the token against the one captured when the set was reviewed. If they differ, skip the record and report why. That comparison — not the API — is the guard, and it deserves a unit test rather than a hand run.

A reconciled record deletes without complaint

We expected QuickBooks to refuse. It does not. After verifying that a record was reconciled, we ran it through and it was deleted with no error code and no message. The QuickBooks interface agrees, in its own words:

“The transaction you are deleting has been reconciled. Deleting your changes could put you out of balance the next time you try to reconcile. Are you sure you want to delete it?”

That is a warning, not a refusal — on both surfaces. Which means a delete tool cannot lean on the API to protect a user’s reconciliation. It has to detect the reconciled records itself and say so before the run. We asked whether that detection is even possible, and it is.

Detecting a reconciled transaction

A normal entity read carries no reconciliation field, so you cannot read the state off the record. But the TransactionList report exposes it as a filter:

GET /v3/company/{realmId}/reports/TransactionList
    ?start_date=2026-09-01&end_date=2026-09-30
    &cleared=Reconciled

In our run the reconciled record came back, and — this is the part that makes it usable — the report carries the transaction Id (as the id on the transaction-type column), so its rows can be joined onto the previewed set by id. One report call covers every transaction type for a date range, so detection costs one call per run, not one per entity.

Two cautions from the same run. The enum is narrower than secondary sources claim: Reconciled is valid, but Unreconciled is rejected with fault 2170, “Invalid Enumeration”. And there is no reconciliation column — only the filter — so you learn membership of the reconciled set, not a per-record flag.

The batch limit is 30, and the rejection is atomic

POST /v3/company/{realmId}/batch takes up to 30 BatchItemRequest entries. A 60-operation batch came back as HTTP 400, fault 1040 — “The Batch Limit is 30 BatchItemRequests” — with created: 0. Nothing was applied. Getting the constant wrong fails as a clean refusal, not partial damage, which is the failure mode you want on a delete.

Read the response per item: a batch returns one BatchItemResponse per operation, and one bad operation does not fail the others. If the call fails as a whole, the only way to find the poison entry is to retry the records one at a time — which is why a bulk delete needs a single-record fallback on a different, correct endpoint.

Throttling: the batch envelope is the scarce resource

The query that quietly returns 100 rows

The worst bug we found was not an error at all. Our query never set a page size, so it took the API’s default and stopped without saying so: 160 invoices matched, the result returned 100, and it reported “100 matched” as though that were the set.

This is the dangerous shape on a delete tool, because the export is the record of what was removed. A silently truncated set means the user reviewed and backed up one list while the tool acted on another. Set an explicit page size (maximum 1000), page with startposition, and check each page against the response’s own totalCount. If the set cannot be read in full, refuse rather than proceed.

What this means if you are building a delete tool

  1. Read and page deliberately. Set the page size; verify the count; refuse a partial set.
  2. Detect reconciliation yourself. The API will not protect those records, and neither will it warn.
  3. Own the version promise. Re-read each record immediately before deleting it and compare the token; skip on a mismatch and say why.
  4. Chunk at 30. Sequence the batches, honour Retry-After, and isolate a failed batch rather than retrying the whole run.
  5. Log per record. Deleted, skipped or failed, with the reason and the fault code. A log that records only successes is not a log.

Questions developers actually ask

Will the QuickBooks Online API refuse to delete a reconciled transaction?

No. We verified a record was reconciled, then deleted it through the API — it was removed with no error code and no message. The QuickBooks Online interface behaves the same way: it warns that deleting a reconciled transaction “could put you out of balance the next time you try to reconcile”, then allows the delete. Reconciliation is a warning, never a refusal, on either surface.

Does the QuickBooks Online API enforce SyncToken on a delete?

Not on the paths a bulk tool uses. Every record carries a SyncToken, and every write is documented as carrying the record’s current token so that a stale write is refused. In our sandbox testing that did not happen: a batch delete sent with a deliberately wrong token (999 against a current token of 0) returned 200 Deleted, and the same was true of the single-record delete path. So if your requirement is “delete exactly the version the user reviewed”, the API will not enforce it for you — re-read the record immediately before deleting it and compare the token yourself.

What is the batch limit for the QuickBooks Online API?

Thirty operations per batch request. A 60-operation batch was rejected with HTTP 400 and fault code 1040, “The Batch Limit is 30 BatchItemRequests”. The rejection is atomic: nothing in the batch was applied. So calls of more than 30 operations fail cleanly rather than partially, and a bulk delete has to chunk its work into batches of 30.

What is the rate limit for the QuickBooks Online delete API?

The batch endpoint is the scarce one. In our testing, 50 consecutive batch calls succeeded and the 51st was refused with HTTP 429, Intuit fault 3001 (ThrottleExceeded) and a Retry-After of 60 seconds. The query endpoint was not throttled at 60 back-to-back calls. The two endpoints do not share a ceiling, and the smaller one is the one deletes use — so a sequential run fits under the limit, but parallel deletes would cross it quickly.

Why does my QuickBooks Online query return only 100 rows?

Because the query has a default page size of 100 and truncates silently — it does not error or tell you the set was cut. We hit this when 160 invoices existed and the query returned 100, reporting “100 matched” as though that were everything. Set an explicit page size (the documented maximum is 1000) and page through with startposition, comparing the rows against the response’s own totalCount. Treat “100” as observed behaviour, not a documented default.

What QuickBooks Online fault code means a transaction is inside a closed period?

Fault 6200. It reads “The account period has closed” and names both dates — for example, “Txn Date=09/27/2026 is before book closing date=09/30/2026 (code 6200)”. It is a per-record refusal: records inside the closed period fail and are reported, while the rest of the set still deletes. That makes a closed period the one condition where the API itself is a real safety net.

Developer resources — the calls at a glance, the fault-code index, and the downloads. This is the evidence log behind our guide to deleting transactions via the QuickBooks Online API. Related: how to bulk delete transactions in QuickBooks Online · journal entries · other accounting software.