Skip to Content
SimulatorsQuickBooks OnlineOverview

Simulators

QuickBooks Online simulator

quickbooks-twin is a local, stateful simulator of the QuickBooks Online Accounting API for testing accounting code. Customers, the list entities, fourteen transactions and the company’s CompanyInfo keep QuickBooks’ envelopes, SyncToken checks and faults, in JSON at minorversion 75. Expect QuickBooks Online’s own field defaults, fault codes and update rules everywhere except where a Differs from QuickBooks line or Limitations names a gap. It never calls Intuit, moves no money and sends no email, so no test record lands in a real company file.

Quickstart

Install the CLI, sign in and boot the simulator with RYSTIC_URL pointing at it.

On Pro you sign in with an API key from your account .

curl -fsSL https://www.rystic.ai/install.sh | sh
rystic login rys_…   # your API key
export RYSTIC_URL=$(rystic run quickbooks-twin -d --port 0 --scenario quickbooks_customer_ledger --json | jq -r .data.url)
curl -s "$RYSTIC_URL/_rystic/version"
# -> {..."product":"quickbooks-twin"...}

On Enterprise, the licensed edition signs in with a license file in place of the key: rystic login ./rystic-license.json (licensing ).

First calls

Every path names the default scenario’s realm, 4620816365320737870. Read a customer, change one field with a sparse update that names its current SyncToken and read it back:

R=4620816365320737870
curl -s "$RYSTIC_URL/v3/company/$R/customer/1" -H 'Authorization: Bearer placeholder' | jq -c '.Customer | {Id, DisplayName, Balance, SyncToken}'
# -> {"Id":"1","DisplayName":"Amy's Bird Sanctuary","Balance":239,"SyncToken":"3"}
curl -s "$RYSTIC_URL/v3/company/$R/customer?minorversion=75" -H 'Authorization: Bearer placeholder' -H 'Content-Type: application/json' -d '{"Id":"1","SyncToken":"3","sparse":true,"Notes":"Prefers morning delivery"}' | jq -c '.Customer | {Id, Notes, SyncToken}'
# -> {"Id":"1","Notes":"Prefers morning delivery","SyncToken":"4"}
curl -s "$RYSTIC_URL/v3/company/$R/customer/1" -H 'Authorization: Bearer placeholder' | jq -c '.Customer | {Id, Notes, SyncToken}'
# -> {"Id":"1","Notes":"Prefers morning delivery","SyncToken":"4"}

Connect your client

Point your client at $RYSTIC_URL in place of https://sandbox-quickbooks.api.intuit.com or https://quickbooks.api.intuit.com; the /v3/company/{realmId}/… paths stay as they are, and any non-empty access token works. Node, with node-quickbooks:

const QuickBooks = require("node-quickbooks");

QuickBooks.V3_ENDPOINT_BASE_URL = `${process.env.RYSTIC_URL}/v3/company/`;
const qbo = new QuickBooks(
  "placeholder", "placeholder", "placeholder", false,
  "4620816365320737870", true, false, 75, "2.0", "placeholder",
);
qbo.getCustomer("1", (err, customer) => {
  if (err) throw new Error(JSON.stringify(err));
  console.log(customer.DisplayName);
});

Python, with python-quickbooks:

import os

from intuitlib.client import AuthClient
from quickbooks import QuickBooks
from quickbooks.objects.customer import Customer

os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
QuickBooks.sandbox_api_url_v3 = os.environ["RYSTIC_URL"] + "/v3"
auth = AuthClient("placeholder", "placeholder", "http://localhost/callback", "sandbox")
auth.access_token = "placeholder"
auth.refresh_token = "placeholder"
client = QuickBooks(auth_client=auth, company_id="4620816365320737870", minorversion=75)
print(Customer.get(1, qb=client).DisplayName)

The simulator serves plain HTTP, which python-quickbooks refuses without OAUTHLIB_INSECURE_TRANSPORT. For another library, set its base URL as Point your client at it describes. Without the intercept gateway, a library that keeps Intuit’s host talks to Intuit.

No client has been checked against this simulator yet.

Auth

Send Authorization: Bearer <token> with any non-empty OAuth 2.0 token.

A request with no bearer token returns 401 with code 3200 and type AuthenticationFault. That covers no Authorization header, an empty token or another scheme such as Basic. The envelope depends on the route, so assert on the status and the code only:

