Debugging QuickBooks Online API: Missing Sales Tax Category Due to MinorVersion Parameter

By manhnv, at: March 5, 2025, 2:01 p.m.

Estimated Reading Time: __READING_TIME__ minutes

Debugging QuickBooks Online API: Missing Sales Tax Category Due to MinorVersion Parameter
Debugging QuickBooks Online API: Missing Sales Tax Category Due to MinorVersion Parameter

Debugging QuickBooks Online API: Missing Sales Tax Category Due to MinorVersion Parameter

 

Introduction


While working with the QuickBooks Online (QBO) API, I encountered an inconsistency between UAT and Production environments when retrieving invoice and item data. The issue? The TaxClassificationRef field, which helps determine an item’s sales tax category, was missing in production but present in UAT.

After debugging, I discovered the root cause was the minorversion parameter in the API request. This blog post documents my findings, the debugging process, and the final solution.

 

The Problem: Missing TaxClassificationRef in Production


I ran the following Python QuickBooks queries for Invoice and Item in both UAT and Production:


Production API Response (Missing TaxClassificationRef)


Invoice Query Response

Invoice.get(9999, qb=qb).to_dict()

 

Relevant Output Snippet

{'Id': '9999',
 'SyncToken': '1',
 'sparse': False,
 'domain': 'QBO',
 'Deposit': 0,
 'Balance': 455.73,
 'AllowIPNPayment': False,
 'AllowOnlineCreditCardPayment': True,
 'AllowOnlineACHPayment': True,
 'DocNumber': '1927',
 'PrivateNote': '',
 'DueDate': '2025-04-04',
 'ShipDate': '',
 'TrackingNum': '',
 'TotalAmt': 455.73,
 'TxnDate': '2025-03-05',
 'ApplyTaxAfterDiscount': False,
 'PrintStatus': 'NeedToPrint',
 'EmailStatus': 'NotSet',
 'ExchangeRate': 1,
 'GlobalTaxCalculation': 'TaxExcluded',
 'InvoiceLink': '',
 'HomeBalance': 0,
 'HomeTotalAmt': 0,
 'FreeFormAddress': False,
 'EInvoiceStatus': None,
 'BillAddr': {'Id': '715',
  'Line1': 'Glinteco',
  'Line2': '132 My Street',
  'Line3': 'Kingston, New York 12401 US',
  'Line4': '',
  'Line5': '',
  'City': '',
  'CountrySubDivisionCode': '',
  'Country': '',
  'PostalCode': '',
  'Lat': '',
  'Long': '',
  'Note': ''},
 'ShipAddr': {'Id': '716',
  'Line1': 'Glinteco',
  'Line2': '132 My Street',
  'Line3': 'Kingston, New York 12401 US',
  'Line4': '',
  'Line5': '',
  'City': '',
  'CountrySubDivisionCode': '',
  'Country': '',
  'PostalCode': '',
  'Lat': '',
  'Long': '',
  'Note': ''},
 'BillEmail': {'Address': '[email protected]'},
 'BillEmailCc': None,
 'BillEmailBcc': None,
 'CustomerRef': {'value': '145', 'name': 'Glinteco', 'type': ''},
 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar', 'type': ''},
 'CustomerMemo': None,
 'DepartmentRef': None,
 'TxnTaxDetail': {'TotalTax': 34.73,
  'TxnTaxCodeRef': {'value': '3', 'name': '', 'type': ''},
  'TaxLine': [{'Amount': 26.31,
    'DetailType': 'TaxLineDetail',
    'TaxLineDetail': {'PercentBased': True,
     'TaxPercent': 6.25,
     'NetAmountTaxable': 0,
     'TaxRateRef': {'value': '3', 'name': '', 'type': ''}}},
   {'Amount': 0,
    'DetailType': 'TaxLineDetail',
    'TaxLineDetail': {'PercentBased': True,
     'TaxPercent': 0,
     'NetAmountTaxable': 0,
     'TaxRateRef': {'value': '4', 'name': '', 'type': ''}}},
   {'Amount': 5.26,
    'DetailType': 'TaxLineDetail',
    'TaxLineDetail': {'PercentBased': True,
     'TaxPercent': 1.25,
     'NetAmountTaxable': 0,
     'TaxRateRef': {'value': '5', 'name': '', 'type': ''}}},
   {'Amount': 3.16,
    'DetailType': 'TaxLineDetail',
    'TaxLineDetail': {'PercentBased': True,
     'TaxPercent': 0.75,
     'NetAmountTaxable': 0,
     'TaxRateRef': {'value': '6', 'name': '', 'type': ''}}}]},
 'DeliveryInfo': None,
 'RecurDataRef': None,
 'TaxExemptionRef': None,
 'MetaData': {'CreateTime': '2025-03-04T20:02:58-08:00',
  'LastUpdatedTime': '2025-03-04T20:03:02-08:00'},
 'CustomField': [{'DefinitionId': '1',
   'Type': 'StringType',
   'Name': 'PO Number',
   'StringValue': ''}],
 'Line': [{'Id': '1',
   'LineNum': 1,
   'Description': None,
   'Amount': 421.0,
   'DetailType': 'SalesItemLineDetail',
   'LinkedTxn': [],
   'CustomField': [],
   'SalesItemLineDetail': {'UnitPrice': 421,
    'Qty': 1,
    'ServiceDate': '9999-12-31',
    'TaxInclusiveAmt': 0,
    'MarkupInfo': None,
    'ItemRef': {'value': '1010000001',
     'name': 'Services:glinteco',
     'type': ''},
    'ClassRef': None,
    'TaxCodeRef': {'value': 'TAX', 'name': '', 'type': ''},
    'PriceLevelRef': None}},
  {'Id': None,
   'LineNum': 0,
   'Description': None,
   'Amount': 421.0,
   'DetailType': 'SubTotalLineDetail',
   'LinkedTxn': [],
   'CustomField': [],
   'SubtotalLineDetail': None,
   'SubTotalLineDetail': {}}],
 'LinkedTxn': [],
 'AllowOnlinePayment': False,
 'SalesTermRef': {'value': '3', 'name': 'Net 30', 'type': ''}}

 

