Money, dates and data conventions
QuickBooks Desktop has its own types and quirks: two-decimal amounts, five-decimal prices, local-time timestamps, a Windows code page for text. The API keeps those rules visible instead of hiding them, so values round-trip without surprises.
Field names and shapes
Section titled “Field names and shapes”- JSON only (
application/json; charset=utf-8), except passthrough, which also accepts XML. - Field names are
camelCase. Enum values are lowercasesnake_case, such as"accounts_receivable". Errortypeandcodevalues areUPPER_SNAKE_CASE. - Every object has
objectType, such as"qbd_invoice","end_user"or"list". - Responses always contain every documented field. Missing values are
null; empty collections are[]. Fields that can repeat are always arrays, even with one item. Apart from a QuickBooks object’sid,objectType,createdAt,updatedAtandrevisionNumber, any response field can benull; see Damaged and unusual data. - Request bodies are strict. An unknown field returns
400 UNKNOWN_PARAMETERwithparamnaming it, so a misspelledmemmonever gets dropped silently. - Array query parameters repeat the key:
?customerIds=80000001-1&customerIds=80000002-1. Comma-joined values are rejected. - Enums are open: new values can appear in responses. Handle unknown values gracefully.
Numbers
Section titled “Numbers”| QuickBooks type | JSON | Example | Rules |
|---|---|---|---|
| Amount (totals, balances, line amounts) | decimal string | "1234.50" |
Up to 13 digits before the point and 2 after. Input may have 0 to 2 decimals and comes back with exactly 2. |
| Price (rates, unit prices) | decimal string | "12.34567" |
Up to 10 digits before the point and 5 after. Output keeps QuickBooks’ digits. |
| Quantity | number | 2.5 |
Up to 10 digits before the point and 5 after. |
| Percentage | decimal string | "7.5" |
"7.5" means 7.5 percent. Up to 10 digits before the point and 5 after. |
| Exchange rate | number | 1.3521 |
|
| Integer, boolean | integer, boolean | 3, true |
Three values are JSON numbers although QuickBooks stores them as decimals, matching Conductor: valueDifference on inventory adjustments (still limited to 2 decimal places), and minimumFinanceCharge and annualInterestRate in company preferences.
Money is a string so that 0.1 + 0.2 problems never touch an invoice. Parse it with a decimal type: decimal.Decimal in Python, decimal in C#, BigDecimal in Java, a decimal library in JavaScript. The Python, C# and Java SDKs already return those types.
More decimal places than QuickBooks stores returns 400 DECIMAL_PRECISION_EXCEEDED with param set. We never round for you, because a silently rounded amount is an accounting error that nobody notices.
Output always uses . as the decimal separator and no thousands separators, whatever the Windows language settings on the customer’s computer. QuickBooks on a computer set to, say, Portuguese or German can write 672,00, 1.234,56 or 1 234,56; you receive "672.00" and "1234.56".
Amounts are in the transaction’s currency. With multicurrency on, objects also carry exchangeRate and home-currency amounts such as balanceRemainingInHomeCurrency. See Editions, versions and features.
Dates and times
Section titled “Dates and times”| Kind | Format | Example |
|---|---|---|
Accounting dates (transactionDate, dueDate, shippingDate) |
YYYY-MM-DD, no time zone |
"2026-10-05" |
QuickBooks timestamps (createdAt, updatedAt on QuickBooks objects) |
ISO 8601 with the customer computer’s UTC offset | "2026-10-05T09:14:03-07:00" |
Our timestamps (requests, end users, events, cursorExpiresAt) |
ISO 8601 UTC with milliseconds | "2026-10-05T16:14:03.120Z" |
Accounting dates are calendar dates. An invoice dated 2026-10-05 is dated October 5 everywhere; do not convert it to a time zone.
QuickBooks timestamps keep the offset QuickBooks reports. We do not convert them to UTC, because QuickBooks’ own filters work on that local clock.
Date filters such as updatedAfter, updatedBefore, transactionDateFrom and deletedAfter accept:
- a date:
2026-10-05. Lower bounds mean the start of that day, upper bounds the end; - a local date-time without an offset:
2026-10-05T09:00:00, read in the customer computer’s time zone; - a date-time with an offset:
2026-10-05T16:00:00Z, converted to the computer’s time zone.
Many list and report endpoints also accept date macros such as this_month, last_quarter or this_year_to_date, which QuickBooks evaluates on the customer’s computer.
- US editions of QuickBooks Desktop store text in the Windows-1252 code page, not Unicode. That covers Latin letters with accents (
é,ñ,ü,Å),€,£,©,µ, the no-break space (U+00A0), curly quotes and dashes. They are stored exactly as you write them. - Any other character returns
400 UNSUPPORTED_CHARACTERbefore anything is sent: emoji, Greek, Cyrillic and Asian scripts, control characters, line and paragraph separators (U+2028, U+2029), and fullwidth forms such as&and<. The error names the field inparam, anddetailsgives the code point, the character, its position and, where there is an obvious one, asuggestion(&for&, a plain space for a narrow no-break space,µfor the Greekμ). - We do not fold, strip or replace characters for you, because a silently changed name causes duplicate-name and matching bugs later. One exception changes no text: a letter written as a base letter plus a combining accent (common in text from macOS) is sent in its composed form, so
e+◌́becomesé. - Text you read back is returned as QuickBooks stores it. Characters QuickBooks wrote as Windows-1252 byte references, such as
’for’, come back as the characters they stand for. - Each text field has a maximum length from the QuickBooks schema, shown in the API reference. Longer values return
400 STRING_TOO_LONGbefore anything is sent. - Send plain text. We escape XML special characters such as
&and<for you. - QuickBooks stores a line break as a single line feed (
\n). The API passes a carriage return through to QuickBooks unchanged, and QuickBooks converts\r\nto\nwhen it saves the text. So"line 1\r\nline 2"is stored and returned by later reads as"line 1\nline 2". Text sent with\nalone is stored exactly. If you compare text you sent with text you read back, normalize\r\nto\nfirst.
- Name searches (
names,fullNames,nameContains) are case-insensitive, as in QuickBooks.
Damaged and unusual data
Section titled “Damaged and unusual data”Company files damaged by crashes, imports or old QuickBooks versions sometimes return records with elements missing or values in the wrong format. The API reads such responses without failing them and without dropping records:
- A missing value is
null, even where the QuickBooks schema says the element is always present (an invoice without a customer, a line without anid, a transaction withoutsubtotal). - A value that cannot be read, such as an amount
12,3x, a date0000-00-00or a booleanmaybe, isnull. An enum value with no letters or digits (QuickBooks has returned???) is"unknown". - Malformed XML text, such as a bare
&in a memo, is kept as written.
Each of these is reported. The Daapi-Warnings response header counts them, and GET /v1/requests/{id} lists each one in warnings with code (QBD_VALUE_UNREADABLE or QBD_MARKUP_REPAIRED), the path of the affected value (data[2].subtotal) and a message that quotes what QuickBooks sent. If you see them often for one customer, ask them to run Verify Data and Rebuild Data in QuickBooks.
Only a missing or unreadable id, createdAt, updatedAt or revisionNumber on a QuickBooks object fails the response, with QBD_RESPONSE_UNREADABLE, because a record that cannot be identified cannot be updated safely.
- QuickBooks IDs (
idon lists and transactions, lineids) pass through unchanged. They look like80000012-1730312001and are at most 36 characters. Store them as strings. - IDs are unique within one company file, not across files. Store them together with the end user ID.
- Our own IDs carry a type prefix:
eu_end users,conn_connections,req_requests,authsess_auth sessions,evt_webhook events,proj_projects,org_organizations. They are sortable by creation time.
References
Section titled “References”Inputs reference other records by ID, in fields named <thing>Id: customerId, itemId, classId, accountId. Outputs return a reference object:
"customer": { "id": "80000012-1730312001", "fullName": "Acme Supply:Warehouse job" }fullName is the record’s full hierarchical name at the time of the response, with levels separated by colons. Inputs do not accept names, because names change and can be ambiguous across hierarchy levels. Look up an ID by name with a list filter such as fullNames, then use the ID.
A reference to an ID that does not exist, or that points to the wrong kind of record, returns 422 QBD_REFERENCE_NOT_FOUND with param naming the field.
Validation errors
Section titled “Validation errors”| Code | When |
|---|---|
INVALID_PARAMETER |
A value breaks the schema: wrong type, out of range, bad format |
UNKNOWN_PARAMETER |
A field the operation does not accept |
DECIMAL_PRECISION_EXCEEDED |
Too many decimal places |
STRING_TOO_LONG |
Text longer than QuickBooks allows |
UNSUPPORTED_CHARACTER |
A character QuickBooks cannot store |
FIELD_NOT_CLEARABLE |
null on a field QuickBooks cannot clear |
All of them come back before the request is queued, with outcome: "not_applied". Nothing reaches QuickBooks.