Route401 body
a customer, bill, sales receipt or CompanyInfo reada lowercase fault beside empty response slots, with time in Unix milliseconds, as below
most other routesa capitalized Fault with an RFC 3339 time
{"attachableResponse":[],"batchItemResponse":[],"cdcresponse":[],"fault":{"error":[{"code":"3200","detail":"Token expired or invalid","element":null,"message":"AuthenticationFailed"}],"type":"AuthenticationFault"},"intuitObject":null,"queryResponse":null,"report":null,"requestId":null,"status":null,"syncErrorResponse":null,"time":1768780800001,"warnings":null}

No OAuth route is served: send a placeholder in place of minting a token. Because the simulator checks no token, it cannot exercise your token-refresh path.

Differs from QuickBooks: the simulator never refuses a token as expired, revoked or short of a scope. Its only 403 is a CompanyInfo read of a realm with no seeded company.

API version

The simulator serves every request as minorversion 75, reads no minorversion parameter and sends no version header. A request that names another value, or none, gets the same shapes. Pass minorversion=75 in your client anyway, as both libraries above do, so your code asks for what the simulator serves.

Errors and limits

Error format

Most refusals return a 400 whose body is a Fault holding type and an Error array, beside a time. Each error has code, Message, Detail and element, the field it names or empty. Assert on the status, type and code rather than the Detail text. A behavior marked (unconfirmed) has not been checked against QuickBooks. How a read refuses an Id:

ReadResponse
a numeric Id that matches no record, on any read but TaxCode, TaxRate and CompanyInfo400 ValidationFault code 610, Message Object Not Found
a TaxCode or TaxRate Id that matches no record404 with an empty body (unconfirmed)
a non-numeric Id on PaymentMethod or PurchaseOrder400 ValidationFault code 610
a non-numeric Id on any other read404 with an empty body (unconfirmed)

A write body that does not parse as JSON returns 400 ValidationFault code 6240, before the token is checked. Its body is the duplicate-name fault, Message Duplicate Name Exists Error, with a fixed time; whether QuickBooks returns the same fault is unconfirmed.

An unserved route returns the simulator’s own 404, and a 401 has its own envelope (Auth).

Rate limits

Network profiles send a 429 you shape, with the body and headers you choose; the simulator counts no requests and never returns 429 on its own (Limitations).

Pagination

Not applicable: listing and search go through QuickBooks’ query endpoint, which Limitations lists as not served, so read each record by its Id.

Idempotency

A ?requestid=<id> replays a write only on the entities in the table’s first row. On every other entity a retry writes again (Limitations):

Write, create or updateA retry with the same requestid
Item, Invoice, Estimate, CreditMemo, Deposit, VendorCredit, Termreturns the stored response
Customer, SalesReceiptruns again, but stores its response for the entities above to replay
Vendor, Class and every other entityruns again

On the first row’s entities, a requestid another entity stored replays that entity’s response (Limitations). A requestid longer than 50 characters returns 400 ValidationFault code 6000 on Customer, Vendor, Item, Class and Term writes.

A stale SyncToken on an update or an invoice void returns 400 ValidationFault code 5010, so sending one update twice fails the second time unless an entity in the table’s first row replays it.

A delete (?operation=delete) of a Bill, BillPayment, CreditMemo, Deposit, Invoice, JournalEntry, Payment, Purchase, PurchaseOrder, RefundReceipt or Transfer succeeds with a stale SyncToken, as QuickBooks does. An Estimate, SalesReceipt or VendorCredit delete with a stale SyncToken returns 400 ValidationFault code 5010 (unconfirmed).

Coverage

The simulator serves customers, the list entities, the TaxCode and TaxRate reads, fourteen transactions, CompanyInfo and the report reads under /v3/company/{realmId}/, in JSON. The query endpoint, batch, change data capture, webhooks, XML and the transactions’ PDF reads and email sends are out of scope.

On 2026-11-07, the simulator matched QuickBooks Online on 491 of the 538 tests that compare the two (91.3%), and 2 of them gave no verdict.

96 routes, counted from the simulator’s route table.