Item Query Response

Item.get(20812, qb=qb).to_dict()

 

Relevant Output Snippet

{'Id': '20812',
 'SyncToken': '0',
 'sparse': False,
 'domain': 'QBO',
 'Name': 'glinteco',
 'Description': '',
 'Active': True,
 'SubItem': True,
 'FullyQualifiedName': 'Services:glinteco',
 'Taxable': True,
 'SalesTaxIncluded': None,
 'UnitPrice': 0,
 'Type': 'Service',
 'Level': 1,
 'PurchaseDesc': None,
 'PurchaseTaxIncluded': None,
 'PurchaseCost': 0,
 'TrackQtyOnHand': False,
 'QtyOnHand': None,
 'InvStartDate': None,
 'AssetAccountRef': None,
 'ExpenseAccountRef': None,
 'IncomeAccountRef': {'value': '1', 'name': 'Services', 'type': ''},
 'SalesTaxCodeRef': None,
 'ParentRef': {'value': '15', 'name': 'Services', 'type': ''},
 'PurchaseTaxCodeRef': None,
 'AbatementRate': None,
 'ReverseChargeRate': None,
 'ServiceType': None,
 'ItemCategoryType': None,
 'Sku': None,
 'MetaData': {'CreateTime': '2025-03-04T20:02:29-08:00',
  'LastUpdatedTime': '2025-03-04T20:02:29-08:00'}}

 

UAT API Response (Contains TaxClassificationRef)


In UAT, the same queries returned a complete dataset, including TaxClassificationRef:

