-
-
Save indiamos/11c4921e23479de135e96e19bbe0b3e6 to your computer and use it in GitHub Desktop.
When trying to enable settings in QuickBooks Online sandbox accounts, you encounter this error:
"You and Craig Carlson were working on this at the same time.
Craig Carlson finished before you did, so your work was not saved."
This is a SyncToken conflict. The sandbox UI has a bug that prevents these settings from being enabled through the normal interface.
Use the QuickBooks API directly with the correct SyncToken pattern. This script demonstrates the pattern by enabling class tracking.
If you found this from the Intuit Developer forum: This gist addresses the same Craig Carlson error when (1) enabling account numbers in the sandbox chart of accounts, or (2) turning on categories (class tracking) in the sandbox. Both use the Preferences endpoint and the steps below. For account numbers, see Enabling account numbers (chart of accounts). For categories/classes, run the script or use the Postman guide Request 2.
curlandjqinstalled- QuickBooks sandbox OAuth access token
- Your sandbox Realm ID (Company ID)
On macOS and Linux, make the script executable once (required so you can run ./enable_qbo_classes.sh):
chmod +x enable_qbo_classes.shThen set your credentials and run the script:
export QBO_REALM_ID='your_realm_id'
export QBO_ACCESS_TOKEN='your_access_token'
./enable_qbo_classes.shOn Windows (e.g. Git Bash or WSL), you can run the script without chmod by invoking bash explicitly: bash enable_qbo_classes.sh.
Or inline:
QBO_REALM_ID='123' QBO_ACCESS_TOKEN='token' ./enable_qbo_classes.shThe script uses the Preferences endpoint and follows QuickBooks' required SyncToken pattern:
- GET
/v3/company/{realmId}/preferencesto retrieve the current SyncToken andAccountingInfoPrefs - POST to
/v3/company/{realmId}/preferences?operation=updatewith that SyncToken, settingAccountingInfoPrefs.ClassTrackingPerTxnandClassTrackingPerTxnLinetotrue - Verify by GETting Preferences again and checking both flags
This avoids the "Craig Carlson" error by properly synchronizing with QuickBooks' optimistic locking mechanism.
This script enables class tracking via Preferences.AccountingInfoPrefs:
ClassTrackingPerTxn: true— assign one class to the entire transactionClassTrackingPerTxnLine: true— assign a class per line
The same "Craig Carlson" (SyncToken) error appears when enabling other settings in the sandbox (e.g. account numbers, departments). The fix is the same: use the API with the correct SyncToken pattern. Many Intuit Developer forum posts ask about this; the solution is always GET the entity → use the returned SyncToken in your update.
If you get the Craig Carlson error when turning on account numbers in the sandbox, use the Preferences endpoint (same as this script), but set UseAccountNumbers instead of the class-tracking flags:
- GET
/v3/company/{realmId}/preferencesand note theSyncToken. - POST to
/v3/company/{realmId}/preferences?operation=updatewith:sparse: trueSyncToken: the value from step 1AccountingInfoPrefs:{ "UseAccountNumbers": true }
The Postman guide (Request 3) and Settings Reference show this explicitly. You can adapt the bash script by changing the update body to send UseAccountNumbers: true in AccountingInfoPrefs instead of (or in addition to) the class-tracking fields.
To enable other Preferences (e.g. departments, sales form options), keep the same GET-Preferences → POST-update pattern and change the body to the relevant prefs. See the Settings Reference for locations of other settings.
Note on API vs. docs: Intuit's API exposes class tracking via Preferences (AccountingInfoPrefs.ClassTrackingPerTxn and ClassTrackingPerTxnLine), which matches the UI (Settings → Advanced → Categories). Some docs also mention IsClassTrackingOn under CompanyInfo; when we tried updating that via the CompanyInfo update endpoint, the API returned "Unsupported Operation." Using the Preferences endpoint worked. If your environment or Intuit's docs differ, try the approach that works for your app or check the latest Preferences and CompanyInfo docs.
Your Realm ID (Company ID) is in the QuickBooks URL when you're logged into your sandbox:
https://app.sandbox.qbo.intuit.com/app/company/{REALM_ID}/...
You need to implement OAuth 2.0 flow to get an access token. See:
Cause: The SyncToken changed between the GET and POST requests (very rare).
Solution: Just re-run the script. It will fetch a fresh SyncToken.
Cause: Your OAuth token expired or is invalid.
Solution:
- Generate a new OAuth access token
- Make sure you're using a token with the correct scopes (
com.intuit.quickbooks.accounting)
Cause: Wrong Realm ID.
Solution:
- Verify your Realm ID is correct
- Make sure you're using the sandbox environment, not production
The script will detect whether class tracking is already enabled and exit gracefully:
Class tracking is already enabled (per-txn and per-line).
QuickBooks uses optimistic locking via SyncToken to prevent conflicting updates:
- Every entity has a
SyncTokenthat increments with each change - You must provide the current SyncToken when updating
- If your SyncToken doesn't match (because someone else updated it), you get a "Stale Object Error"
- The "Craig Carlson" error is QuickBooks' user-friendly way of saying "your SyncToken is stale"
The solution: Always GET the entity first to retrieve the current SyncToken, then immediately POST your update with that token.
The QuickBooks sandbox UI appears to have a bug where it:
- Doesn't properly refresh the SyncToken before updates, or
- Has race conditions that cause stale tokens
By using the API directly and following the proper GET-then-POST pattern, we bypass this UI bug entirely.
This script is designed for sandbox environments. For production:
-
Change the base URL:
export QBO_BASE_URL='https://quickbooks.api.intuit.com'
-
Use your production Realm ID and OAuth token
-
Be careful! Production changes affect real company data.
See the Postman Examples for manual API examples and the Settings Reference for a list of other settings you can enable using this pattern.
This script and documentation were generated with assistance from:
- Cursor - AI-powered code editor
- Claude Code - Anthropic's CLI coding assistant
MIT - Use freely, no warranty provided.
| #!/bin/bash | |
| # QuickBooks Online: Enable Classes Script | |
| # Uses the Preferences endpoint (AccountingInfoPrefs) and the SyncToken pattern. | |
| set -e # Exit on error | |
| # Configuration - UPDATE THESE VALUES | |
| REALM_ID="${QBO_REALM_ID:-}" # Your QuickBooks Realm ID (Company ID) | |
| ACCESS_TOKEN="${QBO_ACCESS_TOKEN:-}" # Your OAuth access token | |
| BASE_URL="${QBO_BASE_URL:-https://sandbox-quickbooks.api.intuit.com}" | |
| # Colors for output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' # No Color | |
| # Check if required variables are set | |
| if [ -z "$REALM_ID" ] || [ -z "$ACCESS_TOKEN" ]; then | |
| echo -e "${RED}Error: QBO_REALM_ID and QBO_ACCESS_TOKEN must be set${NC}" | |
| echo "" | |
| echo "Usage:" | |
| echo " export QBO_REALM_ID='your_realm_id'" | |
| echo " export QBO_ACCESS_TOKEN='your_access_token'" | |
| echo " ./enable_qbo_classes.sh" | |
| echo "" | |
| echo "Or set them inline:" | |
| echo " QBO_REALM_ID='123' QBO_ACCESS_TOKEN='token' ./enable_qbo_classes.sh" | |
| exit 1 | |
| fi | |
| PREFERENCES_URL="${BASE_URL}/v3/company/${REALM_ID}/preferences" | |
| echo -e "${YELLOW}Step 1: Getting Preferences to retrieve SyncToken...${NC}" | |
| # Step 1: GET Preferences | |
| RESPONSE=$(curl -s -w "\n%{http_code}" \ | |
| -X GET \ | |
| -H "Authorization: Bearer ${ACCESS_TOKEN}" \ | |
| -H "Accept: application/json" \ | |
| "$PREFERENCES_URL") | |
| HTTP_CODE=$(echo "$RESPONSE" | tail -n1) | |
| BODY=$(echo "$RESPONSE" | sed '$d') | |
| if [ "$HTTP_CODE" != "200" ]; then | |
| echo -e "${RED}Error: Failed to get preferences (HTTP $HTTP_CODE)${NC}" | |
| echo "$BODY" | jq '.' 2>/dev/null || echo "$BODY" | |
| exit 1 | |
| fi | |
| # Extract SyncToken and Id (Preferences response may use .Preferences or .preferences) | |
| SYNC_TOKEN=$(echo "$BODY" | jq -r '(.Preferences // .preferences).SyncToken // empty') | |
| PREF_ID=$(echo "$BODY" | jq -r '(.Preferences // .preferences).Id // empty') | |
| CLASS_PER_TXN=$(echo "$BODY" | jq -r '(.Preferences // .preferences).AccountingInfoPrefs.ClassTrackingPerTxn // false') | |
| CLASS_PER_LINE=$(echo "$BODY" | jq -r '(.Preferences // .preferences).AccountingInfoPrefs.ClassTrackingPerTxnLine // false') | |
| if [ -z "$SYNC_TOKEN" ]; then | |
| echo -e "${RED}Error: Could not extract SyncToken from preferences response${NC}" | |
| echo "$BODY" | jq '.' | |
| exit 1 | |
| fi | |
| echo -e "${GREEN}✓ Retrieved SyncToken: ${SYNC_TOKEN}${NC}" | |
| echo -e "${GREEN}✓ Current ClassTrackingPerTxn: ${CLASS_PER_TXN}${NC}" | |
| echo -e "${GREEN}✓ Current ClassTrackingPerTxnLine: ${CLASS_PER_LINE}${NC}" | |
| if [ "$CLASS_PER_TXN" = "true" ] && [ "$CLASS_PER_LINE" = "true" ]; then | |
| echo -e "${YELLOW}Class tracking is already enabled (per-txn and per-line).${NC}" | |
| exit 0 | |
| fi | |
| echo "" | |
| echo -e "${YELLOW}Step 2: Updating Preferences to enable class tracking...${NC}" | |
| # Step 2: POST update Preferences (sparse: only AccountingInfoPrefs we care about) | |
| UPDATE_BODY=$(jq -n \ | |
| --arg syncToken "$SYNC_TOKEN" \ | |
| --arg id "$PREF_ID" \ | |
| '{ | |
| sparse: true, | |
| SyncToken: $syncToken, | |
| AccountingInfoPrefs: { | |
| ClassTrackingPerTxn: true, | |
| ClassTrackingPerTxnLine: true | |
| } | |
| } | if $id != "" then . + {Id: $id} else . end') | |
| UPDATE_RESPONSE=$(curl -s -w "\n%{http_code}" \ | |
| -X POST \ | |
| -H "Authorization: Bearer ${ACCESS_TOKEN}" \ | |
| -H "Content-Type: application/json" \ | |
| -H "Accept: application/json" \ | |
| -d "$UPDATE_BODY" \ | |
| "${PREFERENCES_URL}?operation=update") | |
| UPDATE_HTTP_CODE=$(echo "$UPDATE_RESPONSE" | tail -n1) | |
| UPDATE_BODY_RESPONSE=$(echo "$UPDATE_RESPONSE" | sed '$d') | |
| if [ "$UPDATE_HTTP_CODE" != "200" ]; then | |
| echo -e "${RED}Error: Failed to update preferences (HTTP $UPDATE_HTTP_CODE)${NC}" | |
| echo "$UPDATE_BODY_RESPONSE" | jq '.' 2>/dev/null || echo "$UPDATE_BODY_RESPONSE" | |
| if echo "$UPDATE_BODY_RESPONSE" | grep -q "Stale Object Error\|SyncToken"; then | |
| echo "" | |
| echo -e "${YELLOW}This looks like a SyncToken error. Re-run the script to get a fresh SyncToken.${NC}" | |
| fi | |
| exit 1 | |
| fi | |
| echo -e "${GREEN}✓ Successfully updated preferences.${NC}" | |
| echo "" | |
| echo -e "${YELLOW}Step 3: Verifying class tracking is enabled...${NC}" | |
| # Step 3: Verify | |
| VERIFY_RESPONSE=$(curl -s -w "\n%{http_code}" \ | |
| -X GET \ | |
| -H "Authorization: Bearer ${ACCESS_TOKEN}" \ | |
| -H "Accept: application/json" \ | |
| "$PREFERENCES_URL") | |
| VERIFY_HTTP_CODE=$(echo "$VERIFY_RESPONSE" | tail -n1) | |
| VERIFY_BODY=$(echo "$VERIFY_RESPONSE" | sed '$d') | |
| if [ "$VERIFY_HTTP_CODE" = "200" ]; then | |
| NEW_PER_TXN=$(echo "$VERIFY_BODY" | jq -r '(.Preferences // .preferences).AccountingInfoPrefs.ClassTrackingPerTxn // false') | |
| NEW_PER_LINE=$(echo "$VERIFY_BODY" | jq -r '(.Preferences // .preferences).AccountingInfoPrefs.ClassTrackingPerTxnLine // false') | |
| if [ "$NEW_PER_TXN" = "true" ] && [ "$NEW_PER_LINE" = "true" ]; then | |
| echo -e "${GREEN}✓ Class tracking is now enabled (per-txn and per-line).${NC}" | |
| exit 0 | |
| else | |
| echo -e "${YELLOW}⚠ Class tracking may not be fully on. PerTxn=${NEW_PER_TXN} PerLine=${NEW_PER_LINE}${NC}" | |
| exit 1 | |
| fi | |
| else | |
| echo -e "${YELLOW}⚠ Could not verify (HTTP $VERIFY_HTTP_CODE), but update returned success.${NC}" | |
| exit 0 | |
| fi |
If you prefer to use Postman instead of the bash script, follow these examples. They use the Preferences endpoint (same as the script). The CompanyInfo update endpoint returns "Unsupported Operation" for enabling classes, so we use Preferences.
Create a Postman environment with these variables:
| Variable | Example Value | Description |
|---|---|---|
qbo_base_url |
https://sandbox-quickbooks.api.intuit.com |
Sandbox API base URL |
qbo_realm_id |
1234567890 |
Your QuickBooks Company ID |
qbo_access_token |
eyJlbmMiOiJBMTI4Q0... |
Your OAuth 2.0 access token |
qbo_sync_token |
(auto-populated) | Current SyncToken from GET Preferences |
qbo_pref_id |
(auto-populated) | Preferences Id (optional, set by Request 1) |
This request fetches the current Preferences and extracts the SyncToken (and optional Id). Run this first; the test script saves the values to your environment.
Method: GET
URL: {{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences
Headers:
Authorization: Bearer {{qbo_access_token}}
Accept: application/json
Add this to the "Tests" tab:
const response = pm.response.json();
const prefs = response.Preferences || response.preferences;
if (prefs) {
pm.environment.set("qbo_sync_token", prefs.SyncToken);
if (prefs.Id) pm.environment.set("qbo_pref_id", prefs.Id);
console.log("✓ SyncToken:", prefs.SyncToken);
console.log("✓ Id:", prefs.Id || "(none)");
const accounting = prefs.AccountingInfoPrefs || {};
console.log("\n📊 Current class tracking:");
console.log(" ClassTrackingPerTxn:", accounting.ClassTrackingPerTxn);
console.log(" ClassTrackingPerTxnLine:", accounting.ClassTrackingPerTxnLine);
if (accounting.ClassTrackingPerTxn && accounting.ClassTrackingPerTxnLine) {
console.log("\n✓ Class tracking already enabled");
} else {
console.log("\n→ Run Request 2 to enable class tracking");
}
} else {
console.error("❌ Failed to parse Preferences from response");
}{
"Preferences": {
"Id": "1",
"SyncToken": "3",
"AccountingInfoPrefs": {
"ClassTrackingPerTxn": false,
"ClassTrackingPerTxnLine": false,
"UseAccountNumbers": false
}
}
}(API may return preferences in lowercase; the test script handles both.)
Updates Preferences to turn on class tracking (per transaction and per line). Uses the SyncToken from Request 1.
Method: POST
URL: {{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences?operation=update
Headers:
Authorization: Bearer {{qbo_access_token}}
Content-Type: application/json
Accept: application/json
Body (raw JSON):
If you have qbo_pref_id set, include Id; otherwise omit it (the script uses it only when present):
{
"sparse": true,
"SyncToken": "{{qbo_sync_token}}",
"AccountingInfoPrefs": {
"ClassTrackingPerTxn": true,
"ClassTrackingPerTxnLine": true
}
}Optional: add "Id": "{{qbo_pref_id}}" at the top level if your GET response included an Id.
const response = pm.response.json();
if (pm.response.code === 200) {
const prefs = response.Preferences || response.preferences;
if (prefs) {
pm.environment.set("qbo_sync_token", prefs.SyncToken);
console.log("✓ Class tracking updated. New SyncToken:", prefs.SyncToken);
}
} else {
console.error("❌ Failed:", pm.response.text());
}Account numbers are also under Preferences. Run Request 1 again to get a fresh SyncToken after any previous update, then run this.
Method: POST
URL: {{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences?operation=update
Body (raw JSON):
{
"sparse": true,
"SyncToken": "{{qbo_sync_token}}",
"AccountingInfoPrefs": {
"UseAccountNumbers": true
}
}(Add "Id": "{{qbo_pref_id}}" if you use it in Request 2.)
Method: GET
URL: {{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences
Same as Request 1. Check the response: AccountingInfoPrefs.ClassTrackingPerTxn and ClassTrackingPerTxnLine should be true after enabling classes.
You can import this JSON into Postman. It uses the Preferences endpoint for enabling classes (and optionally account numbers).
{
"info": {
"name": "QuickBooks Online - Enable Settings (Preferences)",
"description": "Fix 'Craig Carlson' error by enabling class tracking via Preferences API",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "1. Get Preferences (fetch SyncToken)",
"event": [
{
"listen": "test",
"script": {
"exec": [
"const response = pm.response.json();",
"const prefs = response.Preferences || response.preferences;",
"if (prefs) {",
" pm.environment.set('qbo_sync_token', prefs.SyncToken);",
" if (prefs.Id) pm.environment.set('qbo_pref_id', prefs.Id);",
" console.log('✓ SyncToken:', prefs.SyncToken);",
"}"
]
}
}
],
"request": {
"method": "GET",
"header": [
{ "key": "Authorization", "value": "Bearer {{qbo_access_token}}" },
{ "key": "Accept", "value": "application/json" }
],
"url": "{{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences"
}
},
{
"name": "2. Enable Classes",
"event": [
{
"listen": "test",
"script": {
"exec": [
"if (pm.response.code === 200) {",
" const r = pm.response.json();",
" const p = r.Preferences || r.preferences;",
" if (p) pm.environment.set('qbo_sync_token', p.SyncToken);",
" console.log('✓ Classes enabled');",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{qbo_access_token}}" },
{ "key": "Content-Type", "value": "application/json" },
{ "key": "Accept", "value": "application/json" }
],
"body": {
"mode": "raw",
"raw": "{\n \"sparse\": true,\n \"SyncToken\": \"{{qbo_sync_token}}\",\n \"AccountingInfoPrefs\": {\n \"ClassTrackingPerTxn\": true,\n \"ClassTrackingPerTxnLine\": true\n }\n}"
},
"url": "{{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences?operation=update"
}
},
{
"name": "3. Enable Account Numbers",
"event": [
{
"listen": "test",
"script": {
"exec": [
"if (pm.response.code === 200) {",
" const r = pm.response.json();",
" const p = r.Preferences || r.preferences;",
" if (p) pm.environment.set('qbo_sync_token', p.SyncToken);",
" console.log('✓ Account numbers enabled');",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{ "key": "Authorization", "value": "Bearer {{qbo_access_token}}" },
{ "key": "Content-Type", "value": "application/json" },
{ "key": "Accept", "value": "application/json" }
],
"body": {
"mode": "raw",
"raw": "{\n \"sparse\": true,\n \"SyncToken\": \"{{qbo_sync_token}}\",\n \"AccountingInfoPrefs\": {\n \"UseAccountNumbers\": true\n }\n}"
},
"url": "{{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences?operation=update"
}
},
{
"name": "4. Verify Settings",
"request": {
"method": "GET",
"header": [
{ "key": "Authorization", "value": "Bearer {{qbo_access_token}}" },
{ "key": "Accept", "value": "application/json" }
],
"url": "{{qbo_base_url}}/v3/company/{{qbo_realm_id}}/preferences"
}
}
]
}(Postman may require the url field to be an object with raw, host, path; if import fails, create the requests manually using the details above.)
- Set up your environment with
qbo_base_url,qbo_realm_id, andqbo_access_token. - Run Request 1 to get the current SyncToken (saved automatically).
- Run Request 2 to enable class tracking.
- To enable account numbers: run Request 1 again (fresh SyncToken), then Request 3.
- Run Request 4 to verify.
Re-run Request 1 to get a fresh SyncToken, then run the update request again.
Use the eye icon (👁️) in the top-right to see current values, including qbo_sync_token.
Open View → Show Postman Console to see output from the test scripts.
This reference lists common company settings and where they live in the QuickBooks API.
Endpoint: GET / POST /v3/company/{realmId}/preferences (POST with ?operation=update)
Used by this gist: The script and Postman examples enable class tracking via Preferences:
AccountingInfoPrefs.ClassTrackingPerTxn— track classes per transactionAccountingInfoPrefs.ClassTrackingPerTxnLine— track classes per line
Other common Preferences settings:
| Setting Name | Location | Description |
|---|---|---|
UseAccountNumbers |
AccountingInfoPrefs.UseAccountNumbers |
Enable account numbers in chart of accounts |
ClassTrackingPerTxn |
AccountingInfoPrefs.ClassTrackingPerTxn |
Track classes per transaction |
ClassTrackingPerTxnLine |
AccountingInfoPrefs.ClassTrackingPerTxnLine |
Track classes per transaction line |
TrackDepartments |
AccountingInfoPrefs.TrackDepartments |
Enable department tracking |
Pattern: GET preferences → read SyncToken → POST to preferences?operation=update with sparse: true, current SyncToken, and the prefs you want to change.
Endpoint: /v3/company/{realmId}/companyinfo/{companyId}?operation=update
Settings location: CompanyInfo.NameValue[] array (e.g. IsClassTrackingOn, TrackDepartments, UseLocations).
Important: In practice, the CompanyInfo update operation returns "Unsupported Operation" (e.g. when enabling classes). So for class tracking and similar settings, use the Preferences endpoint as in this gist. CompanyInfo is still useful for reading company info and name/value settings via the query API.
The provided script uses the Preferences endpoint. It:
- GETs
/v3/company/{realmId}/preferences - Extracts
SyncToken(and optionalId) - POSTs to
preferences?operation=updatewithAccountingInfoPrefs.ClassTrackingPerTxnandClassTrackingPerTxnLineset totrue
To enable another Preferences setting (e.g. account numbers), keep the same flow and change the update body, for example:
{
"sparse": true,
"SyncToken": "{currentSyncToken}",
"AccountingInfoPrefs": {
"UseAccountNumbers": true
}
}Include Id in the body if the GET response included one (the script does this when present).
Some settings are documented under CompanyInfo.NameValue (e.g. IsClassTrackingOn, TrackDepartments, UseLocations). The CompanyInfo update endpoint does not accept these updates in practice ("Unsupported Operation"). You can still read them via:
curl -X GET \
-H "Authorization: Bearer ${TOKEN}" \
"https://sandbox-quickbooks.api.intuit.com/v3/company/${REALM_ID}/query?query=SELECT * FROM CompanyInfo MAXRESULTS 1" \
| jq '.QueryResponse.CompanyInfo[0].CompanyInfo.NameValue'For enabling class tracking, use the Preferences endpoint and AccountingInfoPrefs as in this gist.
curl -s -X GET \
-H "Authorization: Bearer ${TOKEN}" \
"https://sandbox-quickbooks.api.intuit.com/v3/company/${REALM_ID}/preferences" \
| jq '.Preferences.AccountingInfoPrefs'curl -s -X GET \
-H "Authorization: Bearer ${TOKEN}" \
"https://sandbox-quickbooks.api.intuit.com/v3/company/${REALM_ID}/query?query=SELECT%20*%20FROM%20CompanyInfo%20MAXRESULTS%201" \
| jq '.QueryResponse.CompanyInfo[0].CompanyInfo.NameValue'(URL-encode the query parameter if needed.)
| Setting Name | Type | Description |
|---|---|---|
UseAccountNumbers |
boolean | Display account numbers |
ClassTrackingPerTxn |
boolean | Track classes per transaction |
ClassTrackingPerTxnLine |
boolean | Track classes per line |
TrackDepartments |
boolean | Enable department tracking |
| Setting Name | Type | Description |
|---|---|---|
CustomTxnNumbers |
boolean | Use custom transaction numbers |
AllowDeposit |
boolean | Allow deposits on sales forms |
AllowDiscount |
boolean | Allow discounts on sales forms |
| Setting Name | Type | Description |
|---|---|---|
TrackingByCustomer |
boolean | Track expenses by customer |
BillableExpenseTracking |
boolean | Track billable expenses |
These appear in API docs and query responses, but the CompanyInfo update endpoint does not accept updates in practice:
| Setting Name | Type | Description |
|---|---|---|
IsClassTrackingOn |
boolean | Class tracking (use Preferences instead to enable) |
TrackDepartments |
boolean | Department tracking |
UseLocations |
boolean | Location tracking |
MultiCurrencyEnabled |
boolean | Multi-currency |
AutoApplyCredit |
boolean | Automatically apply credits |
AutoApplyPayments |
boolean | Automatically apply payments |
- Always use
sparse: truewhen updating Preferences. - Always include the current
SyncTokenfrom a GET request. - SyncToken increments with each change; re-GET before each update if you do multiple changes.
- Some settings can only be enabled, not disabled (one-way).
- Multi-currency can only be enabled once and cannot be disabled.
- Some settings require specific QuickBooks subscription levels.