Show all operations
ResourceOperations
Account (7)POST /v3/company/{realmId}/account; GET /v3/company/{realmId}/account/{accountId}; GET /v3/company/{realmId}/reports/AccountList; GET /v3/company/{realmId}/reports/BalanceSheet; GET /v3/company/{realmId}/reports/CashFlow; GET /v3/company/{realmId}/reports/GeneralLedger; GET /v3/company/{realmId}/reports/TrialBalance
Bill (6)POST /v3/company/{realmId}/bill; POST /v3/company/{realmId}/bill?operation=delete; GET /v3/company/{realmId}/bill/{billId}; GET /v3/company/{realmId}/reports/AgedPayableDetail; GET /v3/company/{realmId}/reports/AgedPayables; GET /v3/company/{realmId}/reports/TransactionListByVendor
BillPayment (4)POST /v3/company/{realmId}/billpayment; POST /v3/company/{realmId}/billpayment?include=void&operation=update; POST /v3/company/{realmId}/billpayment?operation=delete; GET /v3/company/{realmId}/billpayment/{billpaymentId}
Class (3)POST /v3/company/{realmId}/class; GET /v3/company/{realmId}/class/{classId}; GET /v3/company/{realmId}/reports/ClassSales
Company info (8)GET /v3/company/{realmId}/companyinfo/{companyId}; GET /v3/company/{realmId}/reports/CustomerIncome; GET /v3/company/{realmId}/reports/DepartmentSales; GET /v3/company/{realmId}/reports/JournalReport; GET /v3/company/{realmId}/reports/ProfitAndLoss; GET /v3/company/{realmId}/reports/TransactionList; GET /v3/company/{realmId}/reports/TransactionListByCustomer; GET /v3/company/{realmId}/reports/TransactionListWithSplits
CreditMemo (3)POST /v3/company/{realmId}/creditmemo; POST /v3/company/{realmId}/creditmemo?operation=delete; GET /v3/company/{realmId}/creditmemo/{creditmemoId}
Customer (7)POST /v3/company/{realmId}/customer; GET /v3/company/{realmId}/customer/{customerId}; GET /v3/company/{realmId}/reports/AgedReceivableDetail; GET /v3/company/{realmId}/reports/AgedReceivables; GET /v3/company/{realmId}/reports/CustomerBalance; GET /v3/company/{realmId}/reports/CustomerBalanceDetail; GET /v3/company/{realmId}/reports/CustomerSales
Department (2)POST /v3/company/{realmId}/department; GET /v3/company/{realmId}/department/{departmentId}
Deposit (3)POST /v3/company/{realmId}/deposit; POST /v3/company/{realmId}/deposit?operation=delete; GET /v3/company/{realmId}/deposit/{depositId}
Employee (2)POST /v3/company/{realmId}/employee; GET /v3/company/{realmId}/employee/{employeeId}
Estimate (3)POST /v3/company/{realmId}/estimate; POST /v3/company/{realmId}/estimate?operation=delete; GET /v3/company/{realmId}/estimate/{estimateId}
Invoice (5)POST /v3/company/{realmId}/invoice; POST /v3/company/{realmId}/invoice?operation=delete; POST /v3/company/{realmId}/invoice?operation=void; GET /v3/company/{realmId}/invoice/{invoiceId}; GET /v3/company/{realmId}/reports/ProfitAndLossDetail
Item (5)POST /v3/company/{realmId}/item; GET /v3/company/{realmId}/item/{itemId}; GET /v3/company/{realmId}/reports/InventoryValuationDetail; GET /v3/company/{realmId}/reports/InventoryValuationSummary; GET /v3/company/{realmId}/reports/ItemSales
JournalEntry (3)POST /v3/company/{realmId}/journalentry; POST /v3/company/{realmId}/journalentry?operation=delete; GET /v3/company/{realmId}/journalentry/{journalentryId}
Payment (4)POST /v3/company/{realmId}/payment; POST /v3/company/{realmId}/payment?include=void&operation=update; POST /v3/company/{realmId}/payment?operation=delete; GET /v3/company/{realmId}/payment/{paymentId}
Payment method (2)POST /v3/company/{realmId}/paymentmethod; GET /v3/company/{realmId}/paymentmethod/{paymentmethodId}
Purchase (3)POST /v3/company/{realmId}/purchase; POST /v3/company/{realmId}/purchase?operation=delete; GET /v3/company/{realmId}/purchase/{purchaseId}
PurchaseOrder (3)POST /v3/company/{realmId}/purchaseorder; POST /v3/company/{realmId}/purchaseorder?operation=delete; GET /v3/company/{realmId}/purchaseorder/{purchaseorderId}
RefundReceipt (3)POST /v3/company/{realmId}/refundreceipt; POST /v3/company/{realmId}/refundreceipt?operation=delete; GET /v3/company/{realmId}/refundreceipt/{refundreceiptId}
SalesReceipt (4)POST /v3/company/{realmId}/salesreceipt; POST /v3/company/{realmId}/salesreceipt?include=void&operation=update; POST /v3/company/{realmId}/salesreceipt?operation=delete; GET /v3/company/{realmId}/salesreceipt/{salesreceiptId}
TaxAgency (1)GET /v3/company/{realmId}/reports/TaxSummary
TaxCode (1)GET /v3/company/{realmId}/taxcode/{taxcodeId}
TaxRate (1)GET /v3/company/{realmId}/taxrate/{taxrateId}
Term (2)POST /v3/company/{realmId}/term; GET /v3/company/{realmId}/term/{termId}
Transfer (3)POST /v3/company/{realmId}/transfer; POST /v3/company/{realmId}/transfer?operation=delete; GET /v3/company/{realmId}/transfer/{transferId}
Vendor (5)GET /v3/company/{realmId}/reports/VendorBalance; GET /v3/company/{realmId}/reports/VendorBalanceDetail; GET /v3/company/{realmId}/reports/VendorExpenses; POST /v3/company/{realmId}/vendor; GET /v3/company/{realmId}/vendor/{vendorId}
VendorCredit (3)POST /v3/company/{realmId}/vendorcredit; POST /v3/company/{realmId}/vendorcredit?operation=delete; GET /v3/company/{realmId}/vendorcredit/{vendorcreditId}

