Automated Expensify Reimbursement Sync to QuickBooks Online (Make.com)
Streamline expense reporting by automatically converting approved Expensify reports into QuickBooks Online Bills with receipt attachments.
Tools: Expensify → QuickBooks
Platform: Make.com
Short Answer
A fully automated Make.com scenario that triggers upon report approval, performs vendor lookups, creates a Bill in QuickBooks, and attaches the original receipt image, ensuring 100% data accuracy and real-time ledger updates.
The Problem
Manual entry of expense reports into accounting software is prone to human error, delayed financial reporting, and lost receipt documentation. Finance teams often struggle to reconcile employee reimbursements with bank statements while maintaining audit-ready records.
The Outcome
A fully automated Make.com scenario that triggers upon report approval, performs vendor lookups, creates a Bill in QuickBooks, and attaches the original receipt image, ensuring 100% data accuracy and real-time ledger updates.
Step-by-Step Guide
1. **Establish Connections**: In Make.com, create a new scenario. Add the **Expensify** module and connect using your Partner User ID and Secret. Add the **QuickBooks Online** module and authenticate via OAuth2.
2. **Trigger Configuration**: Search for the **Expensify > Watch Reports** module. Set the limit to 10. This module polls for reports based on their status.
3. **Add a Filter**: Click on the line after the trigger. Set a filter where `Status` (from Expensify) is equal to `Approved`. This prevents draft or deleted reports from syncing.
4. **Handle Receipts**: Add an **HTTP > Get a file** module. Map the `Receipt URL` from the Expensify bundle to the URL field. This downloads the binary file into Make.com's memory.
5. **Vendor Management**: Add the **QuickBooks Online > Search for Vendors** module. Search by the `Merchant Name`. Click 'Add an error handler' (right-click module). If no vendor is found, use a **Create a Vendor** module to prevent the scenario from failing.
6. **Map the Bill**: Add the **QuickBooks Online > Create a Bill** module. Map `Vendor ID` from the previous step, `Total Amount` to `Total Amount`, and use the `formatDate()` function: `{{formatDate(now; "YYYY-MM-DD")}}` for the transaction date.
7. **Account Mapping**: In the Bill Lines section, map the Expensify `Category` to your QuickBooks `Account ID`. *Tip: Use a Switch() function if category names don't match exactly.*
8. **Attach Receipt**: Add the **QuickBooks Online > Create an Attachment** module. Set the `Attachable Type` to 'Bill'. Map the `ID` from the 'Create a Bill' step to the `Attachable Ref` field. In the File section, select 'HTTP - Get a file'.
9. **Deduplication**: Before the QBO module, add a **Data Store > Check for record** module using the `Expensify Report ID` as the key to ensure you don't process the same report twice if the webhook re-fires.
10. **Error Handling**: Right-click the QBO modules and select 'Add Error Handler'. Use a **Break** or **Ignore** directive, or send a Slack message to the admin if a mapping fails.
Data Mapping
| Expensify Tool (Source) | QuickBooks Online (Destination) | Transformation / Formula |
| :--- | :--- | :--- |
| `Merchant Name` | `Vendor` | `lower(trim(Merchant))` for exact matching |
| `Total` | `Amount` | `parseNumber(Total)` to ensure decimal format |
| `Category` | `Expense Account` | `{{switch(Category; "Travel"; 54; "Meals"; 12)}}` (ID Mapping) |
| `Report ID` | `Doc Number` | Used as a unique Reference Number |
| `Comment` | `Description` | `{{if(Comment; Comment; "No description provided")}}` |
| `Receipt URL` | `Attachment Buffer` | Handled by **HTTP: Get a File** module |
Gotchas & Failure Modes
* **Binary Buffers**: Make.com clears the file buffer after each cycle. Ensure the 'Create Attachment' module immediately follows the 'HTTP Get a File' module or use a Variable to store it.
* **Rate Limiting**: QuickBooks Online has a limit of 100 requests per minute. If processing bulk historic reports, use a **Sleep** module or set 'Max number of cycles' to 5.
* **Account IDs vs. Names**: QBO requires the numerical ID for accounts, not the text name. You must use a Search module or a hardcoded Switch function to map 'Travel' to 'Account 55'.
* **ISO Date Formats**: Expensify dates may arrive in various formats. Always wrap them in `formatDate(date; "YYYY-MM-DD")` for QBO compatibility.
Verification Checklist
- [ ] Run 'Once' and manually enter an Expensify Report ID to test the data flow.
- [ ] Check the 'History' tab in Make.com to confirm the Binary File (receipt) was successfully passed to QBO.
- [ ] Verify in QuickBooks that the Bill status is 'Unpaid' and the 'Attachment' count is 1.
- [ ] Ensure the Filter successfully blocked a 'Processing' or 'Open' report.
- [ ] Confirm no duplicate Bills were created when hitting 'Run' twice on the same data bundle.
Ready to Automate?
Build this automation with Make.com in minutes.