Expensify to QuickBooks Online Automated Reconciliation (n8n)

Seamlessly sync approved Expensify reports to QuickBooks Online using n8n's flexible node-based workflow.

Tools: ExpensifyQuickBooks

Platform: n8n

Short Answer

A fully automated pipeline that triggers upon report approval in Expensify, validates vendor data in QuickBooks, creates the appropriate Bill or Purchase, and attaches the original receipt image—ensuring 100% audit compliance without manual intervention.

The Problem

Manual entry of expense reports into accounting software is prone to human error and delays financial closing cycles. Businesses often struggle with missing receipt attachments and inconsistent vendor categorization between expense and accounting systems.

The Outcome

A fully automated pipeline that triggers upon report approval in Expensify, validates vendor data in QuickBooks, creates the appropriate Bill or Purchase, and attaches the original receipt image—ensuring 100% audit compliance without manual intervention.

Step-by-Step Guide

1. **Create Expensify Credentials**: In n8n, go to Credentials > New. You will need your Expensify `partnerUserID` and `partnerUserSecret`. Use the n8n Expensify node or a generic HTTP Request node for advanced API calls. 2. **Configure Trigger**: Add the 'Expensify' node and set the event to 'Report Approved'. If using the self-hosted n8n, ensure your Webhook URL is accessible via a public tunnel (like Cloudflare or ngrok). 3. **Extract Report Data**: Use an 'HTTP Request' node to call the `combinedReportData` export loop. Expensify requires a specific SQL-like syntax in the body to return JSON data. 4. **Split Expenses**: Add an 'Item Lists' node to split the 'expenses' array into individual items so n8n can process each line item separately. 5. **Sync Vendors**: Add a 'QuickBooks Online' node. Use the 'Vendor' resource and 'Get All' action. Use a filter expression: `{{ $json.merchant == $node.QuickBooks.vendor.DisplayName }}`. If no match is found, add a 'QuickBooks' node to 'Create' the vendor. 6. **Handle Receipts**: Add an 'IF' node to check if `receiptID` is present. If true, use an 'HTTP Request' node with 'Response Format: File' to download the receipt from the Expensify URL. 7. **Map to QuickBooks**: Add a 'QuickBooks Online' node (Action: Create Bill or Purchase). Map the amount, date, and vendor ID. Use expressions like `{{ $json.amount / 100 }}` to convert Expensify cents to QuickBooks decimals. 8. **Upload Attachment**: Link the binary output from the receipt download to a 'QuickBooks Online' node using the 'Attachment' resource. Reference the `ParentId` as the ID from the Bill created in the previous step. 9. **Global Error Handling**: Create a separate workflow or use the 'Error Trigger' node to catch failures (e.g., mapping errors or API timeouts) and notify the admin via Slack.