Feed effects. No write emits a feed effect; watch requests instead. Each call appears on the event feed (/_rystic/events) as a request event, and reading the record back shows what it changed.

Scenarios

The simulator ships 5 scenarios; the quickstart boots quickbooks_customer_ledger.

ScenarioWhat it is forWhat it seedsClock
quickbooks_customer_ledger (default)Blue Heron Bakery’s eight customerscompany_info 1, customer 8, request_dedup 2, taxagency 1, taxcode 1, taxrate 12026-01-19T00:00:00Z
quickbooks_fresh_booksA company file opened a week before the clockcompany_info 1, customer 1, request_dedup 1, taxagency 1, taxcode 1, taxrate 12026-01-19T00:00:00Z
quickbooks_inactive_archiveA company of mostly inactive customerscompany_info 1, customer 5, request_dedup 2, taxagency 1, taxcode 1, taxrate 12026-01-19T00:00:00Z
quickbooks_job_hierarchyA contractor’s customer treecompany_info 1, customer 5, request_dedup 1, taxagency 1, taxcode 1, taxrate 12026-01-19T00:00:00Z
quickbooks_replay_deskFour stored customer requestscompany_info 1, customer 3, request_dedup 4, taxagency 1, taxcode 1, taxrate 12026-01-19T00:00:00Z

What each scenario holds:

  • quickbooks_customer_ledger: Two paid up, five with open balances and one whose BalanceWithJobs is above its own Balance, so customer and CompanyInfo reads return records before any write.
  • quickbooks_fresh_books: Settings configured, one customer with a zero balance and one stored requestid.
  • quickbooks_inactive_archive: Four of five deactivated, one of them with an open balance.
  • quickbooks_job_hierarchy: A parent with two jobs, one a Project and one with a job of its own two levels deep, plus a flat customer, so ParentRef, Level and BillWithParent reads have targets.
  • quickbooks_replay_desk: A create, an update, a deactivation and a validation fault, against three customers. A customer write stores its requestid but never replays it.

Boot one by name, or load one into a running simulator:

rystic run quickbooks-twin -d --port 0 --scenario quickbooks_customer_ledger
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"quickbooks_customer_ledger"}'

