Skip to content

IDs, SyncToken & sparse updates

Cross-cutting rules that apply to every live entity. You usually don't need to change application code for these — they're listed so you know what's happening and why behavior matches QuickBooks Online.

IDs

We pass Desktop's ListID / TxnID through as the QBO Id. As long as your code doesn't parse the format of an ID (almost nobody does), references work unchanged across create → read → update → delete.

CompanyInfo is the exception: its Id equals the realm ID (Desktop's company profile has no ListID/TxnID). See the CompanyInfo section.

SyncToken

Maps to Desktop's EditSequence. Optimistic-concurrency conflicts return the same 400 you'd get from QBO when the token is stale — re-fetch and retry.

ReferenceType

QBO's { value, name } shape maps to Desktop's ListID + FullName. Either side of a round-trip keeps both pieces when Desktop returns them.

Updates & sparse updates

Updates (?operation=update, or a POST body with Id) are classified by the body, not just the query param: a POST whose body carries an Id is always treated as an update, whether or not ?operation=update is on the URL — an Id-bearing POST never reaches create, so it can never duplicate the record.

?operation=update — or a body with "sparse": true — with no Id can't be an update, so we fail loud with a 400 instead of guessing.

Desktop has no partial update, so we read-merge-write the full record for you. Your sparse POST behaves like QBO's — with one semantic difference worth knowing: every update behaves as sparse on Desktop, whether or not your request sets "sparse": true. QBO's full update clears any writable field you omit from the body; Desktop's Mod has no "clear what's missing" mode, so omitted fields are always preserved, never cleared — even on a full-body update with no sparse flag. If your client relies on QBO's full-update semantics to blank out a field by omitting it, that won't happen here; set the field explicitly instead.

Line-level updates on sales forms

On Invoice, Estimate, SalesReceipt, and CreditMemo, an update that carries Line replaces the entire line table — the same contract as QBO, where the Line array on an update is always the complete new set. Two Desktop-flavored consequences to know:

  • Every line in the update is re-created on Desktop, so line Ids change on every line-level update. Don't cache sales-form line Ids across writes, and expect links that point at a specific line (e.g. a partially-invoiced estimate's line links) to be severed by a line-level update.
  • Any existing line you omit from Line is deleted. To leave the line table completely untouched, omit Line from the update body entirely — header-only updates never touch lines. An empty Line: [] is rejected (2020) rather than deleting every line on a form that requires at least one.

CustomerMemo and TxnTaxDetail.TxnTaxCodeRef are also updatable on these four entities. Line-level updates on other transaction entities (Bill, JournalEntry, …) still fail loud with UNSUPPORTED_BY_DESKTOP.

Deletes

POST /{entity}?operation=delete works for transactions (Invoice, SalesReceipt, Bill, Payment, TimeActivity, Estimate) and returns QBO's {"status": "Deleted"} shape.

One honesty note: Desktop's delete takes no SyncToken, so a stale token can't be rejected the way QBO would. Name-list entities (Customer, Vendor, Account, Item) are never deleted — matching QBO, deactivate them with a sparse Active: false update.

Query support

TenkeyBridge compiles a deliberate subset of QBO's SQL-like query language:

  • SELECT * FROM Entity (column lists and aggregates are rejected)
  • Single-condition WHERE on indexed fields (Id, date ranges on TxnDate / MetaData.LastUpdatedTime, DocNumber, Active where applicable)
  • Customer dedup lookups: PrimaryEmailAddr, CompanyName, DisplayName, GivenName, FamilyName (alone), or GivenName + FamilyName together
  • STARTPOSITION / MAXRESULTS pagination within documented caps

Anything outside that subset returns UNSUPPORTED_QUERY rather than a silent mis-parse. Per-entity exceptions (e.g. CompanyInfo rejects all WHERE/pagination) are listed under each entity's Query support section on the compatibility page.

Errors

We return QBO-style Fault JSON, so existing error handling keeps working. Anything Desktop genuinely can't do — or that TenkeyBridge has not shipped yet — returns a documented code. See Error codes.

Gap entities (no Desktop equivalent) and planned entities (not yet built) both return UNSUPPORTED_BY_DESKTOP with a message that links to the entity's compat section. Genuinely unknown entity names still return NOT_FOUND.

TenkeyBridge is an independent product, not affiliated with, endorsed by, or sponsored by Intuit Inc. QuickBooks, QuickBooks Online, and QuickBooks Desktop are trademarks of Intuit Inc., used only to describe compatibility.

TenkeyBridge is an independent product, not affiliated with, endorsed by, or sponsored by Intuit Inc. QuickBooks, QuickBooks Online, and QuickBooks Desktop are trademarks of Intuit Inc., used only to describe compatibility.