Developer resources
Everything we have written for people building on the QuickBooks Online API — the guide, the evidence, the calls, and the faults. If you are deleting records, start here.
Start here
- I need to delete records in QuickBooks Online. The guide to deleting transactions via the API — the call shapes, the batch behaviour, and the dry-run design that keeps a bulk delete honest.
- I want to know what the API actually does. The sandbox findings — what the API refuses and what it does not, the measured limits, and the places the documentation and the API disagree.
- I want the calls in my client now. The Postman collection — query, read, delete one, batch delete — run with your own credentials.
The calls at a glance
| Production base | https://quickbooks.api.intuit.com/v3/company/{realmId} |
|---|---|
| Sandbox base | https://sandbox-quickbooks.api.intuit.com/v3/company/{realmId} |
| OAuth scope | com.intuit.quickbooks.accounting |
| minorversion we tested | 75 |
| Batch limit | 30 operations per call — and the rejection is atomic |
| Delete one record | POST /{entity}?operation=delete with { "Id": "…", "SyncToken": "…" } |
The delete pipeline
A delete has no undo, so the shape of the tool matters more than the speed of it. This is the order that makes a destructive operation honest — and the only order we would ship.
Fault codes we have observed
The codes a delete actually returns, and the condition each one names. These are from our own runs, not from a list — see the findings for the detail behind each.
| Code | Meaning | Where we saw it |
|---|---|---|
1040 | Batch size exceeds allowed limit — more than 30 operations. | Observed. A 60-operation batch was rejected with created: 0 — nothing applied. |
6200 | Account period closed — the transaction is dated before the book-closing date. | Observed. Per record: the rest of the set still deletes. |
3001 | ThrottleExceeded — the request rate was reached (HTTP 429). | Observed. ~50 consecutive batch calls; Retry-After was 60 seconds. |
2170 | Invalid Enumeration — a value the endpoint does not accept. | Observed. cleared=Unreconciled on the TransactionList report. |
2010 | Request has invalid or unsupported property. | Observed. Our own error: an operation field on a batch query item, which takes Query instead. |
500 | Unsupported Operation. | Observed. Deleting via /transaction?operation=delete; the entity belongs in the path. |
What we have not verified
The honest edge of this page. If you learn one of these, it is a correction worth having.
- Whether the entity-specific delete needs more than {Id, SyncToken} for some entity types. One forum thread claims Invoice needs a line item; our sandbox run refuted it for Invoice, but we have not checked every entity.
- The negative member of the cleared filter. Reconciled is valid; Uncleared has not yet survived the API.
- Whether the cleared filter paginates, and what it does at the edges of a period.
- Whether the book-closing date is readable through the API at all. So far: it appears not, so a closed period can only be learned from the refusal itself.
- Production throttling. Our rate-limit numbers come from a sandbox company; a real one may differ.
- What one batch item costs against the rate limit — one unit, or more.
- The default query page size of 100. Observed from behaviour (160 matched, 100 returned), not read from a specification.
How Multi-Delete is built
There is no public API, and that is deliberate — a key that can bulk-delete a company’s books is a liability, not a feature. What we publish is the design, so you can judge it or repeat it:
- Read-only queries gather the set; nothing is written until the delete step.
- Tokens never leave the server — they live in an encrypted,
httpOnlysession cookie, not a database. We store no books and keep no account. - The export is a hard gate, and its token is an HMAC bound to the fingerprint of the exact set — the delete refuses a token that does not match the records it is handed.
- Every record is re-read immediately before it is deleted and its
SyncTokencompared against the one captured at export; a mismatch is a skip, never a force. - Runs are chunked and every outcome is logged per record, with its reason.
Start with the delete guide or the sandbox findings, or download the collection.