What the scenarios do not hold

  • No list entity or transaction: each scenario seeds one company and its customers, so create an account, an item or a vendor with the API before a transaction references it (Transactions and list entities).
  • One tax code, one tax rate and one tax agency only. Every scenario’s customers name tax code 2 in DefaultTaxCodeRef, that code lists rate 1, and the rate names agency 1, the only agency_id TaxSummary accepts. Seed more in state_taxcode, state_taxrate and state_taxagency (Seeding state).
  • Without --scenario, the simulator boots with no records, and the CompanyInfo read returns 403 AuthorizationFault.

Seeding state

Each entity is one register named state_<entity>, such as state_customer, state_vendor or state_invoice. A register keys its records by Id, except state_company_info, which is keyed by realm id. state_request_dedup keys each stored response by its requestid, as {"requestid": "…", "response": {…}}, and a replay returns response as its body. Seed a company under its realm id, with realmId in the record too, and a customer, then read them back:

curl -s -X POST "$RYSTIC_URL/_rystic/seed" -d '{"state_company_info":{"9341452000000001":{"realmId":"9341452000000001","Id":"1","CompanyName":"Example Co"}},"state_customer":{"100":{"Id":"100","DisplayName":"Seeded Customer","SyncToken":"0","Active":true}}}'
curl -s "$RYSTIC_URL/v3/company/9341452000000001/companyinfo/9341452000000001" -H 'Authorization: Bearer placeholder' | jq -c '.CompanyInfo | {Id, CompanyName, LegalName, NameValue}'
# -> {"Id":"1","CompanyName":"Example Co","LegalName":"Company 9341452000000001","NameValue":[]}
curl -s "$RYSTIC_URL/v3/company/9341452000000002/companyinfo/9341452000000002" -H 'Authorization: Bearer placeholder' | jq -c '.Fault | {type, code: .Error[0].code}'
# -> {"type":"AuthorizationFault","code":"3100"}
curl -s "$RYSTIC_URL/v3/company/9341452000000001/customer/100" -H 'Authorization: Bearer placeholder' | jq -c '.Customer | {Id, DisplayName, SyncToken}'
# -> {"Id":"100","DisplayName":"Seeded Customer","SyncToken":"0"}
When you read GET …/companyinfo/{companyId} andIt returns
a company is seeded under the path’s realmthat company
none is403 AuthorizationFault, as for a realm the token is not issued for
either path id is not numeric404 with an empty body

{companyId} selects nothing. A field the seeded company leaves out is filled in: CompanyName and LegalName become Company <realmId>, and NameValue is empty. Registers lists each register’s fields, and Scenarios and seeding covers the seed response, refusals, boot files and the seed gate.

Features

Each feature has its own page:

  • Customers: The customer lifecycle QuickBooks applies: create, read, sparse and full update, deactivate and reactivate, with SyncToken checks, name rules and stored sub-customers.
  • Transactions and list entities: Vendors, items, accounts and the other list entities, and fourteen transactions from Invoice to Transfer, with delete, void and the amounts each keeps.

Determinism and reset

Each entity numbers its records from 1, except Class, which starts at 5000000000000007280. The V4IDPseudonym sequence starts at 000000000000000000000001. The clock moves one millisecond for each request that renders a time, reads included.

The simulator renders the times it writes at a fixed offset:

EntityOffset
Bill, Payment, Deposit, VendorCredit, CreditMemo and Transfer-08:00
a voided SalesReceipt’s LastUpdatedTime and time-08:00
most other entities-07:00

It writes MetaData.CreateTime and MetaData.LastUpdatedTime to the second. A customer response’s time is to the second too, and a CompanyInfo response’s time to the millisecond. A 401’s time format depends on the route; see Auth.

Reset and determinism covers reset, the clock and the RNG.

Limitations

Known issues.

  • A requestid is shared across entities: a write replays whatever another entity stored under the same id, where QuickBooks scopes it to the request.
  • No request rate is enforced, where QuickBooks throttles each realm’s requests with 429.
  • A retried requestid writes again on every entity but Item, Invoice, Estimate, CreditMemo, Deposit, VendorCredit and Term, where QuickBooks returns the stored response.

Beyond the known issues, 57 of the 153 operations in the published spec are not served, 3 success responses may leave out fields the spec requires, 470 documented responses have no test yet and 325 behaviors are not modeled. The details follow.

Show all limitations