{'Id': '152',
 'SyncToken': '0',
 'sparse': False,
 'domain': 'QBO',
 'Deposit': 0,
 'Balance': 35.0,
 'AllowIPNPayment': False,
 'AllowOnlineCreditCardPayment': False,
 'AllowOnlineACHPayment': False,
 'DocNumber': '1045',
 'PrivateNote': '',
 'DueDate': '2025-04-04',
 'ShipDate': '',
 'TrackingNum': '',
 'TotalAmt': 35.0,
 'TxnDate': '2025-03-05',
 'ApplyTaxAfterDiscount': False,
 'PrintStatus': 'NeedToPrint',
 'EmailStatus': 'NotSet',
 'ExchangeRate': 1,
 'GlobalTaxCalculation': 'TaxExcluded',
 'InvoiceLink': 'https://developer.intuit.com/comingSoonview/scs-v1-12312?locale=en_US&cta=v3invoicelink',
 'HomeBalance': 0,
 'HomeTotalAmt': 0,
 'FreeFormAddress': True,
 'EInvoiceStatus': None,
 'BillAddr': {'Id': '2',
  'Line1': '4581 Finch St.',
  'Line2': '',
  'Line3': '',
  'Line4': '',
  'Line5': '',
  'City': 'Bayshore',
  'CountrySubDivisionCode': 'CA',
  'Country': '',
  'PostalCode': '94326',
  'Lat': 'INVALID',
  'Long': 'INVALID',
  'Note': ''},
 'ShipAddr': {'Id': '2',
  'Line1': '4581 Finch St.',
  'Line2': '',
  'Line3': '',
  'Line4': '',
  'Line5': '',
  'City': 'Bayshore',
  'CountrySubDivisionCode': 'CA',
  'Country': '',
  'PostalCode': '94326',
  'Lat': 'INVALID',
  'Long': 'INVALID',
  'Note': ''},
 'BillEmail': {'Address': '[email protected]'},
 'BillEmailCc': None,
 'BillEmailBcc': None,
 'CustomerRef': {'value': '1', 'name': "Amy's Bird Sanctuary", 'type': ''},
 'CurrencyRef': {'value': 'USD', 'name': 'United States Dollar', 'type': ''},
 'CustomerMemo': {'value': 'Thank you for your business and have a great day!'},
 'DepartmentRef': None,
 'TxnTaxDetail': {'TotalTax': 0,
  'TxnTaxCodeRef': {'value': '4', 'name': '', 'type': ''},
  'TaxLine': [{'Amount': 0,
    'DetailType': 'TaxLineDetail',
    'TaxLineDetail': {'PercentBased': True,
     'TaxPercent': 0,
     'NetAmountTaxable': 35.0,
     'TaxRateRef': {'value': '6', 'name': '', 'type': ''}}}]},
 'DeliveryInfo': None,
 'RecurDataRef': None,
 'TaxExemptionRef': {'value': '', 'name': '', 'type': ''},
 'MetaData': {'CreateTime': '2025-03-04T18:50:26-08:00',
  'LastUpdatedTime': '2025-03-04T18:50:26-08:00',
  'LastModifiedByRef': {'value': '9341454203477221'}},
 'CustomField': [],
 'Line': [{'Id': '1',
   'LineNum': 1,
   'Description': 'Tree and Shrub Trimming',
   'Amount': 35.0,
   'DetailType': 'SalesItemLineDetail',
   'LinkedTxn': [],
   'CustomField': [],
   'SalesItemLineDetail': {'UnitPrice': 35,
    'Qty': 1,
    'ServiceDate': '',
    'TaxInclusiveAmt': 0,
    'MarkupInfo': None,
    'ItemRef': {'value': '18', 'name': 'Trimming', 'type': ''},
    'ClassRef': None,
    'TaxCodeRef': {'value': 'TAX', 'name': '', 'type': ''},
    'PriceLevelRef': None,
    'ItemAccountRef': {'value': '45', 'name': 'Landscaping Services'},
    'TaxClassificationRef': {'value': 'EUC-9922-V1-6685'}}},
  {'Id': None,
   'LineNum': 0,
   'Description': None,
   'Amount': 35.0,
   'DetailType': 'SubTotalLineDetail',
   'LinkedTxn': [],
   'CustomField': [],
   'SubtotalLineDetail': None,
   'SubTotalLineDetail': {}}],
 'LinkedTxn': [],
 'AllowOnlinePayment': False,
 'SalesTermRef': {'value': '3', 'name': 'Net 30', 'type': ''}}

 

