QuickBooks Online is where the invoice data needs to live. The problem is that invoices arrive as PDFs, and getting the data from the PDF into QuickBooks currently requires someone to type it there. This guide eliminates that step.
You'll build a system that reads a PDF invoice, extracts the vendor name, invoice number, dates, amounts, and line items, and creates a Bill in QuickBooks Online — automatically, without a human touching a keyboard.
What You'll Need
- A DocuParseAPI account — free at docuparseapi.com/signup
- A QuickBooks Online account with API access
- A QuickBooks app (create one at developer.intuit.com) to get OAuth credentials
- Node.js 18+ or Python 3.8+
How QuickBooks Bills Work
In QuickBooks Online, a Bill represents a supplier invoice — money you owe a vendor. Bills have:
- A Vendor (must exist as a contact in QBO)
- A transaction date and due date
- Line items with amounts and account codes
- A document number (your invoice reference)
The extracted invoice data maps directly to these fields.
merchant→VendorRef.nameMatched or createdinvoice_id→DocNumberDedup keydate→TxnDateISO 8601due_date→DueDatenull → omittedtotal→TotalAmtFloat conversionline_items[]→Line[]One Line per itemline_items[].description→Line[].Descriptionline_items[].total→Line[].AmountFloat conversionSetting the Correct Expense Account
The AccountRef.value in line items must match an account ID in your QuickBooks chart of accounts. To find the right ID:
// List all expense accounts
const query = "SELECT * FROM Account WHERE AccountType = 'Expense'";
const response = await fetch(
`${QBO_BASE}/query?query=${encodeURIComponent(query)}&minorversion=65`,
{ headers: { Authorization: `Bearer ${QBO_ACCESS_TOKEN}`, Accept: "application/json" } }
);
const data = await response.json();
data.QueryResponse.Account.forEach(acc => {
console.log(`${acc.Id}: ${acc.Name}`);
});Set the ID as QBO_EXPENSE_ACCOUNT_ID in your environment variables.