Not served. 57 of the 153 operations in the published spec are not served.

  • CompanyInfo, 1 of 2 served: POST /v3/company/{realmId}/companyinfo
  • CreditMemo, 3 of 5 served: GET /v3/company/{realmId}/creditmemo/{creditmemoId}/pdf, POST /v3/company/{realmId}/creditmemo/{creditmemoId}/send
  • Estimate, 3 of 5 served: GET /v3/company/{realmId}/estimate/{estimateId}/pdf, POST /v3/company/{realmId}/estimate/{estimateId}/send
  • Invoice, 4 of 6 served: GET /v3/company/{realmId}/invoice/{invoiceId}/pdf, POST /v3/company/{realmId}/invoice/{invoiceId}/send
  • Payment, 4 of 6 served: GET /v3/company/{realmId}/payment/{paymentId}/pdf, POST /v3/company/{realmId}/payment/{paymentId}/send
  • PurchaseOrder, 3 of 5 served: GET /v3/company/{realmId}/purchaseorder/{purchaseorderId}/pdf, POST /v3/company/{realmId}/purchaseorder/{purchaseorderId}/send
  • RefundReceipt, 3 of 5 served: GET /v3/company/{realmId}/refundreceipt/{refundreceiptId}/pdf, POST /v3/company/{realmId}/refundreceipt/{refundreceiptId}/send
  • SalesReceipt, 4 of 6 served: GET /v3/company/{realmId}/salesreceipt/{salesreceiptId}/pdf, POST /v3/company/{realmId}/salesreceipt/{salesreceiptId}/send
  • Not served at all: Attachable (5), Budget (3), CDCResponse (1), ChangeOrder (3), CompanyCurrency (2), CreditCardPaymentTxn (3), CustomerType (1), ExchangeRate (2), IntuitBatchRequest (1), InventoryAdjustment (3), Preferences (2), QueryResponse (2), RecurringTransaction (3), ReimburseCharge (1), TaxAgency (2), TaxClassification (3), TaxPayment (1), TaxService (1), TimeActivity (3)

Missing response fields. The spec requires these fields in a success response, and the simulator may leave them out:

  • GET /v3/company/{realmId}/transfer/{transferId} (200): Transfer/TransferEx
  • POST /v3/company/{realmId}/transfer (200): Transfer/TransferEx
  • POST /v3/company/{realmId}/transfer?operation=delete (200): Transfer/TransferEx

Not tested. 549 tests compare the simulator with the real service. 470 documented responses have no test yet, and 141 of them need a credential our test account doesn’t hold (401 ×45, 403 ×96). The other 329:

OperationStatusWhy
GET /v3/company/{realmId}/account/{accountId}400a well-formed request does not provoke it
GET /v3/company/{realmId}/account/{accountId}429no request a client sends provokes it
GET /v3/company/{realmId}/account/{accountId}500no request a client sends provokes it
GET /v3/company/{realmId}/account/{accountId}503no request a client sends provokes it
GET /v3/company/{realmId}/bill/{billId}400a well-formed request does not provoke it
GET /v3/company/{realmId}/bill/{billId}429no request a client sends provokes it
GET /v3/company/{realmId}/bill/{billId}500no request a client sends provokes it
GET /v3/company/{realmId}/bill/{billId}503no request a client sends provokes it
GET /v3/company/{realmId}/billpayment/{billpaymentId}400a well-formed request does not provoke it
GET /v3/company/{realmId}/billpayment/{billpaymentId}429no request a client sends provokes it
GET /v3/company/{realmId}/billpayment/{billpaymentId}500no request a client sends provokes it
GET /v3/company/{realmId}/billpayment/{billpaymentId}503no request a client sends provokes it
GET /v3/company/{realmId}/class/{classId}400a well-formed request does not provoke it
GET /v3/company/{realmId}/class/{classId}429no request a client sends provokes it
GET /v3/company/{realmId}/class/{classId}500no request a client sends provokes it
GET /v3/company/{realmId}/class/{classId}503no request a client sends provokes it
GET /v3/company/{realmId}/companyinfo/{companyId}429no request a client sends provokes it
GET /v3/company/{realmId}/companyinfo/{companyId}500no request a client sends provokes it
GET /v3/company/{realmId}/companyinfo/{companyId}503no request a client sends provokes it
GET /v3/company/{realmId}/creditmemo/{creditmemoId}400a well-formed request does not provoke it
… and 301 more