This has the TaxClassificationRef

"SalesItemLineDetail": { "ItemRef": {"value": "18", "name": "Trimming"}, "TaxCodeRef": {"value": "TAX", "name": ""}, "TaxClassificationRef": {"value": "EUC-9922-V1-6685"} # PRESENT }

 

Key Difference:
 

  • UAT: TaxClassificationRef exists.
     
  • Production: TaxClassificationRef is missing.

 

Debugging the Issue


Step 1: Checking QBO API Docs


I reviewed the QuickBooks Online API documentation and found that TaxClassificationRef should be returned if the item is taxable. This meant something was suppressing this field in Production.


Step 2: Investigating Python QuickBooks Library


Since I was using the python-quickbooks library, I suspected it might be causing the issue. I tried fetching the same data directly using Postman.


Step 3: Postman API Test

 

QBO Invoice Item API Request Postman

 


I created a Postman collection and manually requested:
 

  1. GET /v3/company/{companyId}/invoice/{invoiceId}
     
  2. GET /v3/company/{companyId}/item/{itemId}
     

Results:
 

  • UAT: TaxClassificationRef was present.
     
  • Production: TaxClassificationRef was missing.
     

Step 4: Identifying the Root Cause


After experimenting with different API parameters, I found that the minorversion parameter was responsible for the discrepancy.
 

  • UAT does not require minorversion to return the latest data.
     
  • Production requires minorversion=75 to return TaxClassificationRef.
     

Production API Request Without MinorVersion

GET https://quickbooks.api.intuit.com/v3/company/{companyId}/query?query=SELECT * FROM Item WHERE Id = '20812'

 

Result:

  • TaxClassificationRef missing.
     

Production API Request With MinorVersion

GET https://quickbooks.api.intuit.com/v3/company/{companyId}/query?query=SELECT * FROM Item WHERE Id = '20812'&minorversion=75

 

Result:

  • TaxClassificationRef present.
     

 

The Solution: Always Use MinorVersion in Production


To ensure consistent data between UAT and Production, I updated my API queries to explicitly include minorversion=75 in Production.


Updated Python Query
 

minor_version = "75" if ENV == "production" else None query_url = f"https://quickbooks.api.intuit.com/v3/company/{company_id}/query?query=SELECT * FROM Item WHERE Id = '{item_id}'" if minor_version: query_url += f"&minorversion={minor_version}"

 

Why This Works
 

  • minorversion=75 ensures QBO returns the latest API response format.
     
  • Prevents missing fields like TaxClassificationRef in Production.
     
  • UAT works fine without minorversion, but including it ensures consistency.

 

Lessons Learned
 

  1. API behaviors can differ between UAT and Production.
     
  2. Always cross-check data using Postman or raw API calls.
     
  3. Review QuickBooks API documentation for changes in minor versions.
     
  4. Explicitly set minorversion in Production to avoid missing fields.
     
  5. If using the python-quickbooks library, verify it supports the latest QBO API changes.

 

Final Thoughts


This issue was a great reminder that minor versions can impact API responses in unexpected ways. If you're working with QuickBooks Online API and notice missing fields, check if you need to specify a minor version!

Hope this helps others facing similar QBO integration challenges!

Let me know if you have any questions! 

Tag list:
- QuickBooks
- Fix missing TaxClassificationRef in QBO
- QuickBooks Online integration troubleshooting
- QuickBooks API missing fields
- QuickBooks Item API
- QuickBooks Online API issue
- QuickBooks API sales tax category
- QuickBooks API tax classification
- QuickBooks API minorversion impact
- QuickBooks python-quickbooks library issue
- QBO minorversion parameter
- QBO API UAT vs PROD differences
- QuickBooks Invoice API

Subscribe

Subscribe to our newsletter and never miss out lastest news.