Appearance
The compatibility contract
We deliver the most QuickBooks Online compatibility we can, and we're honest about the rest. Reads are almost entirely compatible; writes are where QuickBooks Desktop's quirks show up. Every partial or unsupported case below comes with the exact fix.
This page is the full entity matrix — every QBO Accounting API entity we track, whether live, planned, or a documented gap. Jump to an entity from the tables below, or read IDs, SyncToken & sparse updates for the cross-cutting rules.
Entity matrix
Every QBO Accounting API entity we track, with an honest verdict and a one-line Desktop reality check. Use this page to answer "does TenkeyBridge cover what I use?" in under a minute.
Legend — Full: works unchanged · Partial: common cases work, see the entity section · Full (read-only): reads work; no write path · Planned: real Desktop analog, not yet shipped · Stretch: lower-priority planned · Never: no honest Desktop equivalent · Future: platform ops after the entity matrix.
Sales
| Entity | Verdict | Headline |
|---|---|---|
| CreditMemo | Partial | Invoice twin — Balance and RemainingCredit both map from Desktop CreditRemaining |
| Customer | Full | Sub-customer maps to Desktop Customer:Job |
| Estimate | Partial | Same shape as Invoice; no expiration/acceptance tracking |
| Invoice | Partial | Line model, tax, discount, linked txns, and custom fields |
| Item | Partial | One Item becomes several Desktop item types |
| Payment | Partial | Applying a payment to specific invoices |
| RefundReceipt | Partial | Card refunds of applied credits only (ARRefundCreditCard) — not general item-line refunds |
| SalesReceipt | Partial | Same as Invoice + deposit account |
Purchasing
| Entity | Verdict | Headline |
|---|---|---|
| Bill | Full | Account vs. item expense lines map cleanly |
| BillPayment | Partial | Fans out to BillPaymentCheck / BillPaymentCreditCard by PayType |
| Purchase | Partial | Fans out to Check / CreditCardCharge / CreditCardCredit by PaymentType |
| PurchaseOrder | Partial | Non-posting; item lines only — never touches the GL on either side |
| Vendor | Full | 1099 / tax-ID field naming only |
| VendorCredit | Partial | Bill mirror image — expense and item lines |
Banking
| Entity | Verdict | Headline |
|---|---|---|
| Account | Full | AccountType / AccountSubType enum mapping |
| Deposit | Partial | Undeposited Funds → bank via LinkedTxn or manual DepositLineDetail |
| JournalEntry | Partial | Debit/Credit lines split across Desktop JournalDebitLine / JournalCreditLine |
| Transfer | Full | Bank-to-bank transfer between two accounts |
Lists & config
| Entity | Verdict | Headline |
|---|---|---|
| Class | Full | Hierarchical Class list; SubClass/FullyQualifiedName from Desktop Sublevel/FullName |
| CompanyCurrency | Full (read-only) | Desktop CurrencyQuery list; empty when multicurrency is off (statusCode 3250, confirmed live, and 3170 both normalized to []) |
| CustomerType | Full (read-only) | Read/query only — QBO CustomerType is read-only via the API; Desktop hierarchy is not exposed |
| Employee | Full (read-only) | Read/query only — no Desktop write path this release; payroll aggregates out of scope |
| ExchangeRate | Partial | Projected from CurrencyRet.ExchangeRate + AsOfDate; one row per currency that carries a rate; empty when multicurrency is off (statusCode 3250, confirmed live, and 3170 both normalized to []) |
| PaymentMethod | Partial | Create only — Desktop has no PaymentMethodMod; Type coarsens Desktop's fine enum to CREDIT_CARD |
| TaxAgency | Full (read-only) | Read-only projection — Vendors referenced by any ItemSalesTax.TaxVendorRef (no native Desktop TaxAgency list) |
| TaxCode | Full | Desktop SalesTaxCode list (TAX/NON); Name max 3 chars (fail-loud, never truncated); a plain taxable/non-taxable flag pair, not a rate container |
| TaxRate | Full (read-only) | Read-only (parity with QBO) — Desktop ItemSalesTaxQuery; each single rate item is a TaxRate; sales-tax groups are not projected as TaxRates |
| Term | Partial | Merged StandardTerms + DateDrivenTerms; Type STANDARD |
| TimeActivity | Partial | Employee time only; Duration compiled from Hours/Minutes or a StartTime/EndTime span |
Company
| Entity | Verdict | Headline |
|---|---|---|
| CompanyInfo | Full (read-only) | Read-only; Id equals the realm ID, no Desktop write path |
| Preferences | Partial | Read-only singleton (Id=1); honest subset of Desktop PreferencesQuery groups |
Planned (Desktop analog exists)
| Entity | Verdict | Headline |
|---|---|---|
| Budget | Planned | qbXML has no Budget records, but budget figures are readable through BudgetSummaryReportQuery — a read-only Budget synthesized from that report is planned; budget writes stay in the Desktop UI forever. |
Never — no Desktop equivalent
| Entity | Verdict | Headline |
|---|---|---|
| Attachable | Never | QuickBooks Desktop's qbXML API has no attachments interface — the word 'Attachment' does not occur anywhere in the qbxmlops130 message set. |
| Department | Never | QBO Departments (locations) have no Desktop equivalent — the only 'Department'/'Location' strings in qbXML are free-text fields on Employee, FixedAsset, and Lead, and Desktop's one real dimensional list (Class) is already exposed faithfully as Class. |
| JournalCode | Never | France-only QBO regulatory feature; not applicable to Desktop — 'JournalCode' occurs nowhere in the qbxmlops130 message set. |
| RecurringTransaction | Never | Desktop's memorized transactions are not exposed by qbXML — there is no message to list, read, create, or execute them. |
| ReimburseCharge | Never | QBO's billable-charge object has no Desktop record behind it — in qbXML, billability is a status flag (BillableStatus) on the source expense/item/time lines, never a standalone charge you can query. |
| TaxClassification | Never | Cloud automated-sales-tax concept with no Desktop counterpart — Desktop's tax model is explicit tax items and codes, all of which TenkeyBridge exposes. |
| TaxService | Never | Cloud AST onboarding operation with no Desktop counterpart — 'TaxService' occurs nowhere in the qbxmlops130 message set. |
Platform
| Entity | Verdict | Headline |
|---|---|---|
| Batch | Full | Batch envelope — up to 30 create/update/delete/query operations in one request, executed sequentially with per-item faults. |
| CDC | Full (read-only) | Change Data Capture — one poll returns changed + deleted records across entities. |
| Reports | Partial | Five QBO-compatible reports translated live from Desktop's report engine. |
Entity detail
CreditMemo
Verdict: Partial · Read: Full · Write: Partial — Invoice twin — Balance and RemainingCredit both map from Desktop CreditRemaining
| QBO field | Support | Notes |
|---|---|---|
| CustomerMemo | Full | Maps to Desktop CustomerMsgRef by FullName; the message must already exist as a Desktop customer message. Updatable via sparse update (#55). |
| Line | Partial | Same DetailType support as Invoice: SalesItemLineDetail, GroupLineDetail, and DescriptionOnly map cleanly; DiscountLineDetail requires a Desktop discount item; other DetailTypes return UNSUPPORTED_BY_DESKTOP. Group lines read back as GroupLineDetail without nested line expansion; Desktop discount lines read back as regular item lines referencing the discount item. Updates carrying Line replace the entire line table: every line is re-created with a new line Id and lines omitted from the update are deleted by Desktop (v1 full replacement, #55). |
| TxnTaxDetail | Partial | Set TxnTaxCodeRef explicitly; computed TotalTax alone is rejected. Updatable via sparse update (#55). |
| LinkedTxn | Partial | Read-only; reflects applied payments/credits, ignored on write — same as QBO. |
| TotalAmt | Full | Read-only, mapped from Desktop TotalAmount. |
| Balance | Full | Read-only remaining unapplied credit; mapped from Desktop CreditRemaining. |
| RemainingCredit | Full | Read-only — total credit still available to apply. A distinct QBO field, not an alias of Balance; both map from Desktop's single CreditRemaining since Desktop has only the one figure. |
| ApplyTaxAfterDiscount | None | UNSUPPORTED_BY_DESKTOP — Desktop credit memos have no ApplyTaxAfterDiscount toggle. Control tax via per-line TaxCodeRef / TxnTaxDetail.TxnTaxCodeRef instead. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- TxnDate
- DocNumber
- BillAddr
- ShipAddr
- PONumber
- SalesTermRef
- DueDate
- PrivateNote
Query support
Standard SELECT * FROM CreditMemo with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- TxnTaxDetail.TotalTax supplied without TxnTaxCodeRef —
UNSUPPORTED_BY_DESKTOP: Desktop cannot honor a computed tax total. Set TxnTaxDetail.TxnTaxCodeRef or per-line TaxCodeRef explicitly. See COMPATIBILITY.md. - Line.DiscountLineDetail without an ItemRef (bare-percentage or amount-off discounts) —
MISSING_REQUIRED_DESKTOP_ITEM: Desktop discounts are items. Create a discount item in the company file and reference it as DiscountLineDetail.ItemRef. See COMPATIBILITY.md. - Nested/grouped line types other than SalesItemLineDetail, DiscountLineDetail, GroupLineDetail, and DescriptionOnly —
UNSUPPORTED_BY_DESKTOP: These line types do not map to QuickBooks Desktop sales transactions. Remove them or flatten to a supported DetailType. See COMPATIBILITY.md. - ApplyTaxAfterDiscount supplied —
UNSUPPORTED_BY_DESKTOP: Desktop credit memos have no ApplyTaxAfterDiscount toggle. Control tax via per-line TaxCodeRef / TxnTaxDetail.TxnTaxCodeRef instead.
Customer
Verdict: Full · Read: Full · Write: Full — Sub-customer maps to Desktop Customer:Job
| QBO field | Support | Notes |
|---|---|---|
| ParentRef | Full | Becomes a Desktop Job under the parent; FullName is colon-delimited. |
| SalesTermRef | Full | Desktop TermsRef. |
| DefaultTaxCodeRef | Full | Desktop SalesTaxCodeRef. |
| AcctNum | Full | Desktop AccountNumber. |
| Balance | Full | Read-only, as in QBO. |
| BalanceWithJobs | Full | Read-only; Desktop TotalBalance. |
| FullyQualifiedName | Full | Read-only, derived by Desktop. |
| Job | Full | Read-only, derived by Desktop Sublevel. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| PreferredPaymentMethodRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| PreferredDeliveryMethod | None | UNSUPPORTED_BY_DESKTOP — Desktop has no delivery-method preference. Remove the field from your payload. |
| Taxable | None | UNSUPPORTED_BY_DESKTOP — Desktop customers have no taxable flag; set tax codes on transactions instead. |
| PrintOnCheckName | None | UNSUPPORTED_BY_DESKTOP — Desktop CustomerRet has no PrintAs element (unlike Vendor/Employee). |
| Mobile | None | UNSUPPORTED_BY_DESKTOP — Desktop CustomerRet has no separate mobile-phone element beyond Phone/AltPhone/Fax. |
| WebAddr | None | UNSUPPORTED_BY_DESKTOP — Desktop CustomerRet has no website element. |
Everything else listed as full works unchanged.
Full fields
- DisplayName
- CompanyName
- Title
- GivenName
- MiddleName
- FamilyName
- PrimaryEmailAddr
- PrimaryPhone
- AlternatePhone
- Fax
- BillAddr
- ShipAddr
- Notes
- Active
- CustomerTypeRef
Query support
Standard SELECT * FROM Customer with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Estimate
Verdict: Partial · Read: Full · Write: Partial — Same shape as Invoice; no expiration/acceptance tracking
| QBO field | Support | Notes |
|---|---|---|
| CustomerMemo | Full | Maps to Desktop CustomerMsgRef by FullName; the message must already exist as a Desktop customer message. Updatable via sparse update (#55). |
| Line | Partial | Same DetailType support as Invoice: SalesItemLineDetail, GroupLineDetail, and DescriptionOnly map cleanly; line-level ClassRef and ServiceDate are populated on read; DiscountLineDetail requires a Desktop discount item; other DetailTypes return UNSUPPORTED_BY_DESKTOP. Group lines read back as GroupLineDetail without nested line expansion; Desktop discount lines read back as regular item lines referencing the discount item. Updates carrying Line replace the entire line table: every line is re-created with a new line Id and lines omitted from the update are deleted by Desktop (v1 full replacement, #55). |
| TxnTaxDetail | Partial | Set TxnTaxCodeRef explicitly on write; computed TotalTax alone is rejected. On read: TotalTax, TxnTaxCodeRef, and TaxLine[{Amount, TaxLineDetail{TaxRateRef, TaxPercent}}]. NetAmountTaxable never returned. Updatable via sparse update (#55). |
| LinkedTxn | Full | Populated on read from LinkedTxnRet (IncludeLinkedTxns automatic) — progress-invoicing links when present. Links to Desktop-only transaction types (SalesOrder, ItemReceipt, …) are omitted rather than guessed at. Accepted and ignored on write. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| TotalAmt | Full | Read-only, computed by Desktop as Subtotal + SalesTaxTotal (not independently verified live — see issue #38 report). |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExpirationDate | None | UNSUPPORTED_BY_DESKTOP — Desktop estimates have no expiration date. Track it in your own system if needed. |
| AcceptedBy | None | UNSUPPORTED_BY_DESKTOP — Desktop estimates have no accepted-by field. Track acceptance in your own system. |
| AcceptedDate | None | UNSUPPORTED_BY_DESKTOP — Desktop estimates have no accepted-date field. Track acceptance in your own system. |
| TxnStatus | None | UNSUPPORTED_BY_DESKTOP — Desktop estimates have no status field matching QBO's Pending/Accepted/Closed/Rejected enum. Track status in your own system. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- TxnDate
- DocNumber
- BillAddr
- ShipAddr
- PONumber
- SalesTermRef
- DueDate
- PrivateNote
Query support
Standard SELECT * FROM Estimate with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- TxnTaxDetail.TotalTax supplied without TxnTaxCodeRef —
UNSUPPORTED_BY_DESKTOP: Desktop cannot honor a computed tax total. Set TxnTaxDetail.TxnTaxCodeRef or per-line TaxCodeRef explicitly. See COMPATIBILITY.md. - Line.DiscountLineDetail without an ItemRef (bare-percentage or amount-off discounts) —
MISSING_REQUIRED_DESKTOP_ITEM: Desktop discounts are items. Create a discount item in the company file and reference it as DiscountLineDetail.ItemRef. See COMPATIBILITY.md. - Nested/grouped line types other than SalesItemLineDetail, DiscountLineDetail, GroupLineDetail, and DescriptionOnly —
UNSUPPORTED_BY_DESKTOP: These line types do not map to QuickBooks Desktop sales transactions. Remove them or flatten to a supported DetailType. See COMPATIBILITY.md.
Invoice
Verdict: Partial · Read: Full · Write: Partial — Line model, tax, discount, linked txns, and custom fields
| QBO field | Support | Notes |
|---|---|---|
| CustomerMemo | Full | Maps to Desktop CustomerMsgRef by FullName; the message must already exist as a Desktop customer message. Updatable via sparse update (#55). |
| Line | Partial | SalesItemLineDetail, GroupLineDetail, and DescriptionOnly map cleanly; line-level ClassRef and ServiceDate are populated on read; DiscountLineDetail requires a Desktop discount item referenced via DiscountLineDetail.ItemRef; other DetailTypes (e.g. SubTotalLineDetail) return UNSUPPORTED_BY_DESKTOP. Group lines read back as GroupLineDetail without nested line expansion; Desktop discount lines read back as regular item lines referencing the discount item. Updates carrying Line replace the entire line table: every line is re-created with a new line Id and lines omitted from the update are deleted by Desktop (v1 full replacement, #55). |
| TxnTaxDetail | Partial | Set TxnTaxCodeRef explicitly on write; computed TotalTax alone is rejected. On read: TotalTax, TxnTaxCodeRef (from ItemSalesTaxRef), and TaxLine[{Amount, TaxLineDetail{TaxRateRef, TaxPercent}}] from SalesTaxTotal/ItemSalesTaxRef/SalesTaxPercentage. NetAmountTaxable is never returned (Desktop has no taxable basis). Updatable via sparse update (#55). |
| LinkedTxn | Full | Populated on read from LinkedTxnRet when IncludeLinkedTxns is requested (automatic). Desktop ReceivePayment → QBO Payment; links to Desktop-only transaction types (SalesOrder, ItemReceipt, …) are omitted rather than guessed at. Accepted and ignored on write — same as QBO treats it as read-only. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| TotalAmt | Full | Read-only, computed by Desktop as Subtotal + SalesTaxTotal. |
| Balance | Full | Read-only, computed by Desktop as BalanceRemaining. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- TxnDate
- DocNumber
- BillAddr
- ShipAddr
- ShipDate
- ShipMethodRef
- PONumber
- SalesTermRef
- DueDate
- PrivateNote
Query support
Standard SELECT * FROM Invoice with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- TxnTaxDetail.TotalTax supplied without TxnTaxCodeRef —
UNSUPPORTED_BY_DESKTOP: Desktop cannot honor a computed tax total. Set TxnTaxDetail.TxnTaxCodeRef or per-line TaxCodeRef explicitly. See COMPATIBILITY.md. - Line.DiscountLineDetail without an ItemRef (bare-percentage or amount-off discounts) —
MISSING_REQUIRED_DESKTOP_ITEM: Desktop discounts are items. Create a discount item in the company file and reference it as DiscountLineDetail.ItemRef. See COMPATIBILITY.md. - Nested/grouped line types other than SalesItemLineDetail, DiscountLineDetail, GroupLineDetail, and DescriptionOnly (e.g. SubTotalLineDetail) —
UNSUPPORTED_BY_DESKTOP: These line types do not map to QuickBooks Desktop sales transactions. Remove them or flatten to a supported DetailType. See COMPATIBILITY.md.
Item
Verdict: Partial · Read: Partial · Write: None — One Item becomes several Desktop item types
| QBO field | Support | Notes |
|---|---|---|
| FullyQualifiedName | Full | Read-only in this release. |
| Active | Full | Read-only in this release. |
| Type | Partial | Service, NonInventory, Inventory, Group map; other Desktop types are omitted from query results. |
| Description | Full | Read-only in this release. |
| UnitPrice | Full | Read-only in this release. |
| Sku | Partial | QBO Sku ⇄ Desktop ManufacturerPartNumber — Desktop has no first-class SKU field; barcode (Advanced Inventory) is intentionally not used. Read-only in this release. |
| QtyOnHand | Full | Read-only in this release. |
| IncomeAccountRef | Full | Read-only in this release. |
| ExpenseAccountRef | Partial | Inventory: COGSAccountRef. Two-sided Service/NonInventory (SalesAndPurchase): ExpenseAccountRef. One-sided Service/NonInventory have no expense account. |
| AssetAccountRef | Full | Read-only in this release; Inventory only. |
| PurchaseDesc | Full | Inventory and two-sided Service/NonInventory (SalesAndPurchase). |
| PurchaseCost | Full | Inventory and two-sided Service/NonInventory (SalesAndPurchase). |
| PrefVendorRef | Full | Inventory and two-sided Service/NonInventory. |
| ParentRef | Full | Desktop item hierarchy. |
| SubItem | Full | Derived from Desktop Sublevel. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. |
Everything else listed as full works unchanged.
Full fields
- Name
Query support
Standard SELECT * FROM Item with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Item types other than Service, NonInventory, Inventory, and Group (assemblies, discounts, sales tax items, payment items, fixed assets, other charge, subtotal) —
UNSUPPORTED_BY_DESKTOP: Omitted from query results; a direct get by id on one of these Desktop items returns a 422 UNSUPPORTED_BY_DESKTOP fault. - Item create/update —
UNSUPPORTED_BY_DESKTOP: Lands in a later release.
Payment
Verdict: Partial · Read: Full · Write: Partial — Applying a payment to specific invoices
| QBO field | Support | Notes |
|---|---|---|
| PaymentRefNum | Full | Desktop RefNumber. Query filtering by PaymentRefNum is not supported yet — query by Id or date range. |
| DepositToAccountRef | Full | Omit to use Desktop's Undeposited Funds preference, same as QBO. |
| Line | Partial | LinkedTxn applications to Invoices only; no Line means an unapplied payment (IsAutoApply=false). CreditMemo/Deposit applications land later. AppliedToTxnRet.TxnDate/RefNumber/BalanceRemaining have no honest home in QBO Payment.Line.LinkedTxn ({TxnId, TxnType} only) and are not projected — re-fetch the invoice for balance/date/doc number. |
| UnappliedAmt | Full | Read-only; Desktop UnusedPayment. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ProcessPayment | Partial | Accepted and ignored — TenkeyBridge never initiates card processing. |
| TxnNumber | None | UNSUPPORTED_BY_DESKTOP — Desktop's internal auto-increment TxnNumber has no QBO equivalent and is not surfaced. |
| UnusedCredits | None | UNSUPPORTED_BY_DESKTOP — Desktop UnusedCredits (unapplied credit memos available to the customer) is distinct from UnappliedAmt/UnusedPayment; no honest home on Payment — belongs on CreditMemo.Balance. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- ARAccountRef
- TxnDate
- TotalAmt
- PaymentMethodRef
- PrivateNote
Query support
Standard SELECT * FROM Payment with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
RefundReceipt
Verdict: Partial · Read: Partial · Write: Partial — Card refunds of applied credits only (ARRefundCreditCard) — not general item-line refunds
| QBO field | Support | Notes |
|---|---|---|
| DepositToAccountRef | Full | Maps to Desktop RefundFromAccountRef. |
| PaymentMethodRef | Full | Must be a credit-card payment method in the company file. |
| Line | Partial | LinkedTxn credit-memo applications → RefundAppliedToTxnAdd only. At least one Line is required on create — Desktop's ARRefundCreditCardAdd requires one or more RefundAppliedToTxnAdd; an empty/missing Line array fails loud rather than sending Desktop an invalid request. SalesItemLineDetail / item-line refunds return UNSUPPORTED_BY_DESKTOP — use CreditMemo + payment/refund pair instead (see CreditMemo). |
| TotalAmt | Full | Read-only from Desktop TotalAmount. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- TxnDate
- DocNumber
- PrivateNote
Query support
Standard SELECT * FROM RefundReceipt with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Item-line RefundReceipt (SalesItemLineDetail etc.) —
UNSUPPORTED_BY_DESKTOP: Desktop has no general item-line refund receipt. Create a CreditMemo and refund via payment/ARRefundCreditCard, or handle cash/check refunds outside this entity. - Update / sparse update —
UNSUPPORTED_BY_DESKTOP: ARRefundCreditCard has no Mod path in this release.
SalesReceipt
Verdict: Partial · Read: Full · Write: Partial — Same as Invoice + deposit account
| QBO field | Support | Notes |
|---|---|---|
| CustomerMemo | Full | Maps to Desktop CustomerMsgRef by FullName; the message must already exist as a Desktop customer message. Updatable via sparse update (#55). |
| Line | Partial | SalesItemLineDetail, GroupLineDetail, and DescriptionOnly map cleanly; line-level ClassRef and ServiceDate are populated on read; DiscountLineDetail requires a Desktop discount item referenced via DiscountLineDetail.ItemRef; other DetailTypes (e.g. SubTotalLineDetail) return UNSUPPORTED_BY_DESKTOP. Group lines read back as GroupLineDetail without nested line expansion; Desktop discount lines read back as regular item lines referencing the discount item. Updates carrying Line replace the entire line table: every line is re-created with a new line Id and lines omitted from the update are deleted by Desktop (v1 full replacement, #55). |
| TxnTaxDetail | Partial | Set TxnTaxCodeRef explicitly on write; computed TotalTax alone is rejected. On read: TotalTax, TxnTaxCodeRef, and TaxLine[{Amount, TaxLineDetail{TaxRateRef, TaxPercent}}]. NetAmountTaxable never returned. Updatable via sparse update (#55). |
| LinkedTxn | Partial | Desktop SalesReceiptQueryRq has no IncludeLinkedTxns and SalesReceiptRet carries no LinkedTxnRet (qbXML 13.0) — never populated on read. Accepted and ignored on write. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| TotalAmt | Full | Read-only; Desktop computes it. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
Everything else listed as full works unchanged.
Full fields
- CustomerRef
- TxnDate
- DocNumber
- BillAddr
- ShipAddr
- ShipDate
- ShipMethodRef
- PrivateNote
- DepositToAccountRef
Query support
Standard SELECT * FROM SalesReceipt with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- TxnTaxDetail.TotalTax supplied without TxnTaxCodeRef —
UNSUPPORTED_BY_DESKTOP: Desktop cannot honor a computed tax total. Set TxnTaxDetail.TxnTaxCodeRef or per-line TaxCodeRef explicitly. See COMPATIBILITY.md.
Bill
Verdict: Full · Read: Full · Write: Full — Account vs. item expense lines map cleanly
| QBO field | Support | Notes |
|---|---|---|
| SalesTermRef | Full | Desktop TermsRef. |
| Line | Full | Account-based and item-based expense lines; other line types return UNSUPPORTED_BY_DESKTOP. Sparse updates cannot modify lines/memo/tax yet. Both AccountBasedExpenseLineDetail.ClassRef and ItemBasedExpenseLineDetail.ClassRef are read/written, mapping to Desktop ExpenseLineAdd/ExpenseLineRet and ItemLineAdd/ItemLineRet ClassRef respectively — on ExpenseLineAdd, ClassRef sits in OSR position (AccountRef < Amount < Memo < CustomerRef < ClassRef). |
| TotalAmt | Full | Read-only, computed by Desktop as AmountDue. |
| Balance | Full | Read-only, as in QBO. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| LinkedTxn | None | UNSUPPORTED_BY_DESKTOP — QBO Bill has no paid-by LinkedTxn field. Desktop may return LinkedTxnRet when IncludeLinkedTxns is set, but there is no honest QBO home — not projected. |
Everything else listed as full works unchanged.
Full fields
- VendorRef
- TxnDate
- DueDate
- DocNumber
- PrivateNote
Query support
Standard SELECT * FROM Bill with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
BillPayment
Verdict: Partial · Read: Full · Write: Partial — Fans out to BillPaymentCheck / BillPaymentCreditCard by PayType
| QBO field | Support | Notes |
|---|---|---|
| PayType | Full | Check → BillPaymentCheck*; CreditCard → BillPaymentCreditCard*. Updates: Check family only — qbXML has no BillPaymentCreditCardMod, so credit-card-family updates fail loud with UNSUPPORTED_BY_DESKTOP (#75); delete and re-create instead. |
| VendorRef | Full | Maps to Desktop PayeeEntityRef. |
| TotalAmt | Full | Read-only from Desktop Amount; write-ignored on create/update — neither BillPaymentCheckAdd nor BillPaymentCreditCardAdd has a top-level Amount element in the OSR, Desktop derives it from the summed AppliedToTxnAdd/PaymentAmount values instead. |
| CheckPayment | Full | CheckPayment.BankAccountRef ⇄ BankAccountRef. |
| CreditCardPayment | Full | CreditCardPayment.CCAccountRef ⇄ CreditCardAccountRef. |
| PrintStatus | Partial | Check flavor only; ⇄ IsToBePrinted. BillPaymentCheckAdd requires IsToBePrinted OR RefNumber (Desktop OSR); when a create supplies neither PrintStatus nor DocNumber, TenkeyBridge synthesizes IsToBePrinted=false so the Add stays schema-valid. |
| Line | Partial | LinkedTxn bills → AppliedToTxnAdd; additional LinkedTxn VendorCredit → SetCredit. Sparse updates cannot modify lines yet. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- TxnDate
- DocNumber
- PrivateNote
Query support
Standard SELECT * FROM BillPayment with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- PayType outside Check/CreditCard —
UNSUPPORTED_BY_DESKTOP: Only Check and CreditCard map to Desktop bill-payment families.
Purchase
Verdict: Partial · Read: Full · Write: Partial — Fans out to Check / CreditCardCharge / CreditCardCredit by PaymentType
| QBO field | Support | Notes |
|---|---|---|
| PaymentType | Partial | Check and CreditCard map to Desktop families; Cash is partial (maps to Check against the supplied bank/petty-cash AccountRef — Desktop has no separate cash purchase type). |
| Credit | Full | true + PaymentType CreditCard → CreditCardCredit*; false/omitted → CreditCardCharge*. |
| AccountRef | Full | Bank account (Check/Cash) or credit-card account (CreditCard). |
| EntityRef | Full | Maps to Desktop PayeeEntityRef (Customer/Vendor/Employee). |
| PrintStatus | Partial | NeedToPrint/PrintComplete ⇄ IsToBePrinted (Check family). |
| Line | Full | AccountBasedExpenseLineDetail and ItemBasedExpenseLineDetail via shared Bill line machinery. Sparse updates cannot modify lines yet. |
| TotalAmt | Full | Read-only from Desktop Amount. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- TxnDate
- DocNumber
- PrivateNote
Query support
- List query STARTPOSITION > 1 across multi-type families —
UNSUPPORTED_QUERY: Deep iterator pagination uses the primary Check family only; page-1 and filtered queries merge Check + CreditCardCharge + CreditCardCredit (per-type order concatenated).
Not supported
- PaymentType outside Check/Cash/CreditCard —
UNSUPPORTED_BY_DESKTOP: Only Check, Cash (→Check), and CreditCard map to Desktop purchase families. - List query STARTPOSITION > 1 across multi-type families —
UNSUPPORTED_QUERY: Deep iterator pagination uses the primary Check family only; page-1 and filtered queries merge Check + CreditCardCharge + CreditCardCredit (per-type order concatenated).
PurchaseOrder
Verdict: Partial · Read: Full · Write: Partial — Non-posting; item lines only — never touches the GL on either side
| QBO field | Support | Notes |
|---|---|---|
| Line | Partial | ItemBasedExpenseLineDetail only (PurchaseOrderLineAdd). AccountBasedExpenseLineDetail returns UNSUPPORTED_BY_DESKTOP. ReceivedQty maps from ReceivedQuantity on read (read-only). Sparse updates cannot modify lines yet. |
| TotalAmt | Full | Read-only from Desktop TotalAmount. |
| POStatus | Partial | Open/Closed map to Desktop IsManuallyClosed, a Mod-only element — PurchaseOrderAdd has no IsManuallyClosed at all. Create with POStatus Open (or omitted) works; POStatus Closed on create returns UNSUPPORTED_BY_DESKTOP (create the PO open, then close it via an update). Closing via sparse update is not wired yet — POStatus is effectively read-only through TenkeyBridge until that lands. |
| APAccountRef | None | UNSUPPORTED_BY_DESKTOP — Purchase orders are non-posting — there is no AP account on Desktop POs. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- VendorRef
- TxnDate
- DocNumber
- VendorAddr
- ShipAddr
- DueDate
- ExpectedDate
- ShipMethodRef
- PrivateNote
Query support
Standard SELECT * FROM PurchaseOrder with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- AccountBasedExpenseLineDetail on a PurchaseOrder line —
UNSUPPORTED_BY_DESKTOP: Desktop PO lines are item-only. Use ItemBasedExpenseLineDetail, or post a Bill/Purchase for account expenses. - POStatus Closed on create —
UNSUPPORTED_BY_DESKTOP: Desktop's PurchaseOrderAdd has no IsManuallyClosed element — a PO can't be created already closed. Create it open, then close it via an update.
Vendor
Verdict: Full · Read: Full · Write: Full — 1099 / tax-ID field naming only
| QBO field | Support | Notes |
|---|---|---|
| PrintOnCheckName | Full | Desktop PrintAs. |
| TaxIdentifier | Full | Maps to Desktop VendorTaxIdent. |
| Vendor1099 | Full | Maps to Desktop IsVendorEligibleFor1099. |
| Balance | Full | Read-only, as in QBO. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
Everything else listed as full works unchanged.
Full fields
- DisplayName
- Active
- CompanyName
- Title
- GivenName
- MiddleName
- FamilyName
- BillAddr
- PrimaryPhone
- AlternatePhone
- Fax
- PrimaryEmailAddr
- AcctNum
Query support
Standard SELECT * FROM Vendor with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
VendorCredit
Verdict: Partial · Read: Full · Write: Partial — Bill mirror image — expense and item lines
| QBO field | Support | Notes |
|---|---|---|
| Line | Full | AccountBasedExpenseLineDetail and ItemBasedExpenseLineDetail via shared Bill line machinery. Sparse updates cannot modify lines yet. |
| TotalAmt | Full | Read-only from Desktop CreditAmount. |
| Balance | Full | Read-only remaining credit from Desktop CreditRemaining. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- VendorRef
- APAccountRef
- TxnDate
- DocNumber
- PrivateNote
Query support
Standard SELECT * FROM VendorCredit with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Account
Verdict: Full · Read: Full · Write: Full — AccountType / AccountSubType enum mapping
| QBO field | Support | Notes |
|---|---|---|
| ParentRef | Full | Becomes a Desktop sub-account; FullName is colon-delimited. |
| AccountType | Partial | Mapped per the COMPATIBILITY.md appendix; unmapped values return 422 UNMAPPED_ACCOUNT_TYPE. Desktop-only Non-Posting appears on reads. |
| AccountSubType | Partial | Accepted and ignored — Desktop has no account subtype; reads never return one. |
| FullyQualifiedName | Full | Read-only, derived by Desktop. |
| SubAccount | Full | Read-only, derived from Desktop Sublevel. |
| CurrentBalance | Full | Read-only, as in QBO. |
| CurrentBalanceWithSubAccounts | Full | Read-only; Desktop TotalBalance. |
| Classification | Partial | Accepted and ignored on writes; not returned on reads — derive it from AccountType client-side. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only for now. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| CashFlowClassification | None | UNSUPPORTED_BY_DESKTOP — Desktop AccountRet.CashFlowClassification has no honest QBO Account field; omitted rather than guessed at. |
| SpecialAccountType | None | UNSUPPORTED_BY_DESKTOP — Desktop SpecialAccountType has no honest QBO Account field; omitted rather than guessed at. |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
- AcctNum
- Description
Query support
Standard SELECT * FROM Account with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Deposit
Verdict: Partial · Read: Full · Write: Partial — Undeposited Funds → bank via LinkedTxn or manual DepositLineDetail
| QBO field | Support | Notes |
|---|---|---|
| Line | Partial | LinkedTxn (PaymentTxnID path) for undeposited payments, or DepositLineDetail{Entity, AccountRef, PaymentMethodRef, CheckNum}. Sparse updates cannot modify lines yet. |
| CashBack | Full | Maps to Desktop CashBackInfo. |
| TotalAmt | Full | Read-only from Desktop DepositTotal. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- DepositToAccountRef
- TxnDate
- PrivateNote
Query support
Standard SELECT * FROM Deposit with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
JournalEntry
Verdict: Partial · Read: Full · Write: Partial — Debit/Credit lines split across Desktop JournalDebitLine / JournalCreditLine
| QBO field | Support | Notes |
|---|---|---|
| PrivateNote | Full | Maps to Desktop Memo when the company file/OSR returns a header Memo on JournalEntry. |
| Adjustment | Full | Maps to Desktop IsAdjustment. |
| Line | Partial | JournalEntryLineDetail only. Write splits by PostingType into JournalDebitLine / JournalCreditLine; read interleaves debit then credit lists. Debits must equal credits or create fails UNSUPPORTED_BY_DESKTOP before the Desktop round-trip. Sparse updates cannot modify lines yet (Desktop JE Mod replaces the entire line table when lines are provided — same out-of-scope stance as Invoice lines / issue #55). JournalEntryLineDetail.Entity: only EntityRef is populated on read — Desktop's line-level EntityRef carries no entity-kind flag, so we don't stamp a Type (Vendor/Customer/Employee); a wrong guess is worse than omitting it. Set Type yourself on write if you know it; it's accepted and simply not echoed back. |
| TotalAmt | Full | Read-only aggregate when present; not independently computed. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- TxnDate
- DocNumber
Query support
Standard SELECT * FROM JournalEntry with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Unbalanced journal entry (debits ≠ credits) —
UNSUPPORTED_BY_DESKTOP: Desktop rejects unbalanced JEs. Balance debits and credits before create. - Line DetailType other than JournalEntryLineDetail —
UNSUPPORTED_BY_DESKTOP: Only JournalEntryLineDetail maps to Desktop journal lines.
Transfer
Verdict: Full · Read: Full · Write: Full — Bank-to-bank transfer between two accounts
| QBO field | Support | Notes |
|---|---|---|
| FromAccountRef | Full | Maps to Desktop TransferFromAccountRef. |
| ToAccountRef | Full | Maps to Desktop TransferToAccountRef. |
| CurrencyRef | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
| ExchangeRate | None | UNSUPPORTED_BY_DESKTOP — Multicurrency not yet supported. |
Everything else listed as full works unchanged.
Full fields
- Amount
- TxnDate
- PrivateNote
Query support
Standard SELECT * FROM Transfer with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Delete —
UNSUPPORTED_BY_DESKTOP: "Transfer" is not a valid qbXML TxnDelType enum value, so delete is not wired for this entity.
Class
Verdict: Full · Read: Full · Write: Full — Hierarchical Class list; SubClass/FullyQualifiedName from Desktop Sublevel/FullName
| QBO field | Support | Notes |
|---|---|---|
| ParentRef | Full | Becomes a Desktop sub-class; FullName is colon-delimited (e.g. Services:West Coast). |
| FullyQualifiedName | Full | Read-only, derived by Desktop from the parent chain. |
| SubClass | Full | Read-only, derived from Desktop Sublevel (true when Sublevel > 0). |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM Class with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
CompanyCurrency
Verdict: Full (read-only) · Read: Full · Write: None — Desktop CurrencyQuery list; empty when multicurrency is off (statusCode 3250, confirmed live, and 3170 both normalized to [])
| QBO field | Support | Notes |
|---|---|---|
| Code | Full | Desktop CurrencyCode. |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM CompanyCurrency with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Create, update, or delete —
UNSUPPORTED_BY_DESKTOP: CompanyCurrency is read/query only — Desktop CurrencyAdd/Mod is out of scope for this stretch entity; QBO also treats company currency catalog as admin-managed.
CustomerType
Verdict: Full (read-only) · Read: Full · Write: None — Read/query only — QBO CustomerType is read-only via the API; Desktop hierarchy is not exposed
Every field works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM CustomerType with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Create or update —
UNSUPPORTED_BY_DESKTOP: QBO's CustomerType is read-only via the API. TenkeyBridge matches that parity even though Desktop allows CustomerTypeAdd. Desktop ParentRef/Sublevel/FullName have no QBO CustomerType fields and are not surfaced.
Employee
Verdict: Full (read-only) · Read: Full · Write: None — Read/query only — no Desktop write path this release; payroll aggregates out of scope
| QBO field | Support | Notes |
|---|---|---|
| PrintOnCheckName | Full | Desktop PrintAs. |
| CustomField | Partial | Name/StringValue populated from Desktop custom fields (DataExt); DefinitionId not available from Desktop; read-only. |
| TargetBonus | None | UNSUPPORTED_BY_DESKTOP — Desktop payroll aggregate; license-gated and out of scope. |
| AdditionalContactRef | None | UNSUPPORTED_BY_DESKTOP — Desktop AdditionalContactRef has no honest QBO Employee field; omitted rather than guessed at. |
Everything else listed as full works unchanged.
Full fields
- GivenName
- MiddleName
- FamilyName
- Suffix
- DisplayName
- Active
- PrimaryPhone
- Mobile
- PrimaryEmailAddr
- PrimaryAddr
- HiredDate
- ReleasedDate
- BirthDate
- Gender
Query support
Standard SELECT * FROM Employee with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Create or update —
UNSUPPORTED_BY_DESKTOP: Employee is read/query only this release; TenkeyBridge doesn't expose a Desktop write path for it.
ExchangeRate
Verdict: Partial · Read: Partial · Write: None — Projected from CurrencyRet.ExchangeRate + AsOfDate; one row per currency that carries a rate; empty when multicurrency is off (statusCode 3250, confirmed live, and 3170 both normalized to [])
| QBO field | Support | Notes |
|---|---|---|
| SourceCurrencyCode | Full | Desktop CurrencyCode on the same CurrencyRet. |
| Rate | Full | Desktop ExchangeRate. |
| AsOfDate | Full | Desktop AsOfDate when present; omitted when Desktop has none. |
| TargetCurrencyCode | None | UNSUPPORTED_BY_DESKTOP — CurrencyRet has no per-row target; home currency lives on Preferences.CurrencyPrefs.HomeCurrency — never invented here. |
Everything else listed as full works unchanged.
Query support
Standard SELECT * FROM ExchangeRate with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- QBO-style keyed lookup GET /exchangerate?sourcecurrencycode=EUR[&asofdate=...] —
UNSUPPORTED_QUERY: Real QBO keys ExchangeRate by sourcecurrencycode/asofdate query params. TenkeyBridge exposes it as a conventional Id-keyed resource (Id = Desktop currency ListID) with SELECT * queries — filter by SourceCurrencyCode client-side. - Create, update, or delete —
UNSUPPORTED_BY_DESKTOP: ExchangeRate is read/query only — projected from CurrencyQuery, not a writable Desktop list. - Currencies without ExchangeRate on CurrencyRet —
UNSUPPORTED_BY_DESKTOP: Projection skips CurrencyRets that do not carry ExchangeRate (home currency rows often omit it).
PaymentMethod
Verdict: Partial · Read: Full · Write: Partial — Create only — Desktop has no PaymentMethodMod; Type coarsens Desktop's fine enum to CREDIT_CARD | NON_CREDIT_CARD
| QBO field | Support | Notes |
|---|---|---|
| Type | Partial | Desktop PaymentMethodType (Visa, Cash, Check, …) coarsens to QBO CREDIT_CARD |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM PaymentMethod with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Update —
UNSUPPORTED_BY_DESKTOP: Desktop has no PaymentMethodMod. Create a new PaymentMethod instead; list entities are not deleted — deactivate is also unavailable without Mod.
TaxAgency
Verdict: Full (read-only) · Read: Full · Write: None — Read-only projection — Vendors referenced by any ItemSalesTax.TaxVendorRef (no native Desktop TaxAgency list)
| QBO field | Support | Notes |
|---|---|---|
| DisplayName | Full | Vendor Name. |
| TaxTrackedOnPurchases | None | UNSUPPORTED_BY_DESKTOP — No Desktop equivalent on the Vendor projection. |
| TaxTrackedOnSales | None | UNSUPPORTED_BY_DESKTOP — No Desktop equivalent on the Vendor projection. |
Everything else listed as full works unchanged.
Full fields
- Active
Query support
Standard SELECT * FROM TaxAgency with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Create or update —
UNSUPPORTED_BY_DESKTOP: TaxAgency is a read-only projection of tax-vendor Vendors. Manage the Vendor (and ItemSalesTax.TaxVendorRef) in Desktop.
TaxCode
Verdict: Full · Read: Full · Write: Full — Desktop SalesTaxCode list (TAX/NON); Name max 3 chars (fail-loud, never truncated); a plain taxable/non-taxable flag pair, not a rate container
| QBO field | Support | Notes |
|---|---|---|
| Name | Full | Desktop limits Name to 3 characters. Longer names return 400 — never truncated. |
| Description | Full | Desktop Desc. |
| Taxable | Full | Desktop IsTaxable. |
| SalesTaxRateList | None | UNMAPPED_FIELD — Desktop's US edition (QBD) does not have ItemSalesTaxRef/ItemPurchaseTaxRef on SalesTaxCode — the OSR marks both 'not in QBD' (they exist only for QBCA/QBUK/QBAU). US Desktop SalesTaxCode is just the taxable/non-taxable flag pair; rate association lives on ItemSalesTax items. Read TaxRate for rate values/agency. Never returned on read; writing it faults UNMAPPED_FIELD. |
Everything else listed as full works unchanged.
Full fields
- Active
Query support
Standard SELECT * FROM TaxCode with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
TaxRate
Verdict: Full (read-only) · Read: Full · Write: None — Read-only (parity with QBO) — Desktop ItemSalesTaxQuery; each single rate item is a TaxRate; sales-tax groups are not projected as TaxRates
| QBO field | Support | Notes |
|---|---|---|
| RateValue | Full | Desktop TaxRate percentage. |
| Description | Full | Desktop ItemDesc. |
| AgencyRef | Full | Desktop TaxVendorRef — the tax agency Vendor. |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM TaxRate with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Create or update —
UNSUPPORTED_BY_DESKTOP: TaxRate is read-only in QBO; TenkeyBridge matches that parity. Desktop ItemSalesTax items are managed as Items in the company file. - ItemSalesTaxGroup as TaxRate —
UNSUPPORTED_BY_DESKTOP: Sales-tax groups are not projected as TaxRate rows. Group members are themselves ItemSalesTax list items and appear as individual TaxRates via ItemSalesTaxQuery.
Term
Verdict: Partial · Read: Full · Write: Partial — Merged StandardTerms + DateDrivenTerms; Type STANDARD | DATE_DRIVEN dispatches which Desktop list; create-only
| QBO field | Support | Notes |
|---|---|---|
| Type | Full | STANDARD ⇄ StandardTerms*; DATE_DRIVEN ⇄ DateDrivenTerms*. Fixed at create — the whole entity is create-only, so this can never change via update. |
| DueDays | Full | STANDARD only — Desktop StdDueDays. |
| DiscountDays | Full | STANDARD only — Desktop StdDiscountDays. |
| DiscountPercent | Full | Both types — Desktop DiscountPct. |
| DayOfMonthDue | Full | DATE_DRIVEN only. |
| DueNextMonthDays | Full | DATE_DRIVEN only. |
| DiscountDayOfMonth | Full | DATE_DRIVEN only. |
Everything else listed as full works unchanged.
Full fields
- Name
- Active
Query support
Standard SELECT * FROM Term with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Update any Term field —
UNSUPPORTED_BY_DESKTOP: qbXML has no StandardTermsMod or DateDrivenTermsMod — Desktop's OSR only defines Add and Query for both Terms lists. Term write support is create-only. - Deactivate a Term —
UNSUPPORTED_BY_DESKTOP: Deactivation is a Mod-only operation (IsActive via StandardTermsMod/DateDrivenTermsMod), which doesn't exist in qbXML. Impossible via the SDK, not just unimplemented here.
TimeActivity
Verdict: Partial · Read: Full · Write: Partial — Employee time only; Duration compiled from Hours/Minutes or a StartTime/EndTime span
| QBO field | Support | Notes |
|---|---|---|
| NameOf | Partial | Only "Employee" is accepted (or omitted); "Vendor" is rejected — see Not supported. |
| EmployeeRef | Full | Required; Desktop EntityRef. Missing value returns 2020. |
| ItemRef | Full | Desktop ItemServiceRef. |
| Description | Full | Desktop Notes. |
| BillableStatus | Partial | Billable, NotBillable, HasBeenBilled; any other value returns 2010. Desktop is stricter than QBO here: "Billable" requires BOTH CustomerRef and ItemRef on the same entry, or QuickBooks rejects the save ("Billable activities must have a customer:job and service item"). Send both, or mark the entry NotBillable. Omitted on create → we emit NotBillable explicitly (QBO's omitted-default); Desktop would otherwise infer Billable from CustomerRef alone. A sparse update that never mentions BillableStatus carries the stored value forward instead — the default only applies to genuinely-absent-on-create. |
| Hours | Full | Explicit duration input; wins over StartTime/EndTime when both are present. |
| Minutes | Full | Explicit duration input; wins over StartTime/EndTime when both are present. |
| StartTime | Full | Alternate duration input paired with EndTime; Desktop only stores the computed Duration, not the span itself. |
| EndTime | Full | Alternate duration input paired with StartTime; must be after it, or 2010. |
| BreakHours | Partial | Only valid alongside StartTime/EndTime; supplying it with Hours/Minutes returns 2010. |
| BreakMinutes | Partial | Only valid alongside StartTime/EndTime; supplying it with Hours/Minutes returns 2010. |
| HourlyRate | Partial | Accepted and ignored — Desktop time tracking has no pay-rate override at the API level. |
| CostRate | Partial | Accepted and ignored — Desktop time tracking has no pay-rate override at the API level. |
| Taxable | Partial | Accepted and ignored — Desktop time tracking has no taxable flag. |
| CustomField | Partial | Desktop TimeTrackingQueryRq has no OwnerID element (qbXML 13.0), so custom fields are never returned for time entries. Accepted and ignored on write. |
| CurrencyRef | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| ExchangeRate | Partial | Accepted and ignored — Desktop manages this itself; multi-currency mapping lands later. |
| PayrollItemRef | None | UNSUPPORTED_BY_DESKTOP — Desktop PayrollItemWageRef has no QBO Accounting TimeActivity equivalent (QBO Payroll is a separate product). |
| TxnNumber | None | UNSUPPORTED_BY_DESKTOP — Desktop's internal auto-increment TxnNumber has no QBO equivalent and is not surfaced. |
Everything else listed as full works unchanged.
Full fields
- TxnDate
- CustomerRef
- ClassRef
Query support
Standard SELECT * FROM TimeActivity with the shared WHERE / STARTPOSITION / MAXRESULTS subset documented in IDs, SyncToken & sparse updates. Anything outside that subset returns UNSUPPORTED_QUERY.
Not supported
- Vendor/contractor time (NameOf: "Vendor", or a VendorRef) —
UNSUPPORTED_BY_DESKTOP: Only employee time is supported this release; vendor/contractor time tracking lands in a later TenkeyBridge release.
CompanyInfo
Verdict: Full (read-only) · Read: Full · Write: None — Read-only; Id equals the realm ID, no Desktop write path
| QBO field | Support | Notes |
|---|---|---|
| LegalName | Full | Desktop LegalCompanyName. |
| CompanyAddr | Full | Desktop Address. |
| CustomerCommunicationAddr | Full | Desktop CompanyAddressForCustomer — an independent address, not a copy of CompanyAddr; absent if Desktop has none on file. |
| LegalAddr | Full | Desktop LegalAddress. |
| PrimaryPhone | Full | Desktop Phone. |
| FiscalYearStartMonth | Full | Desktop FirstMonthFiscalYear; both sides use English month names (live-verified "January"). |
| Country | Full | Desktop Address.Country, passed through as free text — no normalization, and often blank on US company files. |
| NameValue | None | UNSUPPORTED_BY_DESKTOP — No Desktop CompanyRet equivalent — omitted rather than guessed at; never returned. |
| CompanyStartDate | None | UNSUPPORTED_BY_DESKTOP — No Desktop CompanyRet equivalent — omitted rather than guessed at; never returned. |
| SupportedLanguages | None | UNSUPPORTED_BY_DESKTOP — No Desktop CompanyRet equivalent — omitted rather than guessed at; never returned. |
| DefaultTimeZone | None | UNSUPPORTED_BY_DESKTOP — No Desktop CompanyRet equivalent — omitted rather than guessed at; never returned. |
| WebAddr | None | UNSUPPORTED_BY_DESKTOP — CompanyRet has no URL field — omitted rather than guessed at; never returned. |
Everything else listed as full works unchanged.
Full fields
- CompanyName
Query support
- Any WHERE clause, or STARTPOSITION/MAXRESULTS —
UNSUPPORTED_QUERY: CompanyQueryRq takes no filters and always returns the single open company record. Use SELECT * FROM CompanyInfo.
Not supported
- Create, update, or delete —
UNSUPPORTED_BY_DESKTOP: CompanyInfo is read/query only — there is exactly one company record, and Desktop has no API to create or modify it. - Any WHERE clause, or STARTPOSITION/MAXRESULTS —
UNSUPPORTED_QUERY: CompanyQueryRq takes no filters and always returns the single open company record. Use SELECT * FROM CompanyInfo.
Preferences
Verdict: Partial · Read: Partial · Write: None — Read-only singleton (Id=1); honest subset of Desktop PreferencesQuery groups
| QBO field | Support | Notes |
|---|---|---|
| AccountingInfoPrefs | Partial | ClassTrackingPerTxn/ClassTrackingPerTxnLine ← IsUsingClassTracking (same bool projected to both); TrackDepartments always false (no Desktop Locations). |
| CurrencyPrefs | Partial | MultiCurrencyEnabled ← IsMultiCurrencyOn; HomeCurrency ← HomeCurrencyRef. |
| TimeTrackingPrefs | Partial | WorkWeekStartDate ← FirstDayOfWeek only. |
| TaxPrefs | Partial | UsingSalesTax true when SalesTaxPreferences is present on PreferencesRet; no other TaxPrefs fields. |
| SalesFormsPrefs | Partial | DefaultShipMethodRef; AllowEstimates/UsingProgressInvoicing from JobsAndEstimatesPreferences. DefaultTerms never populated — Desktop SalesAndCustomersPreferences carries no DefaultTermsRef (qbXML 13.0). IsAutoApplyingPayments has no honest QBO SalesFormsPrefs twin — omitted. |
| VendorAndPurchasesPrefs | Partial | UsingInventory ← IsUsingInventory only. DaysBillsAreDue / auto-discount have no honest QBO twin. |
| ReportPrefs | Partial | ReportBasis ← SummaryReportBasis when Cash or Accrual. |
| ProductAndServicesPrefs | None | UNSUPPORTED_BY_DESKTOP — No honest PreferencesRet projection — omitted rather than guessed. |
| EmailMessagesPrefs | None | UNSUPPORTED_BY_DESKTOP — No honest PreferencesRet projection — omitted rather than guessed. |
| OtherPrefs | None | UNSUPPORTED_BY_DESKTOP — No honest PreferencesRet projection — omitted rather than guessed. |
Everything else listed as full works unchanged.
Query support
- Any WHERE clause, or STARTPOSITION/MAXRESULTS —
UNSUPPORTED_QUERY: PreferencesQueryRq takes no filters and always returns the single open company PreferencesRet. Use SELECT * FROM Preferences.
Not supported
- Create, update, or delete —
UNSUPPORTED_BY_DESKTOP: Preferences is read/query only in QBO and Desktop — there is no PreferencesAdd/Mod. - Any WHERE clause, or STARTPOSITION/MAXRESULTS —
UNSUPPORTED_QUERY: PreferencesQueryRq takes no filters and always returns the single open company PreferencesRet. Use SELECT * FROM Preferences.
Budget
Verdict: Planned · Read: None · Write: None — qbXML has no Budget records, but budget figures are readable through BudgetSummaryReportQuery — a read-only Budget synthesized from that report is planned; budget writes stay in the Desktop UI forever.
Desktop has a real qbXML analog, but TenkeyBridge has not shipped this entity yet. Requests return UNSUPPORTED_BY_DESKTOP with a link back here until the implementation lands.
Tracking: #101
Query support
- query —
UNSUPPORTED_BY_DESKTOP: Not yet implemented. qbXML cannot enumerate budgets — BudgetSummaryReportQuery requires a FiscalYear — so the planned query path probes a bounded fiscal-year window and synthesizes deterministic Ids. See the tracking issue for the design.- Workaround: Until the read path ships, pull the budget-vs-actual reports from Desktop directly (or export), not via the Accounting API.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Not yet implemented. qbXML has no Budget record API (no BudgetQuery in the qbxmlops130 message set), but BudgetSummaryReportQuery returns budget amounts by account × period (optionally × class or × customer), which is the data QBO's read-only Budget carries. A synthesized read is planned — see the tracking issue.- Workaround: Until the read path ships, pull the budget-vs-actual reports from Desktop directly (or export), not via the Accounting API.
- query —
UNSUPPORTED_BY_DESKTOP: Not yet implemented. qbXML cannot enumerate budgets — BudgetSummaryReportQuery requires a FiscalYear — so the planned query path probes a bounded fiscal-year window and synthesizes deterministic Ids. See the tracking issue for the design.- Workaround: Until the read path ships, pull the budget-vs-actual reports from Desktop directly (or export), not via the Accounting API.
- create —
UNSUPPORTED_BY_DESKTOP: Permanent: qbXML has no BudgetAdd. Budget setup stays in the Desktop UI — QBO's own Budget entity is read-only too, so no QBO-compatible client loses anything here. - update —
UNSUPPORTED_BY_DESKTOP: Permanent: qbXML has no BudgetMod. Budget changes stay in the Desktop UI. - delete —
UNSUPPORTED_BY_DESKTOP: Permanent: qbXML has no BudgetDel.
Attachable
Verdict: Never · Read: None · Write: None — QuickBooks Desktop's qbXML API has no attachments interface — the word 'Attachment' does not occur anywhere in the qbxmlops130 message set.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: Desktop has no attachments API over qbXML — Attachable queries always fail loud.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: zero occurrences of any attachment message (no AttachmentAdd/Query/Ref of any kind) across the full qbxmlops130 schema. Desktop's Attached Documents feature is UI-only; files attached in Desktop cannot be listed or fetched through TenkeyBridge.- Workaround: Store documents in your own system keyed by the TenkeyBridge entity Id — that is what QBD integrations have always had to do.
- query —
UNSUPPORTED_BY_DESKTOP: Desktop has no attachments API over qbXML — Attachable queries always fail loud. - create —
UNSUPPORTED_BY_DESKTOP: Desktop has no attachments API over qbXML — attachments cannot be uploaded through TenkeyBridge. - update —
UNSUPPORTED_BY_DESKTOP: Desktop has no attachments API over qbXML — attachments cannot be modified through TenkeyBridge. - delete —
UNSUPPORTED_BY_DESKTOP: Desktop has no attachments API over qbXML — attachments cannot be deleted through TenkeyBridge.
Department
Verdict: Never · Read: None · Write: None — QBO Departments (locations) have no Desktop equivalent — the only 'Department'/'Location' strings in qbXML are free-text fields on Employee, FixedAsset, and Lead, and Desktop's one real dimensional list (Class) is already exposed faithfully as Class.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: qbXML has no Department/Location list to query — confirmed absent from the qbxmlops130 message set.- Workaround: Query Class instead if you remap locations client-side; that remapping is your call, TenkeyBridge never reinterprets DepartmentRef silently.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29 against the qbxmlops130 message set: qbXML has no Department or Location list — no Add/Mod/Query message pair exists. The tokens only appear as plain STRTYPE fields (Employee.Department, FixedAsset.Location, Lead.Location), which are annotations, not a queryable list.- Workaround: If your integration treats QBO locations as just another dimension, remap DepartmentRef onto Class in your own code — Class is live in TenkeyBridge. We decided against a built-in Department→Class alias, even opt-in: ClassRef already maps to Class, so aliasing would make two QBO fields silently write one Desktop list and collide when a client sends both.
- query —
UNSUPPORTED_BY_DESKTOP: qbXML has no Department/Location list to query — confirmed absent from the qbxmlops130 message set.- Workaround: Query Class instead if you remap locations client-side; that remapping is your call, TenkeyBridge never reinterprets DepartmentRef silently.
- create —
UNSUPPORTED_BY_DESKTOP: Desktop has no Department create. Use Class if you need a dimensional axis on Desktop. - update —
UNSUPPORTED_BY_DESKTOP: Desktop has no Department update. - delete —
UNSUPPORTED_BY_DESKTOP: Desktop has no Department delete.
JournalCode
Verdict: Never · Read: None · Write: None — France-only QBO regulatory feature; not applicable to Desktop — 'JournalCode' occurs nowhere in the qbxmlops130 message set.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: JournalCode is a France-locale QBO regulatory concept with no Desktop counterpart.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: JournalCode is a France-locale QBO regulatory concept (mandatory journal coding for FEC compliance) with zero counterpart in qbXML — US Desktop has no such concept to map. - query —
UNSUPPORTED_BY_DESKTOP: JournalCode is a France-locale QBO regulatory concept with no Desktop counterpart. - create —
UNSUPPORTED_BY_DESKTOP: JournalCode is a France-locale QBO regulatory concept with no Desktop counterpart. - update —
UNSUPPORTED_BY_DESKTOP: JournalCode is a France-locale QBO regulatory concept with no Desktop counterpart. - delete —
UNSUPPORTED_BY_DESKTOP: JournalCode is a France-locale QBO regulatory concept with no Desktop counterpart.
RecurringTransaction
Verdict: Never · Read: None · Write: None — Desktop's memorized transactions are not exposed by qbXML — there is no message to list, read, create, or execute them.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: Memorized transactions cannot be enumerated via qbXML — zero functional API surface.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: no MemorizedTxn message of any kind exists in the qbxmlops130 message set. The only trace of the concept in the entire schema is a cosmetic 'memorizedTxn' row label in generic report output — a taxonomy tag, not an access path to a memorized transaction's contents or schedule.- Workaround: Manage memorized transactions in the Desktop UI. Transactions they generate ARE visible through TenkeyBridge once QuickBooks posts them — they arrive as ordinary invoices/bills/etc.
- query —
UNSUPPORTED_BY_DESKTOP: Memorized transactions cannot be enumerated via qbXML — zero functional API surface. - create —
UNSUPPORTED_BY_DESKTOP: Memorized transactions cannot be created via qbXML; manage them in the Desktop UI. - update —
UNSUPPORTED_BY_DESKTOP: Memorized transactions cannot be updated via qbXML; manage them in the Desktop UI. - delete —
UNSUPPORTED_BY_DESKTOP: Memorized transactions cannot be deleted via qbXML; manage them in the Desktop UI.
ReimburseCharge
Verdict: Never · Read: None · Write: None — QBO's billable-charge object has no Desktop record behind it — in qbXML, billability is a status flag (BillableStatus) on the source expense/item/time lines, never a standalone charge you can query.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: No standalone billable-charge object exists in qbXML to query; billability is line-level state on source transactions.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: 'ReimburseCharge' occurs nowhere in the qbxmlops130 message set. Desktop models billability as a BillableStatus enum (Billable / NotBillable / HasBeenBilled) on expense and item lines of purchase transactions and on time entries — there is no separate queryable charge object to project one from.- Workaround: Read billable state where Desktop actually keeps it: TimeActivity exposes BillableStatus today, and billable purchase lines live on their source Bill/Purchase transactions.
- query —
UNSUPPORTED_BY_DESKTOP: No standalone billable-charge object exists in qbXML to query; billability is line-level state on source transactions. - create —
UNSUPPORTED_BY_DESKTOP: ReimburseCharge is a QBO cloud concept with no Desktop qbXML analog; mark source lines Billable instead. - update —
UNSUPPORTED_BY_DESKTOP: ReimburseCharge is a QBO cloud concept with no Desktop qbXML analog. - delete —
UNSUPPORTED_BY_DESKTOP: ReimburseCharge is a QBO cloud concept with no Desktop qbXML analog.
TaxClassification
Verdict: Never · Read: None · Write: None — Cloud automated-sales-tax concept with no Desktop counterpart — Desktop's tax model is explicit tax items and codes, all of which TenkeyBridge exposes.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: TaxClassification is part of QBO's automated sales tax stack; Desktop uses explicit tax items/codes instead.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: 'TaxClassification' occurs nowhere in the qbxmlops130 message set. Desktop's tax machinery is ItemSalesTax / ItemSalesTaxGroup / SalesTaxCode — explicit records, not AST classification codes — and those ARE available through TenkeyBridge as TaxRate, TaxCode, and TaxAgency.- Workaround: Use TaxCode/TaxRate/TaxAgency for Desktop's real tax model instead of AST classifications.
- query —
UNSUPPORTED_BY_DESKTOP: TaxClassification is part of QBO's automated sales tax stack; Desktop uses explicit tax items/codes instead. - create —
UNSUPPORTED_BY_DESKTOP: TaxClassification cannot be created on Desktop via qbXML. - update —
UNSUPPORTED_BY_DESKTOP: TaxClassification cannot be updated on Desktop via qbXML. - delete —
UNSUPPORTED_BY_DESKTOP: TaxClassification cannot be deleted on Desktop via qbXML.
TaxService
Verdict: Never · Read: None · Write: None — Cloud AST onboarding operation with no Desktop counterpart — 'TaxService' occurs nowhere in the qbxmlops130 message set.
This entity has no honest QuickBooks Desktop equivalent. Every verb returns UNSUPPORTED_BY_DESKTOP — never a silent empty list.
Query support
- query —
UNSUPPORTED_BY_DESKTOP: TaxService is a QBO automated-sales-tax onboarding op with no Desktop API.
Not supported
- read —
UNSUPPORTED_BY_DESKTOP: Re-audited 2026-07-29: TaxService is QBO's automated-sales-tax onboarding endpoint; qbXML has zero AST surface. Desktop tax setup happens through ItemSalesTax/SalesTaxCode records, exposed by TenkeyBridge as TaxRate/TaxCode/TaxAgency.- Workaround: Create tax rates and codes through TaxRate/TaxCode instead of the AST TaxService flow.
- query —
UNSUPPORTED_BY_DESKTOP: TaxService is a QBO automated-sales-tax onboarding op with no Desktop API. - create —
UNSUPPORTED_BY_DESKTOP: TaxService is a QBO automated-sales-tax onboarding op with no Desktop API. - update —
UNSUPPORTED_BY_DESKTOP: TaxService is a QBO automated-sales-tax onboarding op with no Desktop API. - delete —
UNSUPPORTED_BY_DESKTOP: TaxService is a QBO automated-sales-tax onboarding op with no Desktop API.
Batch
Verdict: Full · Read: Full · Write: Full — Batch envelope — up to 30 create/update/delete/query operations in one request, executed sequentially with per-item faults.
This is a gateway-level platform endpoint — not an entity. It cannot be queried or CRUD'd through the entity routes.
http
POST /v3/company/{realmId}/batch| QBO field | Support | Notes |
|---|---|---|
| bId | Full | Required and unique per request; echoed verbatim on each BatchItemResponse slot. |
| operation (create | update | delete) |
| Query items | Full | Full /query parity: the shared WHERE subset, STARTPOSITION/MAXRESULTS, iterator-backed deep pages. |
| per-item faults | Full | A failed item returns a Fault slot (with the tkb help block); the rest of the batch still runs. |
Everything else listed as full works unchanged.
Not supported
- more than 30 items —
BATCH_TOO_MANY_ITEMS: QBO's own per-request cap, cloned. Split into multiple batch calls. - optionsData (e.g. void) —
BATCH_UNSUPPORTED_OPTION: No wired TxnVoid path against Desktop yet — the item faults loud; the rest of the batch runs. - transactional rollback —
UNSUPPORTED_BY_DESKTOP: Batch is not a transaction (QBO's isn't either): items succeed or fault independently; earlier writes are never rolled back by a later failure. - entity CRUD or /query on Batch itself —
UNSUPPORTED_BY_DESKTOP: Batch is a platform endpoint, not an entity — POST /v3/company/{realmId}/batch.
CDC
Verdict: Full (read-only) · Read: Full · Write: None — Change Data Capture — one poll returns changed + deleted records across entities.
This is a gateway-level platform endpoint — not an entity. It cannot be queried or CRUD'd through the entity routes.
http
GET /v3/company/{realmId}/cdc?entities=Invoice,Customer&changedSince=2026-07-01| QBO field | Support | Notes |
|---|---|---|
| entities | Full | Comma-separated QBO entity names. Unsupported names return per-entity Fault slots; live entities in the same request still return data. |
| changedSince | Full | ISO 8601 timestamp or YYYY-MM-DD, at most 30 days back (QBO's own limit). |
| deleted-record stubs | Full | status:'Deleted' stubs via Desktop's TxnDeletedQuery/ListDeletedQuery, with TimeDeleted as MetaData.LastUpdatedTime. |
Everything else listed as full works unchanged.
Not supported
- changedSince older than 30 days —
CDC_INVALID_CHANGED_SINCE: Hard limit, cloned from QBO. Use /query with a MetaData.LastUpdatedTime filter for older data. - more than 1,000 objects for one entity —
CDC_OVERFLOW: Loud per-entity fault, never silent truncation. Page through /query instead. - deactivated list records reported as deletions —
UNSUPPORTED_BY_DESKTOP: Desktop only hard-deletes unused list records. Active:false is a change, not a deletion — it surfaces as a changed record. - deleted TaxAgency / ExchangeRate / Transfer detection —
UNSUPPORTED_BY_DESKTOP: Tax agencies are vendors on Desktop (deletion indistinguishable); exchange rates ride the Currency list; 'Transfer' is not a valid TxnDelType.
Reports
Verdict: Partial · Read: Partial · Write: None — Five QBO-compatible reports translated live from Desktop's report engine.
This is a gateway-level platform endpoint — not an entity. It cannot be queried or CRUD'd through the entity routes.
http
GET /v3/company/{realmId}/reports/ProfitAndLoss?start_date=2026-01-01&end_date=2026-12-31| QBO field | Support | Notes |
|---|---|---|
| ProfitAndLoss / BalanceSheet / TrialBalance | Full | GeneralSummaryReportQueryRq (ProfitAndLossStandard / BalanceSheetStandard / TrialBalance). Values verbatim from Desktop — no recomputation. |
| AgedReceivables / AgedPayables | Full | AgingReportQueryRq (ARAgingSummary / APAgingSummary). Desktop's file-configured aging buckets come back as columns, honestly. |
| start_date / end_date / date_macro | Full | ISO dates or QBO date macros (fiscal-relative on both sides, so macros map 1:1). Omit them and you get fiscal year-to-date, matching QBO — Desktop's own bare default is month-to-date, so TenkeyBridge always sends an explicit period. |
| report_date | Full | The aging reports are as-of a single date. Omit it and QBO's default (today) is used. |
| accounting_method | Partial | REPORT_UNSUPPORTED_OPTION — Cash/Accrual on the three summary reports. Aging reports reject it — qbXML has no ReportBasis there. |
| Column titles | Partial | Desktop's own column titles pass through verbatim, so aging buckets read '> 90' where QBO says '91 and over', and a period column reads 'Jan - Dec 26' where QBO says 'Total'. QBO's MetaData.ColKey has no Desktop equivalent and is not invented. |
Everything else listed as full works unchanged.
Not supported
- columns / customer / vendor / item / class / department / qzurl / adjusted_gain_loss —
REPORT_UNSUPPORTED_OPTION: Column and filter customization is v2. Desktop returns its standard report layout. - aging_period / num_periods / aging_method —
REPORT_UNSUPPORTED_OPTION: Desktop aging buckets are company-file configuration, not request parameters. - summarize_column_by other than Total —
REPORT_UNSUPPORTED_OPTION: qbXML SummarizeColumnsBy exists — clean v2 upgrade path. - other QBO report names (CashFlow, detail/aging-detail variants, …) —
REPORT_UNKNOWN: Planned. The fault lists the five supported reports.