Not modeled. Behavior the simulator does not model, by operation:

  • The 404 and 429 bodies are undocumented by Intuit, so only their statuses are modeled. (GET /v3/company/{realmId}/billpayment/{billpaymentId})
  • The 404, 429, 500 and 503 bodies are undocumented, so only their statuses are claimed. (GET /v3/company/{realmId}/employee/{employeeId})
  • The request shape that provokes the documented 404: the operation names no resource by a path or query identifier whose absence is documented to produce it. (GET /v3/company/{realmId}/reports/AgedReceivableDetail)
  • Whether start_duedate greater than end_duedate is a 400 or an empty report. (GET /v3/company/{realmId}/reports/AgedReceivableDetail)
  • Whether a customer or term ID in the filter that names no record is refused (610) or simply matches nothing. (GET /v3/company/{realmId}/reports/AgedReceivableDetail)
  • Whether an unknown column name in columns is refused or silently dropped. (GET /v3/company/{realmId}/reports/AgedReceivableDetail)
  • Whether qzurl=true adds a href to each ColData of this report, and the shape of that URL, is undocumented beyond the ColData schema. (GET /v3/company/{realmId}/reports/AgedReceivables)
  • 500 InternalServerError (SystemFault code 10000) and 503 ServiceUnavailable: server-side faults with no caller-side trigger documented. (GET /v3/company/{realmId}/reports/ClassSales)
  • The report’s exact row and column layout under each summarize_column_by grouping, and the arpaid/date_macro effect on which transactions are counted: only the default Total grouping sample is documented. (GET /v3/company/{realmId}/reports/CustomerBalance)
  • The report’s own content rules are undocumented here: which transactions a customer section lists, how arpaid Paid/All change the rows, how aging_method Current shifts the aging, and which column types a given columns value adds. (GET /v3/company/{realmId}/reports/CustomerBalanceDetail)
  • Whether a customer, term or department ID naming no record is refused (610 Object Not Found) or silently filters to an empty report is undocumented. (GET /v3/company/{realmId}/reports/CustomerBalanceDetail)
  • The exact row and column grammar under summarize_column_by values other than the default Total; only the default-grouped sample is documented. (GET /v3/company/{realmId}/reports/CustomerIncome)
  • The exact column set and row grouping each summarize_column_by value produces; only the Total form is exemplified. (GET /v3/company/{realmId}/reports/CustomerSales)
  • What provokes the documented 404 on this route: it takes no resource path parameter beyond realmId, which the run supplies, so no in-scope request shape names a resource that can be made absent. (GET /v3/company/{realmId}/reports/CustomerSales)
  • Whether qzurl=true adds ColData.href on every data row or only on some column types. (GET /v3/company/{realmId}/reports/CustomerSales)
  • The documented hierarchy defect (‘the response for the General Ledger report hierarchy is broken in certain circumstances when there are sub accounts configured’): the conditions and the resulting shape are not stated, so the Rows tree is modeled only as the documented nesting. (GET /v3/company/{realmId}/reports/GeneralLedger)
  • No body is documented for 404, 429, 500 or 503 on this route. (GET /v3/company/{realmId}/reports/InventoryValuationSummary)
  • Whether the Header carries Item and SummarizeColumnsBy when those parameters are supplied is undocumented here; the sample shows neither. (GET /v3/company/{realmId}/reports/InventoryValuationSummary)
  • The Header’s NoReportData option semantics beyond the sample value ‘false’. (GET /v3/company/{realmId}/reports/ItemSales)
  • The exact ordering ascend/descend imposes on the Rows array. (GET /v3/company/{realmId}/reports/ItemSales)
  • … and 305 more

By design.

  • No realm isolation. A read selects by Id without checking the realm in its path. Creating a record under a realm id that is not all digits returns 404 with an empty body, and so do the customer, CompanyInfo, Bill, PaymentMethod, PurchaseOrder and SalesReceipt reads. Every other read serves any realm id. Voiding a BillPayment returns that 404 under a realm id of fewer than 10 digits or of one repeated digit.

    Differs from QuickBooks: QuickBooks scopes every record to its realm.

  • Bodies are read as JSON whatever their Content-Type. An XML body returns the unparsable-body refusal (Error format).

Release notes: Changelog

Last updated on