Create and pay QuickBooks test documents
Staging verified: This workflow passed on November 3, 2026 with a Console-created synthetic company and ordinary runtime credentials. Production qualification is pending. Supported operations are described below.
Use a synthetic company with QuickBooks selected and a Developer or higher plan with native API access. Generation credits and native API access are separate; adding generation credits does not enable native routes. See Connect your software for current access requirements.
Create the company in the Console, then create a Read and modify company key in Settings → Company → Company API keys. Keep it on your server. You can also use a staging organization key with the same access for the organization that owns the company. Use the matching origin and slug from that company's Connect panel:
export FICTIX_API_ORIGIN="https://api-staging.fictix.ai"
export FICTIX_PROJECT_SLUG="<your staging company slug>"
export FICTIX_PROJECT_API_KEY="<your company key>"
QBO_BASE="$FICTIX_API_ORIGIN/api/v1/orgs/$FICTIX_PROJECT_SLUG/native/qbo/v3/company/test"
These requests change only the synthetic company's records. They do not send money through a real QuickBooks or bank connection.
Read the IDs your application will use
Query customers, vendors, items and ledger accounts. Replace Account in this
request with Customer, Vendor or Item for the other lists:
curl --fail-with-body -sS --get "$QBO_BASE/query" \
-H "X-API-Key: $FICTIX_PROJECT_API_KEY" \
--data-urlencode 'query=SELECT * FROM Account STARTPOSITION 1 MAXRESULTS 1000'
Read the records inside QueryResponse.Account, QueryResponse.Customer,
QueryResponse.Vendor and QueryResponse.Item. Use their returned Id values
in native references. In particular, AccountRef.value refers to a native
Account.Id; do not substitute a different ID from an export or canonical
data response.
Choose an active service item with an income-account mapping, an expense account, and the bank-linked cash account for this company. Invoice creation resolves the item's income account. Payment posting requires exactly one active bank account linked to the selected cash ledger account, using the document's currency. An ambiguous or missing mapping returns a validation error before posting.
The query reference
describes supported filters and paging. Queries and single-record GETs also
support Invoice, Bill, Payment, BillPayment and JournalEntry.
Create an invoice
Save this as invoice.json, replacing the customer and item IDs with values
you just read. Use your transaction date in YYYY-MM-DD format.
{
"CustomerRef": {"value": "<customer Id>"},
"TxnDate": "2026-11-03",
"Line": [{
"Amount": 0.01,
"DetailType": "SalesItemLineDetail",
"SalesItemLineDetail": {
"ItemRef": {"value": "<service item Id>"},
"Qty": 1,
"UnitPrice": 0.01
}
}]
}
curl --fail-with-body -sS "$QBO_BASE/invoice" \
-H "X-API-Key: $FICTIX_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: qbo-invoice-demo-1" \
--data-binary @invoice.json
A successful response contains Invoice.Id, TotalAmt: 0.01 and
Balance: 0.01. Creation posts the receivable and revenue. It does not record
a cash receipt. Save Invoice.Id for the payment.
Use a distinct idempotency key for each operation. Persist the key and exact
payload before sending. If the response is lost, retry with that same key and
body; changing the payload under the same key returns 409. Use a new key
for a genuinely new invoice.
Apply the customer's payment
Save this as payment.json. Use the same customer, the cash account's native
ID, and the returned invoice ID:
{
"CustomerRef": {"value": "<customer Id>"},
"TxnDate": "2026-11-03",
"TotalAmt": 0.01,
"DepositToAccountRef": {"value": "<cash Account Id>"},
"Line": [{
"Amount": 0.01,
"LinkedTxn": [{"TxnId": "<Invoice.Id>", "TxnType": "Invoice"}]
}]
}
curl --fail-with-body -sS "$QBO_BASE/payment" \
-H "X-API-Key: $FICTIX_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: qbo-payment-demo-1" \
--data-binary @payment.json
The response contains Payment.Id. Read the invoice again at
GET /invoice/{Invoice.Id}: its balance should now be zero. The payment
creates the linked bank transaction and balanced cash/receivable posting.
Create a vendor bill
Save this as bill.json using the vendor and expense account IDs:
{
"VendorRef": {"value": "<vendor Id>"},
"TxnDate": "2026-11-03",
"Line": [{
"Amount": 0.01,
"DetailType": "AccountBasedExpenseLineDetail",
"AccountBasedExpenseLineDetail": {
"AccountRef": {"value": "<expense Account Id>"}
}
}]
}
curl --fail-with-body -sS "$QBO_BASE/bill" \
-H "X-API-Key: $FICTIX_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: qbo-bill-demo-1" \
--data-binary @bill.json
A successful response contains Bill.Id and an outstanding balance of
0.01. The posting increases expense and accounts payable; cash is unchanged.
Pay the bill
Save this as billpayment.json. This workflow supports PayType: "Check":
{
"VendorRef": {"value": "<vendor Id>"},
"TxnDate": "2026-11-03",
"TotalAmt": 0.01,
"PayType": "Check",
"CheckPayment": {"BankAccountRef": {"value": "<cash Account Id>"}},
"Line": [{
"Amount": 0.01,
"LinkedTxn": [{"TxnId": "<Bill.Id>", "TxnType": "Bill"}]
}]
}
curl --fail-with-body -sS "$QBO_BASE/billpayment" \
-H "X-API-Key: $FICTIX_PROJECT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: qbo-billpayment-demo-1" \
--data-binary @billpayment.json
Read GET /bill/{Bill.Id} to confirm a zero balance. The payment creates the
linked bank withdrawal and balanced payable/cash posting. Retrying an
operation with its original key and payload must not create another payment.
Check the resulting books
Query JournalEntry. Each line contains a numeric Amount,
DetailType: "JournalEntryLineDetail", and a JournalEntryLineDetail object
with PostingType: "Debit" or "Credit" and a resolvable AccountRef.
Each journal's debit and credit amounts must balance. Existing document IDs
must remain stable as your application writes new records.
The four operations above create four balanced journals. After both exact payments, the new invoice and bill have zero outstanding balance, and their opposite cash movements cancel. You can also read canonical entities or download a CSV export to reconcile the company's receivables, payables and bank balances with its ledger.
Supported slice
This guide covers new single-currency, non-tax service invoices, expense
bills, and exact payments linked to one existing document. The party, currency,
amount, active accounts and mappings must agree. Unsupported invoice or bill
corrections return 409; creating a payment does not authorize editing a
posted document. Inventory, tax and currency-conversion workflows are outside
this example. Direct JournalEntry writes are rejected; journal reads expose
the actual posted accounting consequences.
Validation errors return a QBO Fault or a Fictix error body. Check the HTTP
status and body before treating an operation as accepted. The broader
provider workflow reference and
Intuit's accounting documentation
describe the wire conventions; supported Fictix operations remain bounded by
this guide.
